Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
314 changes: 314 additions & 0 deletions abi/snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -4497,6 +4497,320 @@
"number": 415
}
],
"vfs_metadata": {
"access_modes": [
{
"name": "F_OK",
"value": 0
},
{
"name": "R_OK",
"value": 4
},
{
"name": "W_OK",
"value": 2
},
{
"name": "X_OK",
"value": 1
}
],
"at_flags": [
{
"name": "AT_FDCWD",
"value": -100
},
{
"name": "AT_SYMLINK_NOFOLLOW",
"value": 256
},
{
"name": "AT_REMOVEDIR",
"value": 512
},
{
"name": "AT_EMPTY_PATH",
"value": 4096
}
],
"dirent_types": [
{
"name": "DT_UNKNOWN",
"value": 0
},
{
"name": "DT_FIFO",
"value": 1
},
{
"name": "DT_CHR",
"value": 2
},
{
"name": "DT_DIR",
"value": 4
},
{
"name": "DT_BLK",
"value": 6
},
{
"name": "DT_REG",
"value": 8
},
{
"name": "DT_LNK",
"value": 10
},
{
"name": "DT_SOCK",
"value": 12
}
],
"fcntl_commands": [
{
"name": "F_DUPFD",
"value": 0
},
{
"name": "F_GETFD",
"value": 1
},
{
"name": "F_SETFD",
"value": 2
},
{
"name": "F_GETFL",
"value": 3
},
{
"name": "F_SETFL",
"value": 4
},
{
"name": "F_GETLK",
"value": 12
},
{
"name": "F_SETLK",
"value": 13
},
{
"name": "F_SETLKW",
"value": 14
},
{
"name": "F_SETOWN",
"value": 8
},
{
"name": "F_GETOWN",
"value": 9
},
{
"name": "F_DUPFD_CLOEXEC",
"value": 1030
},
{
"name": "F_DUPFD_CLOFORK",
"value": 1028
},
{
"name": "F_OFD_GETLK",
"value": 36
},
{
"name": "F_OFD_SETLK",
"value": 37
},
{
"name": "F_OFD_SETLKW",
"value": 38
}
],
"fd_flags": [
{
"name": "FD_CLOEXEC",
"value": 1
},
{
"name": "FD_CLOFORK",
"value": 2
}
],
"file_modes": [
{
"name": "S_IFMT",
"value": 61440
},
{
"name": "S_IFSOCK",
"value": 49152
},
{
"name": "S_IFLNK",
"value": 40960
},
{
"name": "S_IFREG",
"value": 32768
},
{
"name": "S_IFBLK",
"value": 24576
},
{
"name": "S_IFDIR",
"value": 16384
},
{
"name": "S_IFCHR",
"value": 8192
},
{
"name": "S_IFIFO",
"value": 4096
},
{
"name": "S_ISUID",
"value": 2048
},
{
"name": "S_ISGID",
"value": 1024
},
{
"name": "S_ISVTX",
"value": 512
},
{
"name": "S_IRWXU",
"value": 448
},
{
"name": "S_IRUSR",
"value": 256
},
{
"name": "S_IWUSR",
"value": 128
},
{
"name": "S_IXUSR",
"value": 64
},
{
"name": "S_IRWXG",
"value": 56
},
{
"name": "S_IRGRP",
"value": 32
},
{
"name": "S_IWGRP",
"value": 16
},
{
"name": "S_IXGRP",
"value": 8
},
{
"name": "S_IRWXO",
"value": 7
},
{
"name": "S_IROTH",
"value": 4
},
{
"name": "S_IWOTH",
"value": 2
},
{
"name": "S_IXOTH",
"value": 1
},
{
"name": "S_MODE_BITS",
"value": 4095
}
],
"open_flags": [
{
"name": "O_RDONLY",
"value": 0
},
{
"name": "O_WRONLY",
"value": 1
},
{
"name": "O_RDWR",
"value": 2
},
{
"name": "O_ACCMODE",
"value": 3
},
{
"name": "O_CREAT",
"value": 64
},
{
"name": "O_EXCL",
"value": 128
},
{
"name": "O_NOCTTY",
"value": 256
},
{
"name": "O_TRUNC",
"value": 512
},
{
"name": "O_APPEND",
"value": 1024
},
{
"name": "O_NONBLOCK",
"value": 2048
},
{
"name": "O_DIRECTORY",
"value": 65536
},
{
"name": "O_NOFOLLOW",
"value": 131072
},
{
"name": "O_CLOEXEC",
"value": 524288
},
{
"name": "O_CLOFORK",
"value": 8388608
}
],
"seek_whence": [
{
"name": "SEEK_SET",
"value": 0
},
{
"name": "SEEK_CUR",
"value": 1
},
{
"name": "SEEK_END",
"value": 2
}
]
},
"wakeup_events": {
"fields": [
{
Expand Down
2 changes: 0 additions & 2 deletions crates/kernel/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4179,8 +4179,6 @@ pub fn sys_execveat(
path: &[u8],
flags: u32,
) -> Result<(), Errno> {
const AT_EMPTY_PATH: u32 = 0x1000;

if flags & AT_EMPTY_PATH != 0 && path.is_empty() {
// fexecve path: exec the file referenced by dirfd
let entry = proc.fd_table.get(dirfd)?;
Expand Down
9 changes: 9 additions & 0 deletions crates/shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ pub mod flags {
pub const O_ACCMODE: u32 = 3;
pub const O_CREAT: u32 = 0o100;
pub const O_EXCL: u32 = 0o200;
pub const O_NOCTTY: u32 = 0o400;
pub const O_TRUNC: u32 = 0o1000;
pub const O_APPEND: u32 = 0o2000;
pub const O_NONBLOCK: u32 = 0o4000;
Expand All @@ -511,6 +512,7 @@ pub mod flags {
pub const AT_FDCWD: i32 = -100;
pub const AT_SYMLINK_NOFOLLOW: u32 = 0x100;
pub const AT_REMOVEDIR: u32 = 0x200;
pub const AT_EMPTY_PATH: u32 = 0x1000;
}

/// File descriptor flags (FD_*).
Expand Down Expand Up @@ -672,6 +674,11 @@ pub mod mode {
pub const S_IFCHR: u32 = 0o020000;
pub const S_IFIFO: u32 = 0o010000;

// Special permission bits
pub const S_ISUID: u32 = 0o4000;
pub const S_ISGID: u32 = 0o2000;
pub const S_ISVTX: u32 = 0o1000;

// Owner permissions
pub const S_IRWXU: u32 = 0o700;
pub const S_IRUSR: u32 = 0o400;
Expand All @@ -689,6 +696,8 @@ pub mod mode {
pub const S_IROTH: u32 = 0o004;
pub const S_IWOTH: u32 = 0o002;
pub const S_IXOTH: u32 = 0o001;

pub const S_MODE_BITS: u32 = S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO;
}

/// Shared-memory channel layout offsets and sizes.
Expand Down
2 changes: 1 addition & 1 deletion docs/plans/2026-05-20-rust-owned-host-logic-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ path.
| In progress / stacked PR | Process lifecycle cleanup consolidation | Rust `ProcessTable` now owns parent lookup, wait-target matching, wait-status derivation, host-crash zombie marking, authorized child reaping, thread-exit clear-tid metadata, SysV shared-memory attachment metadata, host-bridged TCP listener target policy, and process-owned host timer cleanup metadata. TS keeps blocked waiter queues, Worker/memory cleanup, platform timer handles, process-memory writes/futex wakeups, and the actual TCP server objects because those are host primitives. Remaining audit: thread channel/Worker allocation and free-list lifecycle. | Kernel owns process lifecycle invariants that do not require Worker identity; JS owns Worker termination, memory objects, crash observation, and platform callbacks. | ProcessTable unit tests; fork/exec/spawn/clone/wait tests; crash/trap tests; browser parity smoke when worker entries change. |
| In progress / stacked PR | IPC/resource cleanup in Rust | Rust `Process` now records `shmat` address -> segment metadata, inherits it through fork, clears it across exec setup, and detaches live mappings from `remove_process()`. TS still copies bytes between guest memory and kernel SysV segments because only the host can address guest `Memory`. | `remove_process()` owns IPC attachment cleanup; JS only handles guest-memory transfer and host primitive wake/schedule work. | SysV IPC and mqueue Rust tests plus host integration/e2e coverage for blocking and cleanup. |
| In progress / stacked PR | Readiness metadata improvements | Rust/shared now owns the kernel wakeup event record layout, wake-type bits, poll/epoll event bits, and `fd_set` sizing consumed by the host. Kernel wakeup events now target matching poll retries by pipe index before falling back to the broad retry pass; select/pselect and signal-safe ppoll/pselect fallback behavior remains JS-owned. | JS still owns timers/retry queues/`Atomics.waitAsync`, but readiness decisions are less inferred from syscall numbers. No extra Wasm round trip per syscall. | Pipe/socket/poll/select/ppoll/pselect tests; browser bridge smoke for affected wake paths; performance comparison before removing broad fallback logic. |
| Planned | VFS policy split | Keep backend I/O, OPFS/IndexedDB/fetch, Node `fs`, and lazy archive materialization in JS. Move permission and policy decisions into Rust where process uid/gid/umask/fd context is authoritative. | Guest-visible policy is enforced in Rust; host adapters only perform platform operations requested through a checked contract. | VFS unit tests, uid/gid/permission tests, host-fs metadata tests, default mount tests, Node/browser parity tests. |
| In progress / stacked PR | VFS policy split | Rust/shared now owns VFS-visible open flags, `*at` flags, fd/fcntl flags, access modes, file mode bits, dirent types, and seek constants generated into `host/src/generated/abi.ts`; host VFS adapters and the WASI shim consume those generated values. Standalone OPFS worker and vendored SharedFS internals keep local copies because they are entry-point/vendor boundaries. Kernel already enforces uid/gid/umask permission checks from host stat metadata. Remaining design work: explicit mount/read-only policy contract and Node/browser backend parity for enforcing it. | Guest-visible constants and existing permission policy metadata are Rust-owned. Mount/read-only enforcement needs a checked contract before host adapters can become pure platform executors. | Generated ABI vitest; `check-abi-version.sh`; VFS unit tests, uid/gid/permission tests, host-fs metadata tests, default mount tests, Node/browser parity tests before changing enforcement behavior. |
| Done / stacked PR | Procfs/process snapshot schema metadata | `crates/shared` owns the binary process snapshot layout, `dump-abi` publishes the schema in `abi/snapshot.json` and generated TS bindings, and `parseProcSnapshots` consumes those generated offsets and sizes. | TS no longer hand-decodes undocumented offsets for kernel process snapshot data. Procfs text formatting remains Rust-owned. | Rust procfs/process snapshot tests; generated ABI vitest; UI/kernel-host tests that consume snapshots. |

Deferral rule: if a chunk would move browser/Node primitives, add runtime JS
Expand Down
Loading
Loading