Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ opened: 2026-09-01
# A child's stdio slot is not the handle `Command` named for it

Found while building a guest arm for
`sys/stdio/toyos.rs`'s error mapping, which needs a child whose own stdin or
`sdk/std/sys/stdio.rs`'s error mapping, which needs a child whose own stdin or
stdout the parent has staged. It could not be staged, twice, and the second one
is a capability statement rather than a plumbing one.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ opened: 2026-09-27

No volume records an object id, so nothing tells the held file from another
put at its path since, and a handle held across a restart answers `Gone`
(`std`'s `sys/fs/toyos.rs`); `logd` loses `/log` for the boot if LOG's server
(`std`'s `sdk/std/sys/fs.rs`); `logd` loses `/log` for the boot if LOG's server
restarts.

**Exit**: DATA's entry carries an object id and a generation that nothing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ opened: 2026-10-04

# A held launcher that will not open is a direct spawn

std's ToyOS `launch` (`library/std/src/sys/process/toyos.rs` in the `rust/`
fork) reads `toyos::endow::launcher().and_then(|held| held.open(LAUNCHER).ok())`:
std's ToyOS `launch` (`sdk/std/sys/process.rs`) reads `toyos::endow::launcher().and_then(|held| held.open(LAUNCHER).ok())`:
a process that holds a launcher and whose open of it fails is treated as one
that holds none, and its spawn of a declared program goes on as a direct spawn,
without that program's row and with no error. The shape is the one `main` had
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ opened: 2026-10-02

`toyos::launch::launch` (`toyos/src/launch.rs`) answers `LaunchError::NotSent`
when `Launch::encode` refuses the request, and std's `Command::launch`
(`rust/library/std/src/sys/process/toyos.rs`) answers `NotSent` with the direct
(`sdk/std/sys/process.rs`) answers `NotSent` with the direct
spawn. `encode` refuses a request whose header, program, argv, environment,
working directory and connector names do not fit `MAX_FRAME_LEN`
(`toyos/src/ipc.rs`). Its other refusal, too many connectors or slots, std
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The kernel resolves a symlink on its own mounts — ROOT and `/tmp` — in its o
tree (`kernel/src/vfs.rs`), and its tree holds nothing under `/apps`,
`/config`, `/home`, `/state`, `/log` or `/boot` but ROOT's empty directories:
those are file servers', reached through a directory capability
(`rust/library/std/src/sys/fs/toyos.rs`). So a link in `/tmp` whose target is
(`sdk/std/sys/fs.rs`). So a link in `/tmp` whose target is
`/home/toy/notes` opens nothing (`NotFound`), where the same link on a served
directory is followed — a file server hands an absolute target back to the
client, which resolves it in its own table.
Expand Down
4 changes: 2 additions & 2 deletions issues/a-provided-name-cannot-reach-an-undeclared-child.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ base's whole entry set when the bit is set and refuses a bit it does not define
(`kernel/src/syscall/ipc.rs`), and `endowment_denied`'s
`the_base_plus_one_more_name` asserts both halves in a guest.

**What is left is the std fork, and only the std lane can do it.**
`rust/library/std/src/sys/process/toyos.rs`'s `spawn` endows the parent's
**What is left is std's ToyOS backend, and only the std lane can do it.**
`sdk/std/sys/process.rs`'s `spawn` endows the parent's
namespace handle unchanged — `inherited_namespace` duplicates it and pushes it
under `SVC_LABEL` — so a caller that transferred a connector to a program the
manifest does **not** declare, the one case where the launcher answers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opened: 2026-09-29

# A Rust std executable runs no `.init_array`, so a C constructor linked into it is skipped

`rust/library/std/src/sys/pal/toyos/mod.rs:93` starts a std binary at
`sdk/std/sys/pal/mod.rs:93` starts a std binary at
`start_rust`, which calls `main` directly and never walks `.init_array`
(the comment there: "exes don't run .init_array"). `userland/libc/src/lib.rs`'s
`start_c` does walk it, but only `#[cfg(not(feature = "std-runtime"))]`: a
Expand Down
6 changes: 3 additions & 3 deletions issues/a-served-file-panics-when-asked-its-raw-fd.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ opened: 2026-09-27

# A served file panics when asked its raw fd

`std::os::toyos::io::AsRawFd` for `std::fs::File` calls the fork's
`File::as_raw_fd` (`rust/library/std/src/sys/fs/toyos.rs`), which panics with
`std::os::toyos::io::AsRawFd` for `std::fs::File` calls the backend's
`File::as_raw_fd` (`sdk/std/sys/fs.rs`), which panics with
"a file on a file server has no kernel handle" for every file under `/apps`,
`/config`, `/home`, `/state`, `/log` and `/boot`. A crate that takes a file's
fd — to lock it, map it or hand it to a C library — builds for ToyOS and
panics there, which is what "existing Rust just works" rules out.

Owner: the std fork's ToyOS file layer.
Owner: std's ToyOS file layer.

**Exit**: `as_raw_fd` on a served file answers without a panic — a kernel
handle that reaches the file's server, as `as_child_stdio`'s pipe does for a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ a name that exists `EEXIST`, so libc's `symlink` refuses `ENOSYS`

**Exit**: `symlink` is the file server's, not the kernel's. libc's `symlink`
sends the request to the server of the directory that is to hold the link, as
std's does (`on_path` in `rust/library/std/src/sys/fs/toyos.rs`), with nothing
std's does (`on_path` in `sdk/std/sys/fs.rs`), with nothing
asked first, and answers its `AlreadyExists` `EEXIST`. fsd makes the link in
the one request that refuses a name that exists, and libc's `readdir` of that
directory names the link, each asserted by a test. The kernel's `SYS_SYMLINK`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The kernel keeps an exited thread in its process's table until
`SYS_THREAD_JOIN` collects it, and counts it against
`toyos_abi::syscall::MAX_THREADS` until then
(`kernel::proclife::spawn::Admit::Full`). std's `Thread`
(`rust/library/std/src/sys/thread/toyos.rs`) has no `Drop`, and a `JoinHandle`
(`sdk/std/sys/thread.rs`) has no `Drop`, and a `JoinHandle`
dropped without `join` detaches, so nothing ever collects a thread std
detached: a program that detaches threads over its life has `thread::spawn`
refused once those that exited and those still running are
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opened: 2026-09-27

# An accept that never reaches netd strands its listener's owner

std's `TcpListener::accept` (`rust/library/std/src/sys/net/connection/toyos.rs`)
std's `TcpListener::accept` (`sdk/std/sys/net/connection.rs`)
reads netd's wake byte first, and only then calls `toyos::net::tcp_accept`,
which reaches netd (`NetdConn::connect`) and makes the data path
(`DataPath::create`) before it sends the request. If either fails, or the send
Expand Down
2 changes: 1 addition & 1 deletion issues/c-programs-name-no-file-a-file-server-holds.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ opened: 2026-09-27

`/apps`, `/config`, `/home`, `/state`, `/log` and `/boot` are served by
`/system/bin/fsd` through directory capabilities in each program's namespace,
and std reaches them through `toyos::fs` (`rust/library/std/src/sys/fs/toyos.rs`).
and std reaches them through `toyos::fs` (`sdk/std/sys/fs.rs`).
`userland/libc` does not: `open`, `stat`, `opendir` and every other path call
in `userland/libc/src/posix_io.rs` and `userland/libc/src/stdio.rs` go to the
kernel's `SYS_OPEN` family, and the kernel serves ROOT and `/tmp` only. So a C
Expand Down
4 changes: 2 additions & 2 deletions issues/create-new-on-a-kernel-path-is-not-exclusive.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ opened: 2026-09-27
# `create_new` on a kernel path is not exclusive

std's `OpenOptions::create_new(true)` promises an open that fails with
`AlreadyExists` when the file is there. The std fork's `to_flags`
(`rust/library/std/src/sys/fs/toyos.rs`) turns `create_new` into the kernel's
`AlreadyExists` when the file is there. std's ToyOS `to_flags`
(`sdk/std/sys/fs.rs`) turns `create_new` into the kernel's
plain `OpenFlags::CREATE`, and the kernel has no exclusive flag to turn it
into, so on `/tmp` a second `create_new` of one path opens the file the first
made and says nothing. A served path does not share it: the file protocol
Expand Down
2 changes: 1 addition & 1 deletion issues/dtv-capacity-is-a-workload-bound.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ scheduler designs establishing that a bound over a workload-set quantity is a
defect rather than a policy, and this is one.

**The refusal has no recoverable form.** The only caller is std's
`__tls_get_addr_slow` (`rust/library/std/src/sys/pal/toyos/tls.rs`), and its own
`__tls_get_addr_slow` (`sdk/std/sys/pal/tls.rs`), and its own
comment says why it cannot pass the error on: *"`__tls_get_addr`'s ABI is an
address and there is nobody to return an error to: a refusal added to `offset` is
a pointer near the top of the address space that the caller would then
Expand Down
4 changes: 2 additions & 2 deletions issues/every-flush-of-a-served-file-syncs-its-whole-volume.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ opened: 2026-09-27

# Every flush of a served file syncs its whole volume

The std fork's `File::flush` is `File::fsync`
(`rust/library/std/src/sys/fs/toyos.rs`), where every other platform's is a
std's ToyOS `File::flush` is `File::fsync`
(`sdk/std/sys/fs.rs`), where every other platform's is a
no-op, and fsd answers `FSYNC` by syncing the volume, every open file's entry
and every dirty block of the cache (`userland/fsd/src/main.rs`, `FSYNC`). So a
`BufWriter` over a file on `/home` syncs all of DATA each time it flushes, and a
Expand Down
32 changes: 32 additions & 0 deletions issues/nothing-keys-the-hosted-rustc-on-stds-sources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
status: open
kind: tooling
opened: 2026-10-07
---

# Nothing keys the hosted rustc on std's sources

Nothing keys the hosted rustc on std's sources. `src/toolchain.rs`'s
`hosted_rustc_owed` reads a stamp and whether `bin/rustc` is there, and no std
source: an edit to `sdk/std`, or to the fork's `library/`, leaves a built
hosted rustc standing, and `src/build.rs`'s `collect_hosted_rustc` ships its
`lib/*.so`, the `libstd-*.so` that rustc itself runs on among them, beside the
rlibs of the build's own sysroot. The compiler's key, which is what forgets a
hosted rustc, reads the fork's `compiler/`, `src/tools`, `src/stage0` and
`Cargo.lock` and nothing of `library/`.

It is also unmeasured since std's ToyOS backend left the fork for `sdk/std`:
no hosted rustc has been built whose std reaches the backend through the
fork's `#[path]` arms. Only the primary checkout builds one, in its own
`rust/` (`issues/a-worktree-cannot-build-a-hosted-rustc-of-its-own.md`), so
the branch that moved the backend could not; no tracked config sets
`hosted-rustc = true`, and the primary held no hosted `stage2` when the move
landed. By reading, bootstrap compiles `library/std` in place and the arms
resolve to the primary's `sdk/std`.

Owner: the build system (`src/toolchain.rs`).

**Exit:** on the primary at a `main` that carries the move, a build whose
config asks for the hosted rustc exits 0, and the `libstd-*.so` under
`rust/build/x86_64-unknown-toyos/stage2/lib` carries `sdk/std/sys/` paths and
no `sys/pal/toyos`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
status: open
kind: tooling
opened: 2026-10-07
---

# Nothing refuses a std that read a worktree file its key does not name

A sysroot's key reads the trees `src/sysroot.rs`'s `SYSROOT_SOURCES` lists,
and nothing holds that list against what std's build read. With `sdk/std`
taken off it, an edit to `sdk/std/sys/pal/mod.rs` that makes every program
exit one higher left the key at `46c572c6e5176094`: `cargo run --
--build-only --arch aarch64` finished in 2 s having built no std, and
`virt_readonly_copyout` passed on the std built before the edit.

`toolchain::assert_std_built_from` reads std's dep-info and decides only
whether its `toyos-abi` and `toyos` sources are this worktree's.
`assert_std_reads_no_worktree` holds the freestanding libraries to reading
nothing of the worktree; ToyOS's std has no check of what it may read there.

**Exit:** a build of ToyOS's std whose dep-info names a file of the worktree
that is outside its fork and outside every tree the key reads is refused by
name, and a test builds that case.
6 changes: 3 additions & 3 deletions issues/os-toyos-io-traits-keep-a-posix-name.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ opened: 2026-08-24
# `std::os::toyos::io` names its raw-handle traits `AsRawFd` and `FromRawFd`

`os::toyos::*` is ToyOS's own extension API and speaks ToyOS, and "fds belong
only in libc jargon" (owner, 2026-08-19). The `rust/` fork's
`library/std/src/os/toyos/io.rs` re-exports `std::os::fd`, so
only in libc jargon" (owner, 2026-08-19).
`sdk/std/os/io.rs` re-exports `std::os::fd`, so
`std::os::toyos::io::{AsRawFd, FromRawFd}` still speak POSIX.
`tests/toyos-rust-tests/src/bin/std_fs.rs` is their one caller in this
repository.

**Exit**: the next time the trait is touched in the fork, `AsRawFd` and
**Exit**: the next time the trait is touched, `AsRawFd` and
`FromRawFd` in `std::os::toyos::io` are renamed to `os::toyos`'s own word for
a raw handle, and `std_fs.rs` uses the new names (owner, 2026-09-30).
8 changes: 4 additions & 4 deletions issues/remove-dir-all-empties-a-directory-and-leaves-it.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opened: 2026-09-05

# `std::fs::remove_dir_all` empties a directory and never removes it

`rust/library/std/src/sys/fs/toyos.rs`'s `remove_dir_all` walks the directory,
`sdk/std/sys/fs.rs`'s `remove_dir_all` walks the directory,
unlinks every file and recurses into every subdirectory, and returns `Ok(())`
without ever calling `rmdir` on anything — its own path included. Every
directory in the tree it walked survives, empty.
Expand Down Expand Up @@ -35,9 +35,9 @@ the same hole.
## Exit condition

`remove_dir_all` removes the directory it was given and every directory under
it. Closes when that lands in the fork and `userland/pkg`'s own `remove_tree`
it. Closes when that lands and `userland/pkg`'s own `remove_tree`
is deleted with it — that walk exists only because this one does not finish.

The fix is one `rmdir(path)` after the loop, and it is in the sysroot's fourth
source (`rust/library`), so it lands on its own branch with the machine's
The fix is one `rmdir(path)` after the loop, and it is in a sysroot
source (`sdk/std`), so it lands on its own branch with the machine's
sysroot claim.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ Every allocation a ToyOS program makes goes through one `dlmalloc` behind a
process-wide `AtomicI32` that a waiter takes with `swap(1, Acquire)` in a
`spin_loop()` loop, never sleeping on a futex:

- std's: `library/std/src/sys/alloc/toyos.rs` in the `rust/` fork at
`a0d44493`, lines 57–72 (`LOCKED`, `lock`, `DropLock`), taken by `alloc`,
- std's: `sdk/std/sys/alloc.rs`, lines 57–72 (`LOCKED`, `lock`, `DropLock`), taken by `alloc`,
`alloc_zeroed`, `dealloc` and `realloc`, lines 74–96.
- libc's, in a program linked without std: `userland/libc/src/lib.rs`, lines
174–188, taken by `LibcAllocator`'s `alloc`, `dealloc` and `realloc`, lines
Expand All @@ -33,7 +32,7 @@ than one thread, among them `userland/sshserver`, `userland/supervisor` and
The futex both need is there: libc's `futex_lock` and `futex_unlock`
(`userland/libc/src/pthread.rs`, lines 116–131), and std's `sync::Mutex`, which
is the futex mutex on ToyOS (`library/std/src/sys/sync/mutex/mod.rs`, over
`library/std/src/sys/pal/toyos/futex.rs`).
`sdk/std/sys/pal/futex.rs`).

Owner track: `issues/toyos-has-its-own-allocator.md`, whose std front
replaces std's allocator; it does not rule whether this lock is fixed on
Expand Down
2 changes: 1 addition & 1 deletion issues/std-and-libc-drop-the-answer-thread-join-gives.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opened: 2026-09-27

# std and libc drop the answer `thread_join` gives

`rust/library/std/src/sys/thread/toyos.rs`'s `Thread::join` and
`sdk/std/sys/thread.rs`'s `Thread::join` and
`userland/libc/src/pthread.rs`'s `pthread_join` call
`toyos_abi::syscall::thread_join` and discard what it returns. A join the
kernel refuses — `NotFound` for a tid it never had or already collected,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ opened: 2026-09-25

# std answers every spawn refusal but `NotFound` as `Other`

The std fork's direct spawn (`rust/library/std/src/sys/process/toyos.rs`, the
`spawned.map_err` in `Command::spawn`, at fork `3f0bda148507`) maps
std's direct spawn (`sdk/std/sys/process.rs`, the
`spawned.map_err` in `Command::spawn`) maps
`SyscallError::NotFound` to `io::ErrorKind::NotFound` and every other
`SyscallError` to `io::ErrorKind::Other`, and keeps no raw code. So a
`Command::current_dir` the kernel refuses as not absolute — `InvalidArgument`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opened: 2026-09-26

# std's C `calloc` answers an overflowing request with a pointer past its block

`library/std/src/sys/pal/toyos/mod.rs`'s `c_allocator` is the `malloc`,
`sdk/std/sys/pal/mod.rs`'s `c_allocator` is the `malloc`,
`calloc`, `free` and `realloc` of every userland program: std defines them
for the Rust crates that call C's allocator, and `/system/bin/doom`'s C gets
them too, because `userland/libc` defines none of the four when it is built
Expand Down
2 changes: 1 addition & 1 deletion issues/std-file-lock-answers-ok-and-locks-nothing.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opened: 2026-10-03

# std's `File::lock` answers `Ok` and locks nothing

The ToyOS file pal in the std fork (`library/std/src/sys/fs/toyos.rs`) answers
std's ToyOS file pal (`sdk/std/sys/fs.rs`) answers
`Ok(())` from `File::lock`, `lock_shared`, `try_lock`, `try_lock_shared` and
`unlock` and takes no lock. Two processes that each ask for the exclusive lock
on one file are both told they hold it, and nothing in the kernel ABI or the
Expand Down
2 changes: 1 addition & 1 deletion issues/std-leaks-a-thread-stack-per-spawn.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opened: 2026-07-30

# Std leaks a whole thread stack on every `thread::spawn`

`rust/library/std/src/sys/thread/toyos.rs` allocates the stack with
`sdk/std/sys/thread.rs` allocates the stack with
`alloc::alloc` (2 MiB minimum), hands its base to `SYS_THREAD_SPAWN`, and never
records the pointer. `Thread` holds only a tid and has no `Drop`, `join` does not
free it, and the trampoline cannot — it is standing on it. So every spawned
Expand Down
2 changes: 1 addition & 1 deletion issues/std-lookup-host-answers-no-address-as-other.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opened: 2026-09-26

# std's lookup_host answers a name with no address as `Other`

The std fork's `lookup_host` (`library/std/src/sys/net/connection/toyos.rs`)
std's `lookup_host` (`sdk/std/sys/net/connection.rs`)
answers netd's empty answer with `io::ErrorKind::Other` and the message
`DNS lookup failed: no results`, and every netd error that is not one of six
kinds with `Other` and `netd error`. A program asking for a name therefore
Expand Down
6 changes: 3 additions & 3 deletions issues/std-maps-a-device-error-to-other-not-uncategorized.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ kind: defect
opened: 2026-09-01
---

# The std fork answers `Other` for a device error, where upstream says `Uncategorized`
# std on ToyOS answers `Other` for a device error, where upstream says `Uncategorized`

`rust/library/std/src/sys/pal/toyos/mod.rs`'s one
`sdk/std/sys/pal/mod.rs`'s one
`SyscallError -> ErrorKind` map sends `SyscallError::Io` to
`io::ErrorKind::Other`. Every other platform in the fork spells that
`Uncategorized` — `sys/io/error/unix.rs:189`, `hermit.rs:29`, `uefi.rs:53`,
Expand All @@ -26,7 +26,7 @@ header and the code it describes is worse than a non-idiomatic arm.
## Exit condition

One change that moves all four together: `Io => ErrorKind::Uncategorized` in
the fork's map, `userland/logd/src/policy.rs`'s header reworded to name the new
that map, `userland/logd/src/policy.rs`'s header reworded to name the new
spelling, its test's constructed kind moved with it, and
`boot_volume_metadata_error` in `tests/common/volumes.rs`, which requires the
guest to print `kind=Other` for a boot volume that refused every read — a fourth
Expand Down
27 changes: 27 additions & 0 deletions issues/std-names-its-toyos-backend-by-a-path-out-of-the-fork.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
status: open
kind: defect
opened: 2026-10-07
---

# std names its ToyOS backend by a path out of the fork

Fourteen arms under `rust/library/std/src` select ToyOS's file with a
`#[path]` that climbs out of the fork into `sdk/std/`, and two of those files,
`sdk/std/os/ffi.rs` and `sdk/std/sys/pal/mod.rs`, name one back in it
(`os/unix/ffi/os_str.rs`, `sys/pal/unsupported/common.rs`). The owner chose
the mechanism when he ruled the backend out of the fork; what it leaves is
this:

- the fork knows where this repository keeps the backend, and the backend
where the fork keeps two of its files, so moving `sdk/std`, `rust/` or
either of those two breaks every fork commit pinned before the move, as
`issues/std-names-the-sdk-crates-by-path.md` says of the two crates;
- the fourteen lines are not upstream-mergeable as written
(`.claude/agents/implementer.md`, "A fork");
- a panic raised in the backend names its file through the arm that selected
it: `library/std/src/sys/time/../../../../../../sdk/std/sys/time.rs`, read
out of the `libstd` the move built.

**Exit:** no `#[path]` under `rust/library` names a file outside the fork, and
none under `sdk/std` names one inside it.
Loading
Loading