mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-11-04 02:01:14 +01:00 
			
		
		
		
	This change updates all tailfs functions and the majority of the tailfs variables to use the new drive naming. Updates tailscale/corp#16827 Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
		
			
				
	
	
		
			112 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright (c) Tailscale Inc & AUTHORS
 | 
						|
// SPDX-License-Identifier: BSD-3-Clause
 | 
						|
 | 
						|
// Package shared contains types and functions shared by different drive
 | 
						|
// packages.
 | 
						|
package shared
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"io"
 | 
						|
	"io/fs"
 | 
						|
	"sync"
 | 
						|
)
 | 
						|
 | 
						|
// DirFile implements webdav.File for a virtual directory.
 | 
						|
// It mimics the behavior of an os.File that is pointing at a real directory.
 | 
						|
type DirFile struct {
 | 
						|
	// Info provides the fs.FileInfo for this directory
 | 
						|
	Info fs.FileInfo
 | 
						|
	// LoadChildren is used to load the fs.FileInfos for this directory's
 | 
						|
	// children. It is called at most once in order to support listing
 | 
						|
	// children.
 | 
						|
	LoadChildren func() ([]fs.FileInfo, error)
 | 
						|
 | 
						|
	// loadChildrenMu guards children and loadedChildren.
 | 
						|
	loadChildrenMu sync.Mutex
 | 
						|
	children       []fs.FileInfo
 | 
						|
	loadedChildren bool
 | 
						|
}
 | 
						|
 | 
						|
// Readdir implements interface webdav.File. It lazily loads information about
 | 
						|
// children when it is called.
 | 
						|
func (d *DirFile) Readdir(count int) ([]fs.FileInfo, error) {
 | 
						|
	err := d.loadChildrenIfNecessary()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	if count <= 0 {
 | 
						|
		result := d.children
 | 
						|
		d.children = nil
 | 
						|
		return result, nil
 | 
						|
	}
 | 
						|
 | 
						|
	n := len(d.children)
 | 
						|
	if count < n {
 | 
						|
		n = count
 | 
						|
	}
 | 
						|
	result := d.children[:n]
 | 
						|
	d.children = d.children[n:]
 | 
						|
	if len(d.children) == 0 {
 | 
						|
		err = io.EOF
 | 
						|
	}
 | 
						|
	return result, err
 | 
						|
}
 | 
						|
 | 
						|
func (d *DirFile) loadChildrenIfNecessary() error {
 | 
						|
	d.loadChildrenMu.Lock()
 | 
						|
	defer d.loadChildrenMu.Unlock()
 | 
						|
 | 
						|
	if !d.loadedChildren {
 | 
						|
		var err error
 | 
						|
		d.children, err = d.LoadChildren()
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		d.loadedChildren = true
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Stat implements interface webdav.File.
 | 
						|
func (d *DirFile) Stat() (fs.FileInfo, error) {
 | 
						|
	return d.Info, nil
 | 
						|
}
 | 
						|
 | 
						|
// Close implements interface webdav.File. It does nothing and never returns an
 | 
						|
// error.
 | 
						|
func (d *DirFile) Close() error {
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Read implements interface webdav.File. As this is a directory, it always
 | 
						|
// fails with an fs.PathError.
 | 
						|
func (d *DirFile) Read(b []byte) (int, error) {
 | 
						|
	return 0, &fs.PathError{
 | 
						|
		Op:   "read",
 | 
						|
		Path: d.Info.Name(),
 | 
						|
		Err:  errors.New("is a directory"),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Write implements interface webdav.File. As this is a directory, it always
 | 
						|
// fails with an fs.PathError.
 | 
						|
func (d *DirFile) Write(b []byte) (int, error) {
 | 
						|
	return 0, &fs.PathError{
 | 
						|
		Op:   "write",
 | 
						|
		Path: d.Info.Name(),
 | 
						|
		Err:  errors.New("bad file descriptor"),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Seek implements interface webdav.File. As this is a directory, it always
 | 
						|
// fails with an fs.PathError.
 | 
						|
func (d *DirFile) Seek(offset int64, whence int) (int64, error) {
 | 
						|
	return 0, &fs.PathError{
 | 
						|
		Op:   "seek",
 | 
						|
		Path: d.Info.Name(),
 | 
						|
		Err:  errors.New("invalid argument"),
 | 
						|
	}
 | 
						|
}
 |