fs

package
v0.0.0-...-7c31ad9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2022 License: Apache-2.0 Imports: 11 Imported by: 2

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultTime = time.Unix(api.DefaultTime, 0).UTC()

Use this for the accessTime attribute when one is needed but no more obvious value is at hand, or for modifiedTime when doing things like 'create a default dir' when no other value is at hand.

Functions

func NewBreakoutError

func NewBreakoutError(OpArea AbsolutePath, OpPath RelPath, LinkPath RelPath, LinkTarget string) error

func NormalizeIOError

func NormalizeIOError(ioe error) error

Categorize any errors into errcat-style errors with a category of `fs.ErrorCategory` type. Well-recognized errors will be normalized to a specific type, and all other errors will have a category of `ErrMisc`.

func Walk

func Walk(afs FS, preVisit WalkFunc, postVisit WalkFunc) error

Walks a filesystem.

This is much like the standard library's `path/filepath.Walk`, except it's based on `treewalk`, which means it supports both pre- and post-order traversals; and, if uses fs.RelPath (of course) to normalize path names.

If walking directories, implicitly the first path will always be `./`; if the basePath is a file however, the first (and only) path with be `.`. This retains the same invarients from the perspective of the visit funcs (namely, that `filepath.Join(basePath, node.Path)` must be a correct path), but may also require additional understanding from the calling code to handle single files correctly.

In order to get a name for the file in special case that basePath is a single file, use `node.Info.Name()`.

Symlinks are not followed.

The traversal order of siblings is *not* guaranteed, and is *not* necessarily stable.

Caveat: calling `node.NextChild()` during your walk results in undefined behavior.

Types

type AbsolutePath

type AbsolutePath struct {
	// contains filtered or unexported fields
}

Relative paths and absolute paths are not interchangeable. Using these path structures aids in keeping these ideas separate and hopefully prevent certain kinds of errors caused by accidentally using the incorrect path type. It is recommended to use absolute paths when possible.

func MustAbsolutePath

func MustAbsolutePath(p string) AbsolutePath

Converts a string to an absolute path struct. Will panic if the given path is not absolute.

func ParseAbsolutePath

func ParseAbsolutePath(p string) (AbsolutePath, error)

Converts a string to an absolute path struct, returning an error if the given path string is not absolute.

func (AbsolutePath) CoerceRelative

func (p AbsolutePath) CoerceRelative() RelPath

func (AbsolutePath) Dir

func (p AbsolutePath) Dir() AbsolutePath

Returns the absolute path of the directory containing this path

func (AbsolutePath) Join

func (p AbsolutePath) Join(p2 RelPath) AbsolutePath

Creates a new absolute path by following the relative path from this path.

func (AbsolutePath) Last

func (p AbsolutePath) Last() string

Returns the filename of this path

func (AbsolutePath) String

func (p AbsolutePath) String() string

An absolute path string with a zero value of "/" for the root directory

type ErrorCategory

type ErrorCategory string
const (
	/*
		The catch-all for errors we haven't particularly mapped.
	*/
	ErrMisc ErrorCategory = "fs-misc"

	ErrUnexpectedEOF ErrorCategory = "fs-unexpected-eof"
	ErrNotExists     ErrorCategory = "fs-not-exists"
	ErrAlreadyExists ErrorCategory = "fs-already-exists"
	ErrNotDir        ErrorCategory = "fs-not-dir"   // contextually, may be a form of either ErrNotExists or ErrAlready exists: shows up when e.g. lstat doesnotexist/deeper/path or mkdir aregularfile/deeper/path.
	ErrRecursion     ErrorCategory = "fs-recursion" // returned when cycles detected in symlinks.
	ErrShortWrite    ErrorCategory = "fs-shortwrite"
	ErrPermission    ErrorCategory = "fs-permission"

	/*
		Error returned when operating in a confined filesystem slice and an
		operation performed would result in effects outside the area, e.g.
		calling `PlaceFile` with "./reasonable/path" but "./reasonable" happens
		to be a symlink to "../../.." -- the symlink is valid, but to traverse
		it would violate confinement.

		Not all functions which do symlink checks will verify if the symlink target
		is within the operational area; they may return ErrBreakout upon encountering
		any symlink, even if following it would still be within bounds.
		Check the function's documentation for more info on how it behaves.

		Note that any function returning ErrBreakout is, by nature, doing so in a
		best-effort sense: if there are concurrent modifcations to the operational
		area of the filesystem by any other processes, it is *impossible* to
		avoid a TOCTOU violation.
	*/
	ErrBreakout ErrorCategory = "fs-breakout"
)

type FS

type FS interface {
	// The basepath this filesystem was constructed with.
	// This may be useful for debugging messages, but should not otherwise
	// be used; there's no reason, since all methods are consistently
	// using it internally.
	// May be '/' (the zero AbsolutePath) if not applicable.
	BasePath() AbsolutePath

	OpenFile(path RelPath, flag int, perms Perms) (File, error)

	Mkdir(path RelPath, perms Perms) error

	Mklink(path RelPath, target string) error

	Mkfifo(path RelPath, perms Perms) error

	MkdevBlock(path RelPath, major int64, minor int64, perms Perms) error

	MkdevChar(path RelPath, major int64, minor int64, perms Perms) error

	Lchown(path RelPath, uid uint32, gid uint32) error

	Chmod(path RelPath, perms Perms) error

	SetTimesLNano(path RelPath, mtime time.Time, atime time.Time) error

	SetTimesNano(path RelPath, mtime time.Time, atime time.Time) error

	Stat(path RelPath) (*Metadata, error)

	LStat(path RelPath) (*Metadata, error)

	ReadDirNames(path RelPath) ([]string, error)

	Readlink(path RelPath) (target string, isSymlink bool, err error)

	/*
		Resolve a symlink (within the confines of the basepath!), returning
		the path to the final result.

		The resolution acts as if the FS basepath is the real root of the
		filesystem: rooted symlinks or excessive '..' segments still
		yield paths within the FS basepath.
		For example, `ResolveLink("../../..", "./lnk")` yields "./".

		This may opt to be bug-for-bug compatible with linux path resolution:
		specifically, for paths like "/untraversable/../target", where the first
		dir is 0000, we will return a permissions error... despite being able
		to clearly see that the following ".." will make the question irrelevant.
	*/
	ResolveLink(symlink string, startingAt RelPath) (RelPath, error)
}

Interface for all primitive functions we expect to be able to perform on a filesystem.

All paths accepted are RelPath types; typically the FS instance is constructed with an AbsolutePath, and all further operations are joined with that base path.

type File

type File interface {
	io.Closer
	io.Reader
	io.ReaderAt
	io.Seeker
	io.Writer
	io.WriterAt
}

type FilewalkNode

type FilewalkNode struct {
	Info *Metadata
	Err  error
	// contains filtered or unexported fields
}

func (*FilewalkNode) NextChild

func (t *FilewalkNode) NextChild() treewalk.Node

type Metadata

type Metadata struct {
	Name     RelPath   // filename
	Type     Type      // type enum
	Perms    Perms     // permission bits
	Uid      uint32    // user id of owner
	Gid      uint32    // group id of owner
	Size     int64     // length in bytes
	Linkname string    // if symlink: target name of link
	Devmajor int64     // major number of character or block device
	Devminor int64     // minor number of character or block device
	Mtime    time.Time // modified time
	Xattrs   map[string]string
}

type Perms

type Perms uint16

The usual posix permission bits (0777) plus the linux interpretation of the setuid, setgid, and sticky bits.

See http://man7.org/linux/man-pages/man2/open.2.html for more information; specifically, store the setuid, setgid, and sticky bits with the same bits as documented for S_ISUID, S_ISGID, and S_ISVTX. http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysstat.h.html documents that any choice for those three bits is valid as long as they do not conflict with the 0777 range, but, why?

More precisely:

#define S_ISUID  0004000
#define S_ISGID  0002000
#define S_ISVTX  0001000

So, '01777' is as it is in your linux system chmod: a sticky bit is set.

Compared to os.FileMode, this conveys the same amount of information as `mode & (ModePerm|ModeSetuid|ModeSetgid|ModeSticky)`, but again note that we follow the bit layout for those additional modes that is standard in the linux headers.

const (
	Perms_Setuid Perms = 0004000
	Perms_Setgid Perms = 0002000
	Perms_Sticky Perms = 0001000
)

type RelPath

type RelPath struct {
	// contains filtered or unexported fields
}

Relative paths and absolute paths are not interchangeable. Using these path structures aids in keeping these ideas separate and hopefully prevent certain kinds of errors caused by accidentally using the incorrect path type. It is recommended to use absolute paths when possible.

func MustRelPath

func MustRelPath(p string) RelPath

Converts a string to an relative path struct. Will panic if the given path is absolute.

func (RelPath) Dir

func (p RelPath) Dir() RelPath

Returns the relative path of the directory containing this path

func (RelPath) GoesUp

func (p RelPath) GoesUp() bool

Predicate for if this path goes "up" -- in other words, if it starts with "..".

func (RelPath) Join

func (p RelPath) Join(p2 RelPath) RelPath

Creates a new relative path by following the relative path from this path.

func (RelPath) Last

func (p RelPath) Last() string

Returns the filename of this path

func (RelPath) Split

func (p RelPath) Split() []RelPath

Returns a slice of relative paths for each segment in the path.

E.g. for "./a/b/c" it will return [".", "./a", "./a/b", "./a/b/c"].

func (RelPath) SplitParent

func (p RelPath) SplitParent() []RelPath

Returns a slice of relative paths for each segment in the path, minus the path itself.

E.g. for "./a/b/c" it will return [".", "./a", "./a/b"]. Importantly, for "." it will return [] -- an empty list (note that this is different than the behavior of `path.Dir().Split()`, which would still yield ["."].)

For some path where you wish to create all parent paths, it may be useful to `range path.SplitParent()`.

func (RelPath) String

func (p RelPath) String() string

An relative path string with a zero value of "." for current directory

type Type

type Type uint8
const (
	Type_Invalid    Type = 0
	Type_File       Type = 'f'
	Type_Dir        Type = 'd'
	Type_Symlink    Type = 'L'
	Type_NamedPipe  Type = 'p'
	Type_Socket     Type = 'S'
	Type_Device     Type = 'D'
	Type_CharDevice Type = 'c'
	Type_Hardlink   Type = 'h' // Rare, and may only appear contextually.
)

func (Type) String

func (t Type) String() string

type WalkFunc

type WalkFunc func(filenode *FilewalkNode) error

Directories

Path Synopsis
Devmodes in most linux follows the gnu_dev_major / gnu_dev_minor library functions.
Devmodes in most linux follows the gnu_dev_major / gnu_dev_minor library functions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL