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 }