...

Source file src/io/fs/fs.go

Documentation: io/fs

		 1  // Copyright 2020 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  // Package fs defines basic interfaces to a file system.
		 6  // A file system can be provided by the host operating system
		 7  // but also by other packages.
		 8  package fs
		 9  
		10  import (
		11  	"internal/oserror"
		12  	"time"
		13  	"unicode/utf8"
		14  )
		15  
		16  // An FS provides access to a hierarchical file system.
		17  //
		18  // The FS interface is the minimum implementation required of the file system.
		19  // A file system may implement additional interfaces,
		20  // such as ReadFileFS, to provide additional or optimized functionality.
		21  type FS interface {
		22  	// Open opens the named file.
		23  	//
		24  	// When Open returns an error, it should be of type *PathError
		25  	// with the Op field set to "open", the Path field set to name,
		26  	// and the Err field describing the problem.
		27  	//
		28  	// Open should reject attempts to open names that do not satisfy
		29  	// ValidPath(name), returning a *PathError with Err set to
		30  	// ErrInvalid or ErrNotExist.
		31  	Open(name string) (File, error)
		32  }
		33  
		34  // ValidPath reports whether the given path name
		35  // is valid for use in a call to Open.
		36  //
		37  // Path names passed to open are UTF-8-encoded,
		38  // unrooted, slash-separated sequences of path elements, like “x/y/z”.
		39  // Path names must not contain an element that is “.” or “..” or the empty string,
		40  // except for the special case that the root directory is named “.”.
		41  // Paths must not start or end with a slash: “/x” and “x/” are invalid.
		42  //
		43  // Note that paths are slash-separated on all systems, even Windows.
		44  // Paths containing other characters such as backslash and colon
		45  // are accepted as valid, but those characters must never be
		46  // interpreted by an FS implementation as path element separators.
		47  func ValidPath(name string) bool {
		48  	if !utf8.ValidString(name) {
		49  		return false
		50  	}
		51  
		52  	if name == "." {
		53  		// special case
		54  		return true
		55  	}
		56  
		57  	// Iterate over elements in name, checking each.
		58  	for {
		59  		i := 0
		60  		for i < len(name) && name[i] != '/' {
		61  			i++
		62  		}
		63  		elem := name[:i]
		64  		if elem == "" || elem == "." || elem == ".." {
		65  			return false
		66  		}
		67  		if i == len(name) {
		68  			return true // reached clean ending
		69  		}
		70  		name = name[i+1:]
		71  	}
		72  }
		73  
		74  // A File provides access to a single file.
		75  // The File interface is the minimum implementation required of the file.
		76  // Directory files should also implement ReadDirFile.
		77  // A file may implement io.ReaderAt or io.Seeker as optimizations.
		78  type File interface {
		79  	Stat() (FileInfo, error)
		80  	Read([]byte) (int, error)
		81  	Close() error
		82  }
		83  
		84  // A DirEntry is an entry read from a directory
		85  // (using the ReadDir function or a ReadDirFile's ReadDir method).
		86  type DirEntry interface {
		87  	// Name returns the name of the file (or subdirectory) described by the entry.
		88  	// This name is only the final element of the path (the base name), not the entire path.
		89  	// For example, Name would return "hello.go" not "home/gopher/hello.go".
		90  	Name() string
		91  
		92  	// IsDir reports whether the entry describes a directory.
		93  	IsDir() bool
		94  
		95  	// Type returns the type bits for the entry.
		96  	// The type bits are a subset of the usual FileMode bits, those returned by the FileMode.Type method.
		97  	Type() FileMode
		98  
		99  	// Info returns the FileInfo for the file or subdirectory described by the entry.
	 100  	// The returned FileInfo may be from the time of the original directory read
	 101  	// or from the time of the call to Info. If the file has been removed or renamed
	 102  	// since the directory read, Info may return an error satisfying errors.Is(err, ErrNotExist).
	 103  	// If the entry denotes a symbolic link, Info reports the information about the link itself,
	 104  	// not the link's target.
	 105  	Info() (FileInfo, error)
	 106  }
	 107  
	 108  // A ReadDirFile is a directory file whose entries can be read with the ReadDir method.
	 109  // Every directory file should implement this interface.
	 110  // (It is permissible for any file to implement this interface,
	 111  // but if so ReadDir should return an error for non-directories.)
	 112  type ReadDirFile interface {
	 113  	File
	 114  
	 115  	// ReadDir reads the contents of the directory and returns
	 116  	// a slice of up to n DirEntry values in directory order.
	 117  	// Subsequent calls on the same file will yield further DirEntry values.
	 118  	//
	 119  	// If n > 0, ReadDir returns at most n DirEntry structures.
	 120  	// In this case, if ReadDir returns an empty slice, it will return
	 121  	// a non-nil error explaining why.
	 122  	// At the end of a directory, the error is io.EOF.
	 123  	//
	 124  	// If n <= 0, ReadDir returns all the DirEntry values from the directory
	 125  	// in a single slice. In this case, if ReadDir succeeds (reads all the way
	 126  	// to the end of the directory), it returns the slice and a nil error.
	 127  	// If it encounters an error before the end of the directory,
	 128  	// ReadDir returns the DirEntry list read until that point and a non-nil error.
	 129  	ReadDir(n int) ([]DirEntry, error)
	 130  }
	 131  
	 132  // Generic file system errors.
	 133  // Errors returned by file systems can be tested against these errors
	 134  // using errors.Is.
	 135  var (
	 136  	ErrInvalid		= errInvalid()		// "invalid argument"
	 137  	ErrPermission = errPermission() // "permission denied"
	 138  	ErrExist			= errExist()			// "file already exists"
	 139  	ErrNotExist	 = errNotExist()	 // "file does not exist"
	 140  	ErrClosed		 = errClosed()		 // "file already closed"
	 141  )
	 142  
	 143  func errInvalid() error		{ return oserror.ErrInvalid }
	 144  func errPermission() error { return oserror.ErrPermission }
	 145  func errExist() error			{ return oserror.ErrExist }
	 146  func errNotExist() error	 { return oserror.ErrNotExist }
	 147  func errClosed() error		 { return oserror.ErrClosed }
	 148  
	 149  // A FileInfo describes a file and is returned by Stat.
	 150  type FileInfo interface {
	 151  	Name() string			 // base name of the file
	 152  	Size() int64				// length in bytes for regular files; system-dependent for others
	 153  	Mode() FileMode		 // file mode bits
	 154  	ModTime() time.Time // modification time
	 155  	IsDir() bool				// abbreviation for Mode().IsDir()
	 156  	Sys() interface{}	 // underlying data source (can return nil)
	 157  }
	 158  
	 159  // A FileMode represents a file's mode and permission bits.
	 160  // The bits have the same definition on all systems, so that
	 161  // information about files can be moved from one system
	 162  // to another portably. Not all bits apply to all systems.
	 163  // The only required bit is ModeDir for directories.
	 164  type FileMode uint32
	 165  
	 166  // The defined file mode bits are the most significant bits of the FileMode.
	 167  // The nine least-significant bits are the standard Unix rwxrwxrwx permissions.
	 168  // The values of these bits should be considered part of the public API and
	 169  // may be used in wire protocols or disk representations: they must not be
	 170  // changed, although new bits might be added.
	 171  const (
	 172  	// The single letters are the abbreviations
	 173  	// used by the String method's formatting.
	 174  	ModeDir				FileMode = 1 << (32 - 1 - iota) // d: is a directory
	 175  	ModeAppend																		 // a: append-only
	 176  	ModeExclusive																	// l: exclusive use
	 177  	ModeTemporary																	// T: temporary file; Plan 9 only
	 178  	ModeSymlink																		// L: symbolic link
	 179  	ModeDevice																		 // D: device file
	 180  	ModeNamedPipe																	// p: named pipe (FIFO)
	 181  	ModeSocket																		 // S: Unix domain socket
	 182  	ModeSetuid																		 // u: setuid
	 183  	ModeSetgid																		 // g: setgid
	 184  	ModeCharDevice																 // c: Unix character device, when ModeDevice is set
	 185  	ModeSticky																		 // t: sticky
	 186  	ModeIrregular																	// ?: non-regular file; nothing else is known about this file
	 187  
	 188  	// Mask for the type bits. For regular files, none will be set.
	 189  	ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice | ModeCharDevice | ModeIrregular
	 190  
	 191  	ModePerm FileMode = 0777 // Unix permission bits
	 192  )
	 193  
	 194  func (m FileMode) String() string {
	 195  	const str = "dalTLDpSugct?"
	 196  	var buf [32]byte // Mode is uint32.
	 197  	w := 0
	 198  	for i, c := range str {
	 199  		if m&(1<<uint(32-1-i)) != 0 {
	 200  			buf[w] = byte(c)
	 201  			w++
	 202  		}
	 203  	}
	 204  	if w == 0 {
	 205  		buf[w] = '-'
	 206  		w++
	 207  	}
	 208  	const rwx = "rwxrwxrwx"
	 209  	for i, c := range rwx {
	 210  		if m&(1<<uint(9-1-i)) != 0 {
	 211  			buf[w] = byte(c)
	 212  		} else {
	 213  			buf[w] = '-'
	 214  		}
	 215  		w++
	 216  	}
	 217  	return string(buf[:w])
	 218  }
	 219  
	 220  // IsDir reports whether m describes a directory.
	 221  // That is, it tests for the ModeDir bit being set in m.
	 222  func (m FileMode) IsDir() bool {
	 223  	return m&ModeDir != 0
	 224  }
	 225  
	 226  // IsRegular reports whether m describes a regular file.
	 227  // That is, it tests that no mode type bits are set.
	 228  func (m FileMode) IsRegular() bool {
	 229  	return m&ModeType == 0
	 230  }
	 231  
	 232  // Perm returns the Unix permission bits in m (m & ModePerm).
	 233  func (m FileMode) Perm() FileMode {
	 234  	return m & ModePerm
	 235  }
	 236  
	 237  // Type returns type bits in m (m & ModeType).
	 238  func (m FileMode) Type() FileMode {
	 239  	return m & ModeType
	 240  }
	 241  
	 242  // PathError records an error and the operation and file path that caused it.
	 243  type PathError struct {
	 244  	Op	 string
	 245  	Path string
	 246  	Err	error
	 247  }
	 248  
	 249  func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }
	 250  
	 251  func (e *PathError) Unwrap() error { return e.Err }
	 252  
	 253  // Timeout reports whether this error represents a timeout.
	 254  func (e *PathError) Timeout() bool {
	 255  	t, ok := e.Err.(interface{ Timeout() bool })
	 256  	return ok && t.Timeout()
	 257  }
	 258  

View as plain text