silk.platform.native.filesystem.
The system calls for files and directories, for the native FileSystem provider.
When to use#
silk.system.filesystem_native uses NativeFileSystem. Application code uses the FileSystem effect
from silk.system.filesystem instead.
Details#
Each operation starts at the root directory and opens each part of the path relative to its
parent. A symbolic link below the root resolves inside the root: an absolute target starts
again at the root, and .. never goes above it. So a path cannot leave the root. At most 40
links resolve in one path. Removing a file and replacing a file act on a final link itself,
not its target, and a listing reports a link as a link.
FileHandle and DirectoryHandle each own one open descriptor. Close them with
NativeFileSystem.closeFile or NativeFileSystem.closeDirectory to get a close error. A
drop also closes them, and keeps an earlier error.
An atomic write makes a new file in the same directory with a unique name, then makes it visible
at the path. A replace uses renameat, which replaces a final symbolic link itself, not its
target. A create uses linkat, which fails if any entry exists. New files get mode 0666,
filtered by the umask. A replace keeps no permissions, owner, extended attributes, or hard links
of the old file. A synchronized write calls fsync on the new file before it is visible, and on
the directory after. This is not F_FULLFSYNC, and it does not promise that data survives a
power loss.
Errors#
Each operation fails with FileError, with a portable reason and the native error code.
writeFileAtomic fails with AtomicWriteError.
Gotchas#
A call that a signal interrupts is made again, except
close, which is never repeated.Other processes must not change the temporary files of an atomic write.
The functions exist only on Darwin on aarch64, and Linux with GNU libc on x86_64 or aarch64.
Import as NativeFileSystem with import silk.platform.native.filesystem { NativeFileSystem }.
Public declarations: 3.
FileHandle#
pub struct FileHandleAn open file. It owns its descriptor, and closes it one time.
Close it with NativeFileSystem.closeFile to get a close error. A drop also closes it, and
keeps an earlier error.
DirectoryHandle#
pub struct DirectoryHandleAn open directory stream. It keeps a name that did not fit in the output, for the next call.
It owns one open descriptor. Close it with NativeFileSystem.closeDirectory to get a close
error. A drop also closes it, and keeps an earlier error.
Implementation Drop for DirectoryHandle#
impl Drop for DirectoryHandleOperation drop#
fn drop(self: &mut DirectoryHandle) -> ()NativeFileSystem#
pub struct NativeFileSystemThe file system functions. Each takes the root directory and a normalized path below it.
When to use#
silk.system.filesystem_native uses it. Application code uses the FileSystem effect from
silk.system.filesystem instead.
Details#
Each operation starts at the root directory and opens each part of the path relative to its
parent. A symbolic link below the root resolves inside the root, so a path cannot leave the
root. Each operation fails with FileError, with a portable reason and the native error code.
Gotchas#
A call that a signal interrupts is made again, except
close, which is never repeated.The functions exist only on Darwin on aarch64, and Linux with GNU libc on x86_64 or aarch64.
Implementation NativeFileSystem#
impl NativeFileSystemAssociated function openFile#
pub effect fn openFile(root: &[u8], path: &[u8], writing: bool, operation: i32) -> FileHandle ! FileErrorOpens a regular file to read, or to write when writing is true. A file to write is truncated
only after it is found to be a regular file.
Associated function createFile#
pub effect fn createFile(root: &[u8], path: &[u8], bytes: &[u8]) -> () ! FileErrorCreates a file at path and writes bytes, only if no entry exists.
Details#
An existing file, directory, or symbolic link fails with AlreadyExists. The new file gets
mode 0666, filtered by the umask. A reader can see a part of the file during the write. If a
later write or close fails, the new partial file stays. It does not call fsync.
Associated function writeFileAtomic#
pub effect fn writeFileAtomic(root: &[u8], path: &[u8], bytes: &[u8], policy: i32, durability: i32, counter: &mut u64) -> () ! AtomicWriteErrorWrites bytes to a temporary file in the same directory, then makes it visible at path in
one step.
Details#
policy 0 replaces with renameat. The path can be absent, a regular file, or a symbolic
link, which is replaced itself. A directory or another kind fails with WrongType. policy 1
creates with linkat, and fails with AlreadyExists if any entry exists.
The temporary name is created with O_EXCL. At most 128 names are tried. The temporary entry
is removed through the open directory, not by its path again.
durability 0 does not sync. durability 1 calls fsync on the file before it is visible,
then on the directory after. An unsupported policy or sync fails.
Errors#
AtomicWriteError has the first error and whether the new contents are visible. A failed sync
or close of the directory reports that they are visible. A temporary entry that cannot be
removed is reported separately with its name.
Associated function syncDirectory#
pub effect fn syncDirectory(root: &[u8], path: &[u8]) -> () ! FileErrorCalls fsync on the directory at path, then closes it.
If the file system does not support it (EINVAL, ENOTSUP, or ENOSYS), it fails with
Unsupported and the native code.
Associated function openDirectory#
pub effect fn openDirectory(root: &[u8], path: &[u8], operation: i32) -> DirectoryHandle ! FileErrorOpens the directory at path as a stream.
Associated function inspect#
pub effect fn inspect(root: &[u8], path: &[u8], outputKind: &mut i32, length: &mut usize, operation: i32) -> () ! FileErrorWrites the kind (0 for a file, 1 for a directory) and the length of the entry at path. A
symbolic link resolves inside the root.
Associated function command#
pub effect fn command(root: &[u8], path: &[u8], command: i32, operation: i32) -> () ! FileErrorCreates a directory (command 0), removes a file or symbolic link (1), or removes an empty
directory (2) at path. It does not follow a final symbolic link.
Associated function readFile#
pub effect fn readFile(handle: &mut FileHandle, output: &mut [u8], operation: i32) -> usize ! FileErrorReads at most output.length bytes into the start of output, and returns the count. Zero
means the end of the file.
Associated function writeFile#
pub effect fn writeFile(handle: &mut FileHandle, input: &[u8], operation: i32) -> () ! FileErrorWrites all of input. If it fails, part of input can be written already.
Associated function next#
pub effect fn next(handle: &mut DirectoryHandle, output: &mut [u8], count: &mut usize, required: &mut usize, outputKind: &mut i32, operation: i32) -> bool ! FileErrorCopies the name of the next directory entry to output, and returns true.
If the name does not fit, it returns false, writes the needed size to required, and keeps
the name for the next call. A true result with a count of 0 is the end of the directory.
Associated function createUnique#
pub effect fn createUnique(root: &[u8], path: &[u8], prefix: &[u8], counter: &mut u64, output: &mut [u8], count: &mut usize, required: &mut usize, operation: i32) -> bool ! FileErrorCreates a directory in path named prefix, -, and 16 hex digits of counter, and returns
true. It tries at most 128 names. If the name does not fit in output, it returns false and
writes the needed size to required.
Associated function closeFile#
pub effect fn closeFile(value: FileHandle, operation: FileOperation) -> () ! FileErrorCloses the file one time. It does not try again after an interrupt.
Associated function closeDirectory#
pub effect fn closeDirectory(value: DirectoryHandle, operation: FileOperation) -> () ! FileErrorCloses the directory stream one time.
Category: Native platform.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, x86_64-unknown-linux-gnu.