#moonbit-community/rg/sys

    Operating-system abstraction layer for the ripgrep port: arguments, environment, raw stdio, files, directories, metadata and (native only) subprocesses. Errors are IOErrors that render like Rust's io::Error (No such file or directory (os error 2)), always using Linux errno numbers and strerror texts, whatever the host.

    Supported backends: native (C stub, macOS and Linux) and wasm (linear memory backend, WASI preview1). Other backends are not supported.

    #Using it from a wasm executable

    The executable package must export its linear memory as memory:

    options( "is-main": true, link: { "wasm": { "export-memory-name": "memory" } }, )

    The wasm build imports only the WASI functions that both wasmtime and moonrun (moon run --target wasm, moon test --target wasm) implement, so a single binary runs under both:

    moon run --target wasm sys/internal/demo -- ls sys wasmtime run --dir . _build/wasm/debug/build/sys/internal/demo/demo.wasm ls sys

    Paths are resolved against the preopened directories: an absolute path uses the preopen with the longest matching name (--dir /host/path::/guest/path), a relative path uses the . preopen (--dir .; moonrun always preopens the current directory as .), and as a fallback paths are resolved through $PWD. Paths outside every preopen fail with failed to find a pre-opened file descriptor through which "..." could be opened.

    #Limitations on wasm

    • remove_file, symlink and run_command raise Unsupported (remove_dir_all therefore only works on trees of empty directories).
    • metadata cannot see dev/ino (always 0), reports every non-directory as File, and computes len by reading the file.
    • is_tty and stdin_is_readable are always false, now_nanos is 0, hostname is None, and current_dir is $PWD or "." (wasmtime only passes environment variables given with --env or -S inherit-env).

    IOError

    pub suberror IOError {
    IOError(kind~ : IOErrorKind, code~ : Int, message~ : String)
    } derive(
    Debug
    )

    An I/O error, modeled after Rust's std::io::Error.

    code is the errno number displayed for OS errors (the host's number on native, a Linux-style number on wasm), or -1 for errors that do not originate from the operating system.
    impl Show for IOError

    IOError::code

    fn IOError::code(self : IOError) -> Int

    The errno number of this error as displayed (see IOError), or -1 if it is not an OS error.

    IOError::from_errno

    fn IOError::from_errno(code : Int) -> IOError

    Builds an error from a Linux-style errno number. The kind is derived from it, while the displayed code and message are the host's (e.g. ELOOP is 62 on macOS), like Rust's io::Error.

    IOError::kind

    fn IOError::kind(self : IOError) -> IOErrorKind

    The kind of this error.

    IOError::message

    fn IOError::message(self : IOError) -> String

    The message of this error (without the (os error N) suffix).

    IOError::other

    fn IOError::other(kind : IOErrorKind, message : String) -> IOError

    Builds an error that does not originate from the operating system.

    DirEntry

    pub(all) struct DirEntry {
    name : String
    file_type : FileType?
    } derive(Eq,
    Debug
    )

    An entry returned by read_dir.

    file_type is the type reported by the directory listing itself (d_type / WASI dirent.d_type), without following symlinks, or None when the OS does not know it.

    File

    pub struct File {
    // private fields
    }

    An open file (a thin wrapper around a file descriptor).

    File::close

    fn File::close(self : File) -> Unit

    Closes the file. Closing an already closed file does nothing.

    File::fd

    fn File::fd(self : File) -> Int

    The underlying file descriptor.

    File::open

    fn File::open(path : String) -> File raise IOError

    Opens a file for reading.

    File::read

    fn File::read(self : File, buf : FixedArray[Byte], start : Int, len : Int) -> Int raise IOError

    Reads up to len bytes into buf[start:start + len]. Returns the number of bytes read, which is 0 at end of file.

    FileTimes

    pub(all) struct FileTimes {
    modified : Int64?
    accessed : Int64?
    created : Int64?
    } derive(Eq,
    Debug
    )

    File timestamps, as nanoseconds since the Unix epoch. A field is None if the platform doesn't provide it.

    FileType

    pub(all) enum FileType {
    File
    Dir
    Symlink
    Other
    } derive(Eq,
    Debug
    )

    The type of a file system entry.

    IOErrorKind

    pub(all) enum IOErrorKind {
    NotFound
    PermissionDenied
    AlreadyExists
    InvalidInput
    Interrupted
    BrokenPipe
    IsADirectory
    NotADirectory
    Unsupported
    Other
    } derive(Eq,
    Debug
    )

    A coarse classification of I/O errors, modeled after Rust's std::io::ErrorKind.

    Metadata

    pub(all) struct Metadata {
    file_type : FileType
    len : Int64
    dev : UInt64
    ino : UInt64
    } derive(Eq,
    Debug
    )

    Metadata about a file system entry.

    dev and ino are 0 on wasm (WASI preview1 as implemented by all supported runners does not expose them without fd_filestat_get). For the same reason len is -1 (unknown) for files on wasm; use file_len to compute it when needed.

    Metadata::is_dir

    fn Metadata::is_dir(self : Metadata) -> Bool

    Metadata::is_file

    fn Metadata::is_file(self : Metadata) -> Bool

    fn Metadata::is_symlink(self : Metadata) -> Bool

    Process

    pub struct Process {
    // private fields
    }

    A running child process with piped stdout and stderr (see Process::spawn).

    Process::finish

    fn Process::finish(self : Process) -> (Int, Bytes) raise IOError

    Closes the child's stdout, waits for it to exit and returns its exit status (128 + the signal number if it was killed) and its stderr.

    Process::read

    fn Process::read(self : Process, buf : FixedArray[Byte], start : Int, len : Int) -> Int raise IOError

    Reads the child's stdout into buf[start:start+len] (collecting its stderr meanwhile). Returns 0 at the end of the output.

    Process::spawn

    fn Process::spawn(program : String, args : Array[String], stdin_path? : String) -> Process raise IOError

    Spawns program (looked up in PATH) with args, with its stdout and stderr piped. The child's stdin is the file at stdin_path, or /dev/null.

    ProcessOutput

    pub(all) struct ProcessOutput {
    status : Int
    stdout : Bytes
    stderr : Bytes
    } derive(Eq,
    Debug
    )

    The result of run_command.

    args

    fn args() -> Array[String]

    The command line arguments, including the program name.

    canonicalize

    fn canonicalize(path : String) -> String raise IOError

    The canonical, absolute form of path (resolving symlinks).

    create_dir_all

    fn create_dir_all(path : String) -> Unit raise IOError

    Recursively creates a directory and all of its missing parents.

    current_dir

    fn current_dir() -> String?

    The current working directory.

    env_var

    fn env_var(name : String) -> String?

    The value of the environment variable name, if set.

    env_vars

    fn env_vars() -> Array[(String, String)]

    All environment variables.

    exit

    fn exit(code : Int) -> Unit

    Terminates the process with the given exit code.

    file_len

    fn file_len(path : String) -> Int64 raise IOError

    The length of the file at path (following symlinks).

    file_times

    fn file_times(path : String) -> FileTimes raise IOError

    Returns the modification, access and creation times of path (following symlinks).

    hostname

    fn hostname() -> String?

    The host name of the machine.

    ignore_sigpipe

    fn ignore_sigpipe() -> Unit

    Makes writes to a closed pipe fail with a broken pipe error instead of terminating the process (like Rust programs, which ignore SIGPIPE). Spawned processes still get the default disposition.

    is_tty

    fn is_tty(fd : Int) -> Bool

    Whether fd refers to a terminal.

    is_windows

    fn is_windows() -> Bool

    metadata

    fn metadata(path : String) -> Metadata raise IOError

    Metadata for path, following symlinks.

    mmap_supported

    fn mmap_supported() -> Bool

    Whether ripgrep would search files through memory maps on this platform when asked to (it never does on macOS, where they are slow).

    now_nanos

    fn now_nanos() -> Int64

    A monotonic clock reading in nanoseconds.

    path_exists

    fn path_exists(path : String) -> Bool

    Returns true if path exists (following symlinks).

    read_dir

    fn read_dir(path : String) -> Array[DirEntry] raise IOError

    Lists the entries of the directory at path (excluding . and ..).

    read_fd

    fn read_fd(fd : Int, buf : FixedArray[Byte], start : Int, len : Int) -> Int raise IOError

    Reads up to len bytes from fd into buf[start:start + len]. Returns 0 at end of file.

    read_file

    fn read_file(path : String) -> Bytes raise IOError

    Reads the whole file at path.
    fn read_link(path : String) -> String raise IOError

    The target of the symlink at path.

    remove_dir_all

    fn remove_dir_all(path : String) -> Unit raise IOError

    Removes a directory after removing all of its contents. Symlinks are removed, not followed.

    remove_file

    fn remove_file(path : String) -> Unit raise IOError

    Removes a file (or symlink).

    run_command

    fn run_command(program : String, args : Array[String], stdin_path? : String) -> ProcessOutput raise IOError

    Runs program (looked up in PATH) with args to completion, capturing its stdout and stderr. The child's stdin is the file at stdin_path, or /dev/null.

    stdin_is_readable

    fn stdin_is_readable() -> Bool

    Whether stdin is a file, a pipe/FIFO or a socket (and not a terminal).
    fn symlink(target : String, link : String) -> Unit raise IOError

    Creates a symlink at link pointing to target.
    fn symlink_metadata(path : String) -> Metadata raise IOError

    Metadata for path, without following a final symlink.

    write_fd

    fn write_fd(fd : Int, buf : FixedArray[Byte], start : Int, len : Int) -> Unit raise IOError

    Writes all of buf[start:start + len] to fd.

    write_file

    fn write_file(path : String, data : Bytes) -> Unit raise IOError

    Writes data to the file at path, creating or truncating it.