github.com/avfs/avfs@v0.33.1-0.20240303173310-c6ba67c33eb7/vfs_types.go (about)

     1  //
     2  //  Copyright 2023 The AVFS authors
     3  //
     4  //  Licensed under the Apache License, Version 2.0 (the "License");
     5  //  you may not use this file except in compliance with the License.
     6  //  You may obtain a copy of the License at
     7  //
     8  //  	http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  //  Unless required by applicable law or agreed to in writing, software
    11  //  distributed under the License is distributed on an "AS IS" BASIS,
    12  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  //  See the License for the specific language governing permissions and
    14  //  limitations under the License.
    15  //
    16  
    17  package avfs
    18  
    19  import (
    20  	"io"
    21  	"io/fs"
    22  	"time"
    23  )
    24  
    25  const (
    26  	DefaultDirPerm  = fs.FileMode(0o777) // DefaultDirPerm is the default permission for directories.
    27  	DefaultFilePerm = fs.FileMode(0o666) // DefaultFilePerm is the default permission for files.
    28  	DefaultName     = "Default"          // DefaultName is the default name.
    29  	DefaultVolume   = "C:"               // DefaultVolume is the default volume name for Windows.
    30  	NotImplemented  = "not implemented"  // NotImplemented is the return string of a non-implemented feature.
    31  
    32  	// FileModeMask is the bitmask used for permissions.
    33  	FileModeMask = fs.ModePerm | fs.ModeSticky | fs.ModeSetuid | fs.ModeSetgid
    34  )
    35  
    36  // Cloner is the interface that wraps the Clone method.
    37  type Cloner interface {
    38  	// Clone returns a shallow copy of the current file system (see MemFs).
    39  	Clone() VFS
    40  }
    41  
    42  // ChRooter is the interface that wraps the Chroot method.
    43  type ChRooter interface {
    44  	// Chroot changes the root to that specified in path.
    45  	// If the user has not root privileges avfs.errPermDenied is returned.
    46  	// If there is an error, it will be of type *PathError.
    47  	Chroot(path string) error
    48  }
    49  
    50  // DirInfo contains information to create a directory.
    51  type DirInfo struct {
    52  	Path string
    53  	Perm fs.FileMode
    54  }
    55  
    56  // File represents a file in the file system.
    57  type File interface {
    58  	fs.File
    59  	fs.ReadDirFile
    60  	io.Reader
    61  	io.ReaderAt
    62  	io.StringWriter
    63  	io.Writer
    64  	io.WriterAt
    65  	io.WriteSeeker
    66  
    67  	// Chdir changes the current working directory to the file,
    68  	// which must be a directory.
    69  	// If there is an error, it will be of type *PathError.
    70  	Chdir() error
    71  
    72  	// Chmod changes the mode of the file to mode.
    73  	// If there is an error, it will be of type *PathError.
    74  	Chmod(mode fs.FileMode) error
    75  
    76  	// Chown changes the numeric uid and gid of the named file.
    77  	// If there is an error, it will be of type *PathError.
    78  	//
    79  	// On Windows, it always returns the syscall.EWINDOWS error, wrapped
    80  	// in *PathError.
    81  	Chown(uid, gid int) error
    82  
    83  	// Fd returns the integer Unix file descriptor referencing the open file.
    84  	// The file descriptor is valid only until f.Close is called or f is garbage collected.
    85  	// On Unix systems this will cause the SetDeadline methods to stop working.
    86  	Fd() uintptr
    87  
    88  	// Name returns the name of the file as presented to Open.
    89  	Name() string
    90  
    91  	// Readdirnames reads and returns a slice of names from the directory f.
    92  	//
    93  	// If n > 0, Readdirnames returns at most n names. In this case, if
    94  	// Readdirnames returns an empty slice, it will return a non-nil error
    95  	// explaining why. At the end of a directory, the error is io.EOF.
    96  	//
    97  	// If n <= 0, Readdirnames returns all the names from the directory in
    98  	// a single slice. In this case, if Readdirnames succeeds (reads all
    99  	// the way to the end of the directory), it returns the slice and a
   100  	// nil error. If it encounters an error before the end of the
   101  	// directory, Readdirnames returns the names read until that point and
   102  	// a non-nil error.
   103  	Readdirnames(n int) (names []string, err error)
   104  
   105  	// Sync commits the current contents of the file to stable storage.
   106  	// Typically, this means flushing the file system's in-memory copy
   107  	// of recently written data to disk.
   108  	Sync() error
   109  
   110  	// Truncate changes the size of the file.
   111  	// It does not change the I/O offset.
   112  	// If there is an error, it will be of type *PathError.
   113  	Truncate(size int64) error
   114  }
   115  
   116  // Namer is the interface that wraps the Name method.
   117  type Namer interface {
   118  	Name() string
   119  }
   120  
   121  // SysStater is the interface returned by ToSysStat on all file systems.
   122  type SysStater interface {
   123  	GroupIdentifier
   124  	UserIdentifier
   125  	Nlink() uint64
   126  }
   127  
   128  // VolumeManager is the interface that manage volumes for Windows file systems.
   129  type VolumeManager interface {
   130  	// VolumeAdd adds a new volume to a Windows file system.
   131  	// If there is an error, it will be of type *PathError.
   132  	VolumeAdd(name string) error
   133  
   134  	// VolumeDelete deletes an existing volume and all its files from a Windows file system.
   135  	// If there is an error, it will be of type *PathError.
   136  	VolumeDelete(name string) error
   137  
   138  	// VolumeList returns the volumes of the file system.
   139  	VolumeList() []string
   140  }
   141  
   142  // OpenMode defines constants used by OpenFile and CheckPermission functions.
   143  type OpenMode uint16
   144  
   145  const (
   146  	OpenLookup     OpenMode = 0o001     // OpenLookup checks for lookup permission on a directory.
   147  	OpenWrite      OpenMode = 0o002     // OpenWrite opens or checks for write permission.
   148  	OpenRead       OpenMode = 0o004     // OpenRead opens or checks for read permission.
   149  	OpenAppend     OpenMode = 1 << iota // OpenAppend opens a file for appending (os.O_APPEND).
   150  	OpenCreate                          // OpenCreate creates a file (os.O_CREATE).
   151  	OpenCreateExcl                      // OpenCreateExcl creates a non existing file (os.O_EXCL).
   152  	OpenTruncate                        // OpenTruncate truncates a file (os.O_TRUNC).
   153  )
   154  
   155  // IOFS is the virtual file system interface implementing io/fs interfaces.
   156  type IOFS interface {
   157  	VFSBase
   158  	fs.FS
   159  	fs.GlobFS
   160  	fs.ReadDirFS
   161  	fs.ReadFileFS
   162  	fs.StatFS
   163  	fs.SubFS
   164  }
   165  
   166  // Typer is the interface that wraps the Type method.
   167  type Typer interface {
   168  	// Type returns the type of the fileSystem or Identity manager.
   169  	Type() string
   170  }
   171  
   172  // VFS is the virtual file system interface.
   173  // Any simulated or real file system should implement this interface.
   174  type VFS interface {
   175  	VFSBase
   176  
   177  	// Open opens the named file for reading. If successful, methods on
   178  	// the returned file can be used for reading; the associated file
   179  	// descriptor has mode O_RDONLY.
   180  	// If there is an error, it will be of type *PathError.
   181  	Open(name string) (File, error)
   182  
   183  	// Sub returns an FS corresponding to the subtree rooted at dir.
   184  	Sub(dir string) (VFS, error)
   185  }
   186  
   187  // VFSBase regroups the common methods to VFS and IOFS.
   188  type VFSBase interface {
   189  	CurUserMgr
   190  	Featurer
   191  	IdmMgr
   192  	Namer
   193  	OSTyper
   194  	Typer
   195  	UMasker
   196  
   197  	// Abs returns an absolute representation of path.
   198  	// If the path is not absolute it will be joined with the current
   199  	// working directory to turn it into an absolute path. The absolute
   200  	// path name for a given file is not guaranteed to be unique.
   201  	// Abs calls Clean on the result.
   202  	Abs(path string) (string, error)
   203  
   204  	// Base returns the last element of path.
   205  	// Trailing path separators are removed before extracting the last element.
   206  	// If the path is empty, Base returns ".".
   207  	// If the path consists entirely of separators, Base returns a single separator.
   208  	Base(path string) string
   209  
   210  	// Chdir changes the current working directory to the named directory.
   211  	// If there is an error, it will be of type *PathError.
   212  	Chdir(dir string) error
   213  
   214  	// Chmod changes the mode of the named file to mode.
   215  	// If the file is a symbolic link, it changes the mode of the link's target.
   216  	// If there is an error, it will be of type *PathError.
   217  	//
   218  	// A different subset of the mode bits are used, depending on the
   219  	// operating system.
   220  	//
   221  	// On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and
   222  	// ModeSticky are used.
   223  	//
   224  	// On Windows, only the 0200 bit (owner writable) of mode is used; it
   225  	// controls whether the file's read-only attribute is set or cleared.
   226  	// The other bits are currently unused. For compatibility with Go 1.12
   227  	// and earlier, use a non-zero mode. Use mode 0400 for a read-only
   228  	// file and 0600 for a readable+writable file.
   229  	//
   230  	// On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive,
   231  	// and ModeTemporary are used.
   232  	Chmod(name string, mode fs.FileMode) error
   233  
   234  	// Chown changes the numeric uid and gid of the named file.
   235  	// If the file is a symbolic link, it changes the uid and gid of the link's target.
   236  	// A uid or gid of -1 means to not change that value.
   237  	// If there is an error, it will be of type *PathError.
   238  	//
   239  	// On Windows or Plan 9, Chown always returns the syscall.EWINDOWS or
   240  	// EPLAN9 error, wrapped in *PathError.
   241  	Chown(name string, uid, gid int) error
   242  
   243  	// Chtimes changes the access and modification times of the named
   244  	// file, similar to the Unix utime() or utimes() functions.
   245  	//
   246  	// The underlying file system may truncate or round the values to a
   247  	// less precise time unit.
   248  	// If there is an error, it will be of type *PathError.
   249  	Chtimes(name string, atime, mtime time.Time) error
   250  
   251  	// Clean returns the shortest path name equivalent to path
   252  	// by purely lexical processing. It applies the following rules
   253  	// iteratively until no further processing can be done:
   254  	//
   255  	//	1. Replace multiple Separator elements with a single one.
   256  	//	2. Eliminate each . path name element (the current directory).
   257  	//	3. Eliminate each inner .. path name element (the parent directory)
   258  	//	   along with the non-.. element that precedes it.
   259  	//	4. Eliminate .. elements that begin a rooted path:
   260  	//	   that is, replace "/.." by "/" at the beginning of a path,
   261  	//	   assuming Separator is '/'.
   262  	//
   263  	// The returned path ends in a slash only if it represents a root directory,
   264  	// such as "/" on Unix or `C:\` on Windows.
   265  	//
   266  	// Finally, any occurrences of slash are replaced by Separator.
   267  	//
   268  	// If the result of this process is an empty string, Clean
   269  	// returns the string ".".
   270  	//
   271  	// See also Rob Pike, ``Lexical File Names in Plan 9 or
   272  	// Getting Dot-Dot Right,''
   273  	// https://9p.io/sys/doc/lexnames.html
   274  	Clean(path string) string
   275  
   276  	// Create creates the named file with mode 0666 (before umask), truncating
   277  	// it if it already exists. If successful, methods on the returned
   278  	// File can be used for I/O; the associated file descriptor has mode
   279  	// O_RDWR.
   280  	// If there is an error, it will be of type *PathError.
   281  	Create(name string) (File, error)
   282  
   283  	// CreateTemp creates a new temporary file in the directory dir,
   284  	// opens the file for reading and writing, and returns the resulting file.
   285  	// The filename is generated by taking pattern and adding a random string to the end.
   286  	// If pattern includes a "*", the random string replaces the last "*".
   287  	// If dir is the empty string, CreateTemp uses the default directory for temporary files, as returned by TempDir.
   288  	// Multiple programs or goroutines calling CreateTemp simultaneously will not choose the same file.
   289  	// The caller can use the file's Name method to find the pathname of the file.
   290  	// It is the caller's responsibility to remove the file when it is no longer needed.
   291  	CreateTemp(dir, pattern string) (File, error)
   292  
   293  	// Dir returns all but the last element of path, typically the path's directory.
   294  	// After dropping the final element, Dir calls Clean on the path and trailing
   295  	// slashes are removed.
   296  	// If the path is empty, Dir returns ".".
   297  	// If the path consists entirely of separators, Dir returns a single separator.
   298  	// The returned path does not end in a separator unless it is the root directory.
   299  	Dir(path string) string
   300  
   301  	// EvalSymlinks returns the path name after the evaluation of any symbolic
   302  	// links.
   303  	// If path is relative the result will be relative to the current directory,
   304  	// unless one of the components is an absolute symbolic link.
   305  	// EvalSymlinks calls Clean on the result.
   306  	EvalSymlinks(path string) (string, error)
   307  
   308  	// FromSlash returns the result of replacing each slash ('/') character
   309  	// in path with a separator character. Multiple slashes are replaced
   310  	// by multiple separators.
   311  	FromSlash(path string) string
   312  
   313  	// Getwd returns a rooted path name corresponding to the
   314  	// current directory. If the current directory can be
   315  	// reached via multiple paths (due to symbolic links),
   316  	// Getwd may return any one of them.
   317  	Getwd() (dir string, err error)
   318  
   319  	// Glob returns the names of all files matching pattern or nil
   320  	// if there is no matching file. The syntax of patterns is the same
   321  	// as in Match. The pattern may describe hierarchical names such as
   322  	// /usr/*/bin/ed (assuming the Separator is '/').
   323  	//
   324  	// Glob ignores file system errors such as I/O errors reading directories.
   325  	// The only possible returned error is ErrBadPattern, when pattern
   326  	// is malformed.
   327  	Glob(pattern string) (matches []string, err error)
   328  
   329  	// Idm returns the identity manager of the file system.
   330  	// if the file system does not have an identity manager, avfs.DummyIdm is returned.
   331  	Idm() IdentityMgr
   332  
   333  	// IsAbs reports whether the path is absolute.
   334  	IsAbs(path string) bool
   335  
   336  	// IsPathSeparator reports whether c is a directory separator character.
   337  	IsPathSeparator(c uint8) bool
   338  
   339  	// Join joins any number of path elements into a single path, adding a
   340  	// separating slash if necessary. The result is Cleaned; in particular,
   341  	// all empty strings are ignored.
   342  	Join(elem ...string) string
   343  
   344  	// Lchown changes the numeric uid and gid of the named file.
   345  	// If the file is a symbolic link, it changes the uid and gid of the link itself.
   346  	// If there is an error, it will be of type *PathError.
   347  	//
   348  	// On Windows, it always returns the syscall.EWINDOWS error, wrapped
   349  	// in *PathError.
   350  	Lchown(name string, uid, gid int) error
   351  
   352  	// Link creates newname as a hard link to the oldname file.
   353  	// If there is an error, it will be of type *LinkError.
   354  	Link(oldname, newname string) error
   355  
   356  	// Lstat returns a FileInfo describing the named file.
   357  	// If the file is a symbolic link, the returned FileInfo
   358  	// describes the symbolic link. Lstat makes no attempt to follow the link.
   359  	// If there is an error, it will be of type *PathError.
   360  	Lstat(name string) (fs.FileInfo, error)
   361  
   362  	// Match reports whether name matches the shell file name pattern.
   363  	// The pattern syntax is:
   364  	//
   365  	//	pattern:
   366  	//		{ term }
   367  	//	term:
   368  	//		'*'         matches any sequence of non-Separator characters
   369  	//		'?'         matches any single non-Separator character
   370  	//		'[' [ '^' ] { character-range } ']'
   371  	//		            character class (must be non-empty)
   372  	//		c           matches character c (c != '*', '?', '\\', '[')
   373  	//		'\\' c      matches character c
   374  	//
   375  	//	character-range:
   376  	//		c           matches character c (c != '\\', '-', ']')
   377  	//		'\\' c      matches character c
   378  	//		lo '-' hi   matches character c for lo <= c <= hi
   379  	//
   380  	// Match requires pattern to match all of name, not just a substring.
   381  	// The only possible returned error is ErrBadPattern, when pattern
   382  	// is malformed.
   383  	//
   384  	// On Windows, escaping is disabled. Instead, '\\' is treated as
   385  	// path separator.
   386  	//
   387  	Match(pattern, name string) (matched bool, err error)
   388  
   389  	// Mkdir creates a new directory with the specified name and permission
   390  	// bits (before umask).
   391  	// If there is an error, it will be of type *PathError.
   392  	Mkdir(name string, perm fs.FileMode) error
   393  
   394  	// MkdirAll creates a directory named path,
   395  	// along with any necessary parents, and returns nil,
   396  	// or else returns an error.
   397  	// The permission bits perm (before umask) are used for all
   398  	// directories that MkdirAll creates.
   399  	// If path is already a directory, MkdirAll does nothing
   400  	// and returns nil.
   401  	MkdirAll(path string, perm fs.FileMode) error
   402  
   403  	// MkdirTemp creates a new temporary directory in the directory dir
   404  	// and returns the pathname of the new directory.
   405  	// The new directory's name is generated by adding a random string to the end of pattern.
   406  	// If pattern includes a "*", the random string replaces the last "*" instead.
   407  	// If dir is the empty string, MkdirTemp uses the default directory for temporary files, as returned by TempDir.
   408  	// Multiple programs or goroutines calling MkdirTemp simultaneously will not choose the same directory.
   409  	// It is the caller's responsibility to remove the directory when it is no longer needed.
   410  	MkdirTemp(dir, pattern string) (string, error)
   411  
   412  	// OpenFile is the generalized open call; most users will use Open
   413  	// or Create instead. It opens the named file with specified flag
   414  	// (O_RDONLY etc.) and perm (before umask), if applicable. If successful,
   415  	// methods on the returned File can be used for I/O.
   416  	// If there is an error, it will be of type *PathError.
   417  	OpenFile(name string, flag int, perm fs.FileMode) (File, error)
   418  
   419  	// PathSeparator return the OS-specific path separator.
   420  	PathSeparator() uint8
   421  
   422  	// ReadDir reads the named directory,
   423  	// returning all its directory entries sorted by filename.
   424  	// If an error occurs reading the directory,
   425  	// ReadDir returns the entries it was able to read before the error,
   426  	// along with the error.
   427  	ReadDir(name string) ([]fs.DirEntry, error)
   428  
   429  	// ReadFile reads the file named by filename and returns the contents.
   430  	// A successful call returns err == nil, not err == EOF. Because ReadFile
   431  	// reads the whole file, it does not treat an EOF from Read as an error
   432  	// to be reported.
   433  	ReadFile(filename string) ([]byte, error)
   434  
   435  	// Readlink returns the destination of the named symbolic link.
   436  	// If there is an error, it will be of type *PathError.
   437  	Readlink(name string) (string, error)
   438  
   439  	// Rel returns a relative path that is lexically equivalent to targpath when
   440  	// joined to basepath with an intervening separator. That is,
   441  	// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself.
   442  	// On success, the returned path will always be relative to basepath,
   443  	// even if basepath and targpath share no elements.
   444  	// An error is returned if targpath can't be made relative to basepath or if
   445  	// knowing the current working directory would be necessary to compute it.
   446  	// Rel calls Clean on the result.
   447  	Rel(basepath, targpath string) (string, error)
   448  
   449  	// Remove removes the named file or (empty) directory.
   450  	// If there is an error, it will be of type *PathError.
   451  	Remove(name string) error
   452  
   453  	// RemoveAll removes path and any children it contains.
   454  	// It removes everything it can but returns the first error
   455  	// it encounters. If the path does not exist, RemoveAll
   456  	// returns nil (no error).
   457  	RemoveAll(path string) error
   458  
   459  	// Rename renames (moves) oldpath to newpath.
   460  	// If newpath already exists and is not a directory, Rename replaces it.
   461  	// OS-specific restrictions may apply when oldpath and newpath are in different directories.
   462  	// If there is an error, it will be of type *LinkError.
   463  	Rename(oldpath, newpath string) error
   464  
   465  	// SameFile reports whether fi1 and fi2 describe the same file.
   466  	// For example, on Unix this means that the device and inode fields
   467  	// of the two underlying structures are identical; on other systems
   468  	// the decision may be based on the path names.
   469  	// SameFile only applies to results returned by this package's Stat.
   470  	// It returns false in other cases.
   471  	SameFile(fi1, fi2 fs.FileInfo) bool
   472  
   473  	// Split splits path immediately following the final Separator,
   474  	// separating it into a directory and file name component.
   475  	// If there is no Separator in path, Split returns an empty dir
   476  	// and file set to path.
   477  	// The returned values have the property that path = dir+file.
   478  	Split(path string) (dir, file string)
   479  
   480  	// Stat returns a FileInfo describing the named file.
   481  	// If there is an error, it will be of type *PathError.
   482  	Stat(name string) (fs.FileInfo, error)
   483  
   484  	// Symlink creates newname as a symbolic link to oldname.
   485  	// If there is an error, it will be of type *LinkError.
   486  	Symlink(oldname, newname string) error
   487  
   488  	// TempDir returns the default directory to use for temporary files.
   489  	//
   490  	// On Unix systems, it returns $TMPDIR if non-empty, else /tmp.
   491  	// On Windows, it uses GetTempPath, returning the first non-empty
   492  	// value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory.
   493  	// On Plan 9, it returns /tmp.
   494  	//
   495  	// The directory is neither guaranteed to exist nor have accessible
   496  	// permissions.
   497  	TempDir() string
   498  
   499  	// ToSlash returns the result of replacing each separator character
   500  	// in path with a slash ('/') character. Multiple separators are
   501  	// replaced by multiple slashes.
   502  	ToSlash(path string) string
   503  
   504  	// ToSysStat takes a value from fs.FileInfo.Sys() and returns a value that implements interface avfs.SysStater.
   505  	ToSysStat(info fs.FileInfo) SysStater
   506  
   507  	// Truncate changes the size of the named file.
   508  	// If the file is a symbolic link, it changes the size of the link's target.
   509  	// If there is an error, it will be of type *PathError.
   510  	Truncate(name string, size int64) error
   511  
   512  	// WalkDir walks the file tree rooted at root, calling fn for each file or
   513  	// directory in the tree, including root.
   514  	//
   515  	// All errors that arise visiting files and directories are filtered by fn:
   516  	// see the fs.WalkDirFunc documentation for details.
   517  	//
   518  	// The files are walked in lexical order, which makes the output deterministic
   519  	// but requires WalkDir to read an entire directory into memory before proceeding
   520  	// to walk that directory.
   521  	//
   522  	// WalkDir does not follow symbolic links.
   523  	WalkDir(root string, fn fs.WalkDirFunc) error
   524  
   525  	// WriteFile writes data to a file named by filename.
   526  	// If the file does not exist, WriteFile creates it with permissions perm;
   527  	// otherwise WriteFile truncates it before writing.
   528  	WriteFile(filename string, data []byte, perm fs.FileMode) error
   529  }