fs
The fs module provides an abstracted interface for accessing an arbitrary filesystem. If you want to work with the host filesystem, you probably want to refer to the functions available in os:: instead, which provides an implementation of fs for the host filesystem.
Index
Types
type dirent = struct {
name: str,
ftype: mode,
};
type filestat = struct {
mask: stat_mask,
mode: mode,
uid: uint,
gid: uint,
sz: size,
inode: u64,
atime: time::instant,
mtime: time::instant,
ctime: time::instant,
};
type finishfunc = fn(iter: *iterator) void;
type flag = enum {
RDONLY = 0,
WRONLY = 1,
RDWR = 2,
CREATE = 64,
EXCL = 128,
CTTY = 256,
TRUNC = 512,
APPEND = 1024,
NONBLOCK = 2048,
DSYNC = 4096,
SYNC = 1052672,
RSYNC = 1052672,
DIRECTORY = 65536,
NOFOLLOW = 131072,
NOATIME = 262144,
NOCLOEXEC = 524288,
PATH = 2097152,
TMPFILE = 4259840,
};
type fs = struct {
close: nullable *closefunc,
open: nullable *openfunc,
openfile: nullable *openfilefunc,
create: nullable *createfunc,
createfile: nullable *createfilefunc,
remove: nullable *removefunc,
rename: nullable *renamefunc,
iter: nullable *iterfunc,
stat: nullable *statfunc,
fstat: nullable *fstatfunc,
readlink: nullable *readlinkfunc,
mkdir: nullable *mkdirfunc,
rmdir: nullable *rmdirfunc,
chmod: nullable *chmodfunc,
fchmod: nullable *fchmodfunc,
chown: nullable *chownfunc,
fchown: nullable *fchownfunc,
chtimes: nullable *chtimesfunc,
fchtimes: nullable *fchtimesfunc,
resolve: nullable *resolvefunc,
link: nullable *linkfunc,
symlink: nullable *symlinkfunc,
};
type iterator = struct {
next: *nextfunc,
finish: nullable *finishfunc,
};
type mode = enum uint {
USER_RWX = 448, USER_RW = 384, USER_RX = 320, USER_R = 256, USER_W = 128, USER_X = 64, GROUP_RWX = 56, GROUP_RW = 48, GROUP_RX = 40, GROUP_R = 32, GROUP_W = 16, GROUP_X = 8, OTHER_RWX = 7, OTHER_RW = 6, OTHER_RX = 5, OTHER_R = 4, OTHER_W = 2, OTHER_X = 1, SETUID = 2048, SETGID = 1024, STICKY = 512, UNKNOWN = 0, FIFO = 4096, DIR = 16384, CHR = 8192, BLK = 24576, REG = 32768, LINK = 40960, SOCK = 49152, };
type nextfunc = fn(iter: *iterator) (dirent | done | error);
type stat_mask = enum uint {
UID = 1 << 0,
GID = 1 << 1,
SIZE = 1 << 2,
INODE = 1 << 3,
ATIME = 1 << 4,
MTIME = 1 << 5,
CTIME = 1 << 6,
};
type chmodfunc = fn(fs: *fs, path: str, mode: mode) (void | error);
type chownfunc = fn(fs: *fs, path: str, uid: uint, gid: uint) (void | error);
type chtimesfunc = fn(fs: *fs, path: str, atime: (time::instant | void), mtime: (time::instant | void)) (void | error);
type closefunc = fn(fs: *fs) void;
type createfilefunc = fn(fs: *fs, path: str, mode: mode, flags: flag) (io::file | error);
type createfunc = fn(fs: *fs, path: str, mode: mode, flags: flag) (io::handle | error);
type fchmodfunc = fn(fd: io::file, mode: mode) (void | error);
type fchownfunc = fn(fd: io::file, uid: uint, gid: uint) (void | error);
type fchtimesfunc = fn(fd: io::file, atime: (time::instant | void), mtime: (time::instant | void)) (void | error);
type fstatfunc = fn(fs: *fs, file: io::file) (filestat | error);
type iterfunc = fn(fs: *fs, path: str) (*iterator | error);
type linkfunc = fn(fs: *fs, old: str, new: str) (void | error);
type mkdirfunc = fn(fs: *fs, path: str, mode: mode) (void | error);
type openfilefunc = fn(fs: *fs, path: str, flags: flag) (io::file | error);
type openfunc = fn(fs: *fs, path: str, flags: flag) (io::handle | error);
type readlinkfunc = fn(fs: *fs, path: str) (str | error);
type removefunc = fn(fs: *fs, path: str) (void | error);
type renamefunc = fn(fs: *fs, oldpath: str, newpath: str) (void | error);
type resolvefunc = fn(fs: *fs, path: str) str;
type rmdirfunc = fn(fs: *fs, path: str) (void | error);
type statfunc = fn(fs: *fs, path: str) (filestat | error);
type symlinkfunc = fn(fs: *fs, target: str, path: str) (void | error);
Errors
type cannotrename = !void;
type error = !(errors::noentry | errors::noaccess | errors::exists | errors::busy | errors::invalid | errors::unsupported | utf8::invalid | wrongtype | cannotrename | io::error);
type wrongtype = !void;
Functions
fn chmod(fs: *fs, path: str, mode: mode) (void | error);
fn chown(fs: *fs, path: str, uid: uint, gid: uint) (void | error);
fn chtimes(fs: *fs, path: str, atime: (time::instant | void), mtime: (time::instant | void)) (void | error);
fn close(fs: *fs) void;
fn create(fs: *fs, path: str, mode: mode, flags: flag = flag::WRONLY | flag::TRUNC) (io::handle | error);
fn create_file(fs: *fs, path: str, mode: mode, flags: flag = flag::WRONLY | flag::TRUNC) (io::file | error);
fn dirent_dup(e: *dirent) dirent;
fn dirent_finish(e: *dirent) void;
fn dirents_free(dirents: []dirent) void;
fn exists(fs: *fs, path: str) bool;
fn fchmod(fs: *fs, fd: io::file, mode: mode) (void | error);
fn fchown(fs: *fs, fd: io::file, uid: uint, gid: uint) (void | error);
fn fchtimes(fs: *fs, fd: io::file, atime: (time::instant | void), mtime: (time::instant | void)) (void | error);
fn finish(iter: *iterator) void;
fn fstat(fs: *fs, fd: io::file) (filestat | error);
fn isblockdev(mode: mode) bool;
fn ischdev(mode: mode) bool;
fn isdir(mode: mode) bool;
fn isfifo(mode: mode) bool;
fn isfile(mode: mode) bool;
fn islink(mode: mode) bool;
fn issocket(mode: mode) bool;
fn iter(fs: *fs, path: str) (*iterator | error);
fn link(fs: *fs, old: str, new: str) (void | error);
fn mkdir(fs: *fs, path: str, mode: mode) (void | error);
fn mkdirs(fs: *fs, path: str, mode: mode) (void | error);
fn mode_perm(m: mode) mode;
fn mode_str(m: mode) const str;
fn mode_type(m: mode) mode;
fn move(fs: *fs, oldpath: str, newpath: str) (void | error);
fn next(iter: *iterator) (dirent | done | error);
fn open(fs: *fs, path: str, flags: flag = flag::RDONLY) (io::handle | error);
fn open_file(fs: *fs, path: str, flags: flag = flag::RDONLY) (io::file | error);
fn readdir(fs: *fs, path: str) ([]dirent | error);
fn readlink(fs: *fs, path: str) (str | error);
fn realpath(fs: *fs, path: str) (str | error);
fn remove(fs: *fs, path: str) (void | error);
fn rename(fs: *fs, oldpath: str, newpath: str) (void | error);
fn resolve(fs: *fs, path: str) str;
fn rmdir(fs: *fs, path: str) (void | error);
fn rmdirall(fs: *fs, path: str) (void | error);
fn stat(fs: *fs, path: str) (filestat | error);
fn strerror(err: error) const str;
fn symlink(fs: *fs, target: str, path: str) (void | error);
Types
type dirent
type dirent = struct {
name: str,
ftype: mode,
};
An entry in a directory. This may be borrowed from the filesystem's internal state. If you want to keep this around beyond one call to next, use dirent_dup.
type filestat
type filestat = struct {
mask: stat_mask,
mode: mode,
uid: uint,
gid: uint,
sz: size,
inode: u64,
atime: time::instant,
mtime: time::instant,
ctime: time::instant,
};
Information about a file or directory. The mask field defines what other fields are set; mode is always set.
type finishfunc
type finishfunc = fn(iter: *iterator) void;
A function which frees state associated with an iterator.
type flag
type flag = enum {
RDONLY = 0,
WRONLY = 1,
RDWR = 2,
CREATE = 64,
EXCL = 128,
CTTY = 256,
TRUNC = 512,
APPEND = 1024,
NONBLOCK = 2048,
DSYNC = 4096,
SYNC = 1052672,
RSYNC = 1052672,
DIRECTORY = 65536,
NOFOLLOW = 131072,
NOATIME = 262144,
NOCLOEXEC = 524288,
PATH = 2097152,
TMPFILE = 4259840,
};
Flags to use for opening a file. Not all operating systems support all flags; at a minimum, RDONLY, WRONLY, RDWR, CREATE, and TRUNC will be supported. Note that NOCTTY and CLOEXEC are on by default, and the CTTY/NOCLOEXEC flags respectively disable them.
type fs
type fs = struct {
close: nullable *closefunc,
open: nullable *openfunc,
openfile: nullable *openfilefunc,
create: nullable *createfunc,
createfile: nullable *createfilefunc,
remove: nullable *removefunc,
rename: nullable *renamefunc,
iter: nullable *iterfunc,
stat: nullable *statfunc,
fstat: nullable *fstatfunc,
readlink: nullable *readlinkfunc,
mkdir: nullable *mkdirfunc,
rmdir: nullable *rmdirfunc,
chmod: nullable *chmodfunc,
fchmod: nullable *fchmodfunc,
chown: nullable *chownfunc,
fchown: nullable *fchownfunc,
chtimes: nullable *chtimesfunc,
fchtimes: nullable *fchtimesfunc,
resolve: nullable *resolvefunc,
link: nullable *linkfunc,
symlink: nullable *symlinkfunc,
};
An abstract implementation of a filesystem, which provides common filesystem operations such as file creation and deletion, but which may be backed by any underlying storage system. See os::cwd for access to the host filesystem.
To create a custom filesystem implementation, embed this type as the first member of a struct with user-specific data and fill out these fields as appropriate.
type iterator
type iterator = struct {
next: *nextfunc,
finish: nullable *finishfunc,
};
A directory iterator. To implement a directory iterator for a filesystem, subtype this struct to store any necessary state and populate the pointers with your implementation.
type mode
type mode = enum uint {
USER_RWX = 448, USER_RW = 384, USER_RX = 320, USER_R = 256, USER_W = 128, USER_X = 64, GROUP_RWX = 56, GROUP_RW = 48, GROUP_RX = 40, GROUP_R = 32, GROUP_W = 16, GROUP_X = 8, OTHER_RWX = 7, OTHER_RW = 6, OTHER_RX = 5, OTHER_R = 4, OTHER_W = 2, OTHER_X = 1, SETUID = 2048, SETGID = 1024, STICKY = 512, UNKNOWN = 0, FIFO = 4096, DIR = 16384, CHR = 8192, BLK = 24576, REG = 32768, LINK = 40960, SOCK = 49152, };
File mode information. These bits do not necessarily reflect the underlying operating system's mode representation, though they were chosen to be consistent with typical Unix file permissions. All implementations shall support at least USER_RW, DIR, and REG.
type nextfunc
type nextfunc = fn(iter: *iterator) (dirent | done | error);
A function which returns the next directory from an iterator.
type stat_mask
type stat_mask = enum uint {
UID = 1 << 0,
GID = 1 << 1,
SIZE = 1 << 2,
INODE = 1 << 3,
ATIME = 1 << 4,
MTIME = 1 << 5,
CTIME = 1 << 6,
};
A mask defining what items are populated in the stat structure.
type chmodfunc
Show undocumented member
type chmodfunc = fn(fs: *fs, path: str, mode: mode) (void | error);
type chownfunc
Show undocumented member
type chownfunc = fn(fs: *fs, path: str, uid: uint, gid: uint) (void | error);
type chtimesfunc
Show undocumented member
type chtimesfunc = fn(fs: *fs, path: str, atime: (time::instant | void), mtime: (time::instant | void)) (void | error);
type closefunc
Show undocumented member
type closefunc = fn(fs: *fs) void;
type createfilefunc
Show undocumented member
type createfilefunc = fn(fs: *fs, path: str, mode: mode, flags: flag) (io::file | error);
type createfunc
Show undocumented member
type createfunc = fn(fs: *fs, path: str, mode: mode, flags: flag) (io::handle | error);
type fchmodfunc
Show undocumented member
type fchmodfunc = fn(fd: io::file, mode: mode) (void | error);
type fchownfunc
Show undocumented member
type fchownfunc = fn(fd: io::file, uid: uint, gid: uint) (void | error);
type fchtimesfunc
Show undocumented member
type fchtimesfunc = fn(fd: io::file, atime: (time::instant | void), mtime: (time::instant | void)) (void | error);
type fstatfunc
Show undocumented member
type fstatfunc = fn(fs: *fs, file: io::file) (filestat | error);
type iterfunc
Show undocumented member
type iterfunc = fn(fs: *fs, path: str) (*iterator | error);
type linkfunc
Show undocumented member
type linkfunc = fn(fs: *fs, old: str, new: str) (void | error);
type mkdirfunc
Show undocumented member
type mkdirfunc = fn(fs: *fs, path: str, mode: mode) (void | error);
type openfilefunc
Show undocumented member
type openfilefunc = fn(fs: *fs, path: str, flags: flag) (io::file | error);
type openfunc
Show undocumented member
type openfunc = fn(fs: *fs, path: str, flags: flag) (io::handle | error);
type readlinkfunc
Show undocumented member
type readlinkfunc = fn(fs: *fs, path: str) (str | error);
type removefunc
Show undocumented member
type removefunc = fn(fs: *fs, path: str) (void | error);
type renamefunc
Show undocumented member
type renamefunc = fn(fs: *fs, oldpath: str, newpath: str) (void | error);
type resolvefunc
Show undocumented member
type resolvefunc = fn(fs: *fs, path: str) str;
type rmdirfunc
Show undocumented member
type rmdirfunc = fn(fs: *fs, path: str) (void | error);
type statfunc
Show undocumented member
type statfunc = fn(fs: *fs, path: str) (filestat | error);
type symlinkfunc
Show undocumented member
type symlinkfunc = fn(fs: *fs, target: str, path: str) (void | error);
Errors
type cannotrename
type cannotrename = !void;
Returned from rename if this rename is not possible due to technical constraints, such as if it would cause a file to move between filesystems. In this situation, other operations (such as copy & remove) may succeed if attempted.
type error
type error = !(errors::noentry | errors::noaccess | errors::exists | errors::busy | errors::invalid | errors::unsupported | utf8::invalid | wrongtype | cannotrename | io::error);
All possible fs error types.
type wrongtype
type wrongtype = !void;
An entry of a particular type was sought, but is something else in practice. For example, opening a file with iter.
Functions
fn chmod
fn chmod(fs: *fs, path: str, mode: mode) (void | error);
Changes mode flags on a file or directory.
fn chown
fn chown(fs: *fs, path: str, uid: uint, gid: uint) (void | error);
Changes ownership of a file.
fn chtimes
fn chtimes(fs: *fs, path: str, atime: (time::instant | void), mtime: (time::instant | void)) (void | error);
Changes the access and modification time of a file. A void value will leave the corresponding time unchanged.
fn close
fn close(fs: *fs) void;
Closes a filesystem. The fs cannot be used after this function is called.
fn create
fn create(fs: *fs, path: str, mode: mode, flags: flag = flag::WRONLY | flag::TRUNC) (io::handle | error);
Creates a new file with the given mode if it doesn't already exist, and opens it for writing.
fn create_file
fn create_file(fs: *fs, path: str, mode: mode, flags: flag = flag::WRONLY | flag::TRUNC) (io::file | error);
Creates a new file with the given mode if it doesn't already exist, and opens it as an io::file for writing. This file will be backed by an open file handle on the host operating system, which may not be possible with all filesystem implementations (such cases will return io::unsupported).
fn dirent_dup
fn dirent_dup(e: *dirent) dirent;
Duplicates a dirent object. Call dirent_finish to get rid of it later.
fn dirent_finish
fn dirent_finish(e: *dirent) void;
Frees memory associated with a dirent object which was duplicated with dirent_dup.
fn dirents_free
fn dirents_free(dirents: []dirent) void;
Frees a slice of dirents.
fn exists
fn exists(fs: *fs, path: str) bool;
Returns true if a node exists at the given path, or false if not.
Note that testing for file existence before using the file can often lead to race conditions. If possible, prefer to simply attempt to use the file (e.g. via "open"), and handle the resulting error should the file not exist.
fn fchmod
fn fchmod(fs: *fs, fd: io::file, mode: mode) (void | error);
Changes mode flags on a io::file.
fn fchown
fn fchown(fs: *fs, fd: io::file, uid: uint, gid: uint) (void | error);
Changes ownership of a io::file.
fn fchtimes
fn fchtimes(fs: *fs, fd: io::file, atime: (time::instant | void), mtime: (time::instant | void)) (void | error);
Changes the access and modification time of an io::file. A void value will leave the corresponding time unchanged.
fn finish
fn finish(iter: *iterator) void;
Frees state associated with an iterator.
fn fstat
fn fstat(fs: *fs, fd: io::file) (filestat | error);
Obtains information about an io::file.
fn isblockdev
fn isblockdev(mode: mode) bool;
Returns true if this item is a block device.
fn ischdev
fn ischdev(mode: mode) bool;
Returns true if this item is a character device.
fn isdir
fn isdir(mode: mode) bool;
Returns true if this item is a directory.
fn isfifo
fn isfifo(mode: mode) bool;
Returns true if this item is a FIFO (named pipe).
fn isfile
fn isfile(mode: mode) bool;
Returns true if this item is a regular file.
fn islink
fn islink(mode: mode) bool;
Returns true if this item is a symbolic link.
fn issocket
fn issocket(mode: mode) bool;
Returns true if this item is a Unix socket.
fn iter
fn iter(fs: *fs, path: str) (*iterator | error);
Returns an iterator for a path, which yields the contents of a directory. Pass empty string to yield from the root. The order in which entries are returned is undefined. The return value must be finished with finish.
fn link
fn link(fs: *fs, old: str, new: str) (void | error);
Creates a new (hard) link at 'new' for the file at 'old'.
fn mkdir
fn mkdir(fs: *fs, path: str, mode: mode) (void | error);
Creates a directory.
fn mkdirs
fn mkdirs(fs: *fs, path: str, mode: mode) (void | error);
Makes a directory, and all non-extant directories in its path.
fn mode_perm
fn mode_perm(m: mode) mode;
Returns the permission bits of a file mode.
fn mode_str
fn mode_str(m: mode) const str;
Converts a mode into a Unix-like mode string (e.g. "-rw-r--r--"). The string is statically allocated, use strings::dup to duplicate it or it will be overwritten on subsequent calls.
fn mode_type
fn mode_type(m: mode) mode;
Returns the type bits of a file mode.
fn move
fn move(fs: *fs, oldpath: str, newpath: str) (void | error);
Moves a file. This will use rename if possible, and will fall back to copy and remove if necessary.
fn next
fn next(iter: *iterator) (dirent | done | error);
Returns the next directory entry from an iterator, or done if none remain. '.' and '..' are skipped. It is a programming error to call this again after it has returned void. Calling this again after an error is safe. The list is not guaranteed to be complete when an error has been returned. The file stat returned may only have the type bits set on the file mode; callers should call stat to obtain the detailed file mode.
fn open
fn open(fs: *fs, path: str, flags: flag = flag::RDONLY) (io::handle | error);
Opens a file.
flag::CREATE isn't very useful with this function, since the new file's mode is set to zero. For this use-case, use create instead.
fn open_file
fn open_file(fs: *fs, path: str, flags: flag = flag::RDONLY) (io::file | error);
Opens a file, as an io::file. This file will be backed by an open file handle on the host operating system, which may not be possible with all filesystem implementations (such cases will return io::unsupported).
flag::CREATE isn't very useful with this function, since the new file's mode is set to zero. For this use-case, use create_file instead.
fn readdir
fn readdir(fs: *fs, path: str) ([]dirent | error);
Reads all entries from a directory. The caller must free the return value with dirents_free.
fn readlink
fn readlink(fs: *fs, path: str) (str | error);
Returns the path referred to by a symbolic link. The return value is statically allocated and will be overwritten on subsequent calls.
fn realpath
fn realpath(fs: *fs, path: str) (str | error);
Canonicalizes a path in this filesystem by resolving all symlinks and collapsing any "." or ".." path components. The return value is statically allocated and will be overwritten on subsequent calls.
fn remove
fn remove(fs: *fs, path: str) (void | error);
Removes a file.
fn rename
fn rename(fs: *fs, oldpath: str, newpath: str) (void | error);
Renames a file. This generally only works if the source and destination path are both on the same filesystem. See move for an implementation which falls back on a "copy & remove" procedure in this situation.
fn resolve
fn resolve(fs: *fs, path: str) str;
Resolves a path to its absolute, normalized value. Relative paths will be rooted (if supported by the fs implementation), and "." and ".." components will be reduced. This function does not follow symlinks; see realpath if you need this behavior. The return value is statically allocated; use strings::dup to extend its lifetime.
fn rmdir
fn rmdir(fs: *fs, path: str) (void | error);
Removes a directory. The target directory must be empty; see rmdirall to remove its contents as well.
fn rmdirall
fn rmdirall(fs: *fs, path: str) (void | error);
Removes a directory, and anything in it.
fn stat
fn stat(fs: *fs, path: str) (filestat | error);
Obtains information about a file or directory. If the target is a symlink, information is returned about the link, not its target.
fn strerror
fn strerror(err: error) const str;
Returns a human-friendly representation of an error.
fn symlink
fn symlink(fs: *fs, target: str, path: str) (void | error);
Creates a new symbolic link at 'path' which points to 'target'.