Rust on Motor OS
Motor OS is a Tier-3 Rust target, x86_64-unknown-motor. A
program that uses the standard library and does not depend, directly or through its
crates, on Unix or Windows APIs cross-compiles and runs. This page says what "the
standard library works" means in practice and how Motor OS differs from Unix for a
program that is being ported.
The target
- Static executables with no dynamic linking,
panic=abort, and no ELF TLS; thread-local storage is provided by the runtime. - The standard library's Motor OS layer is deliberately thin: it calls
moto-rt, which forwards to the per-process runtimert.vdsothrough a versioned function table. The runtime is part of the OS image, so a compiled program picks up runtime fixes when the image is updated. - The target is documented in the Rust platform support pages. Building for it needs the Motor toolchain, described on the Toolchains page.
Cross-compiling on Linux, from a project inside the Motor OS checkout, where the
repository's rust-toolchain.toml selects the Motor toolchain (copy that file
into a project that lives elsewhere):
cargo build --release --target x86_64-unknown-motor
The binary goes into the VM with scp (see
Hello Motor OS). On the developer image the same program can be
built natively with rustc or with Lorry.
What std supports
| Module | Status |
|---|---|
std::thread, sync | Threads, thread-local storage, mutexes, condition variables, channels, futex-based parking. |
std::fs | Files, directories, metadata with timestamps, rename, truncate, permissions in the three-role model, advisory file locks. No symbolic or hard links. |
std::net | TCP and UDP, IPv4 and IPv6, name resolution, nonblocking mode, timeouts, TCP_NODELAY, TTL, linger, buffer sizes. No multicast or broadcast. |
std::process | Command with arguments, environment, and stdio piping; kill, wait, and try_wait; exit codes. No fork, no signals, no process groups. |
std::io | Stdio, pipes, IsTerminal; see Terminals for what a terminal is. |
std::env, time, alloc | Arguments, environment, current directory, current_exe; system and monotonic time; the frusa allocator. |
std::os::unix | Not available. Motor-specific extensions come from moto-rt and moto-sys. |
Ported crates and what works on top of them
- mio and Tokio: Motor OS forks backed by the runtime's edge-triggered readiness interface. The runtime, async TCP and UDP, async child processes, and async stdio work; not every Tokio feature is ported.
- hyper, axum, tower-http: httpd-axum serves this site with them.
- rustls with ring: TLS on both the client (curl, Gears) and server (httpd, httpd-axum) side.
- russh and russh-sftp: the SSH server.
- crossterm: a Motor backend that handles terminal size and Ctrl+C the Motor way, so a crossterm program needs no Motor-specific code.
- ctrlc: a fork whose handler is the process's Ctrl+C handler.
- tracing and friends compile unchanged; see Profiling.
- ripgrep: a fork that ships as
rg.
The forks are ordinary Git dependencies, added to a program's Cargo.toml
under [patch.crates-io] (or as a direct dependency, for russh and ctrlc), as
the in-tree programs do:
| Crate | Repository | Branch or tag |
|---|---|---|
| tokio | https://github.com/moturus/tokio.git | tokio-motor-1.47.1_2025-10-07 |
| mio | https://github.com/moturus/mio.git | mio-motor-v1.0.4_2025-10-07 |
| ring | https://github.com/moturus/ring.git | motor-os-0.17.14 |
| crossterm | https://github.com/moturus/crossterm.git | motor-os-support |
| russh | https://github.com/moturus/russh.git | default branch |
| ctrlc | https://github.com/moturus/rust-ctrlc.git | motor-os-rustc |
| cc (for crates that compile C) | https://github.com/moturus/cc-rs.git | main |
As a rule, sans-io crates and crates such as rand or rustls compile and work, sometimes with minor tweaks; async crates that assume Tokio features which are not ported need refactoring; and crates that wrap native Linux or Windows APIs will not work.
Porting notes
- No fork or exec. Use
std::process::Command; the parent's runtime builds the child directly. Programs that fork to daemonize should instead spawn themselves detached, which needsCAP_SPAWN_DETACHEDand theMOTOR_OS_DETACHEDspawn key; rmux's server is the in-tree example. - No signals. Ctrl+C terminates a process with status 130 unless it
registers a handler, through the
ctrlccrate or crossterm'senable_ctrl_c_events(). There is nothing to catch for termination; a killed process just stops. - No users. A process's authority is its capability word, and files
carry per-role permissions. Write permission on a file cannot be given back once removed;
see Filesystem for how to replace such a file.
~is not a home directory in the Unix sense; per-program configuration goes under/user/cfg, and temporary files under/user/tmp(TMPDIR). Interactive programs cannot create top-level directories. - No pty. A terminal is a pipe whose far end behaves like one.
IsTerminalworks; raw mode is a property of the provider, not of the descriptor, and the terminal size arrives in the byte stream. Use crossterm, or read Terminals if you handle escape sequences yourself. - Error codes. Motor OS error codes map to
io::ErrorKindwhere the toolchain's std knows them; a reset connection isConnectionReset, while a few network conditions still surface asNotConnected. A new code needs both a moto-rt release and a toolchain std that knows it. - Memory. An allocation that would push the machine below the safety floor fails before it starts, and spawning is refused under memory pressure with a recoverable error; a page fault on lazy memory below the floor kills the process. See Memory.
- Motor-specific APIs.
moto-rtexposes the runtime (process capabilities and roles, the Ctrl+C handler, the terminal descriptor, file permission updates);moto-sysexposes the syscalls and shared pages (memory pressure, per-process statistics, peer capabilities on a connection);moto-ipc,moto-io,moto-log, andmoto-statsare the IPC, native I/O, logging, and metrics libraries. Services in the tree use them; ordinary programs rarely need to.
C and C++
Rust is the preferred language on Motor OS, but C and C++ are fully supported: a C library, mlibc, sits on a C ABI shim over the same runtime, libc++ sits on top of it, and Clang/LLVM targets Motor OS directly, on the developer image and as a cross-compiler on Linux. See C/C++ on Motor OS.