Module: fs.stat
Source: ./fs/stat.reef
Overview
fs/stat - File metadata and type queries
Provides functions for querying file type and metadata via stat/lstat. All functions accept a path string and return the requested information.
Metadata accessors return Result[T, error.Error]: Ok(value) on success, Err(NotFound) when the path does not exist, Err(IoError) for other stat failures (e.g. a component of the path exists but is unusable). file_size and file_mtime are int64 (file sizes can exceed 2^31 bytes; mtime needs to survive the year-2038 rollover of a 32-bit time_t).
UID/GID name resolution returns Option[string]: None means there is no passwd/group entry for that id (not that the lookup itself failed — that's only possible via a bad path, which file_uid_name/file_gid_name report as Err).
Functions
fn is_file(path: string): bool
fn is_directory(path: string): bool
fn is_symlink(path: string): bool
fn is_pipe(path: string): bool
fn is_socket(path: string): bool
fn is_block_device(path: string): bool
fn is_char_device(path: string): bool
fn exists(path: string): bool
fn io_failure_kind(path: string): error.ErrorKind
The path exists, so whatever failed was I/O; it does not, so NotFound.
USE ONLY WHERE THE PATH IS EXPECTED TO EXIST BEFORE THE OPERATION -- opening for READ, deleting, renaming, stat'ing, removing a directory.
This constraint is load-bearing and predates the merge; io.buffer carried it as a warning on its own copy. fopen(path, "w"/"a") never creates the file on failure, so an exists()-recheck after a failed WRITE open always sees the path absent and would misclassify every write-open failure -- including permission-denied on the parent directory -- as NotFound. Write and append opens use a flat IoError instead (io.file's writeFile / appendFile / writeBinaryFile set that precedent, and io.stream.stream_open branches on mode before it gets here).
What the IoError case actually covers at the call sites: permission denied on the parent directory, a non-directory component in the path, a cross-device rename, a missing parent for the destination, and a directory that is not empty -- ENOTEMPTY is not separately observable through these runtime entry points.
fn access_failure_kind(path: string): error.ErrorKind
The path exists, so the refusal was about permission; it does not, so NotFound.
The distinction from io_failure_kind is the ErrorKind for the exists case, and it is a real one: a caller retrying on IoError should not retry a PermissionDenied. Once existence is ruled out, permission is the dominant real-world cause for the operations that use this -- EPERM, a read-only filesystem, not being the owner.
io.dir.change_dir wrote this inverted ("if not exists return NotFound; return PermissionDenied"), which is the same predicate and was the harder half to spot.
fn file_size(path: string): result.Result[int64, error.Error]
fn file_mode(path: string): result.Result[int, error.Error]
fn file_uid(path: string): result.Result[int, error.Error]
fn file_gid(path: string): result.Result[int, error.Error]
fn file_mtime(path: string): result.Result[int64, error.Error]
fn uid_name(uid: int): option.Option[string]
Resolves a uid to its passwd-database username.
Returns None if there is no passwd entry for uid.
fn gid_name(gid: int): option.Option[string]
Resolves a gid to its group-database name.
Returns None if there is no group entry for gid.
fn file_uid_name(path: string): result.Result[option.Option[string], error.Error]
Looks up the owning user's name for path in one call (stat + resolve).
Err(NotFound/IoError) if path cannot be stat'd; otherwise Ok(uid_name(owner)),
which is None if the owning uid has no passwd entry.
Implemented directly against the raw stat (rather than composing file_uid + uid_name through core.result's is_err/unwrap_err). Composing file_uid()/file_gid() here would work. Kept as the direct form for clarity rather than churning it.
fn file_gid_name(path: string): result.Result[option.Option[string], error.Error]
Looks up the owning group's name for path in one call (stat + resolve).
Err(NotFound/IoError) if path cannot be stat'd; otherwise Ok(gid_name(group)),
which is None if the owning gid has no group entry.
(See file_uid_name's comment for why this is implemented against the raw
stat rather than composing file_gid + gid_name.)
Generated by reefc doc