Skip to content

Replace the nix crate by rustix#11548

Draft
sylvestre wants to merge 21 commits intouutils:mainfrom
sylvestre:rustix
Draft

Replace the nix crate by rustix#11548
sylvestre wants to merge 21 commits intouutils:mainfrom
sylvestre:rustix

Conversation

@sylvestre
Copy link
Copy Markdown
Contributor

No description provided.

@sylvestre sylvestre changed the title Rustix Replace the nix crate by rustix Mar 30, 2026
@oech3
Copy link
Copy Markdown
Contributor

oech3 commented Mar 30, 2026

By one PR?

@sylvestre
Copy link
Copy Markdown
Contributor Author

sylvestre commented Mar 30, 2026

it is a draft, i want to verify first that it works
benchmarks didn't pass in my branch

@oech3
Copy link
Copy Markdown
Contributor

oech3 commented Mar 30, 2026

I like to use raw lackend for perf as per as possible, but libc backend might needed for some GnuTests depending on LD_PRELOAD.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 30, 2026

Merging this PR will degrade performance by 4.23%

❌ 2 regressed benchmarks
✅ 302 untouched benchmarks
⏩ 46 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation rm_recursive_tree 12.1 ms 12.7 ms -4.23%
Simulation du_wide_tree[(5000, 500)] 9.4 ms 9.7 ms -3.01%

Comparing sylvestre:rustix (d564c7b) with main (ff89074)

Open in CodSpeed

Footnotes

  1. 46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@oech3
Copy link
Copy Markdown
Contributor

oech3 commented Mar 30, 2026

du and rm has some recursive functions. num of syscalls might extreamely increased at those funcs with raw-backend.

Cargo.toml Outdated
rstest_reuse = "0.7.0"
rustc-hash = "2.1.1"
rust-ini = "0.21.0"
rustix = { version = "1.1.4", default-features = false }

This comment was marked as resolved.

@oech3
Copy link
Copy Markdown
Contributor

oech3 commented Mar 30, 2026

du and rm has some recursive functions. num of syscalls might extreamely increased at those funcs with raw-backend.

#11222

@oech3

This comment was marked as off-topic.

@oech3
Copy link
Copy Markdown
Contributor

oech3 commented Mar 31, 2026

Some failing/skipped GnuTests e.g. nfs-removal-race uses LD_PRELOAD which is bypassed by raw-backend.

@github-actions
Copy link
Copy Markdown

GNU testsuite comparison:

GNU test failed: tests/chmod/symlinks. tests/chmod/symlinks is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/misc/sync. tests/misc/sync is passing on 'main'. Maybe you have to rebase?
Note: The gnu test tests/cp/nfs-removal-race is now being skipped but was previously passing.
Note: The gnu test tests/dd/no-allocate is now being skipped but was previously passing.
Note: The gnu test tests/dd/nocache_fail is now being skipped but was previously passing.
Note: The gnu test tests/pr/bounded-memory is now being skipped but was previously passing.
Note: The gnu test tests/stty/bad-speed is now being skipped but was previously passing.
Congrats! The gnu test tests/printf/printf-surprise is now passing!

@sylvestre sylvestre force-pushed the rustix branch 2 times, most recently from 62845d5 to 63dbbbb Compare March 31, 2026 13:07
Add collation_key_buffer (arena) and collation_key_ends (offsets) to
LineData and RecycledChunk, with a collation_key() accessor. All sort
keys for a chunk are stored in a single Vec<u8> to avoid millions of
small heap allocations.
Add rustix 1.1.4 with default-features = false to prepare for
migrating from nix to rustix for safer syscall bindings.
Replace all `nix::libc::*` usages with direct `libc::*` imports
to decouple libc access from the nix crate, as preparation for
migrating from nix to rustix.

Add direct libc dependency to crates that previously relied on
nix's libc re-export: stty, env, sort, date, mknod, touch.
Add a `csignal` module with thin libc-based wrappers for signal
operations that rustix does not cover: signal(), sigaction(),
sigprocmask(), SigSet, SigHandler, and SigmaskHow.

These wrappers will replace nix's signal module as part of the
nix-to-rustix migration.

Also add libc as a non-optional unix dependency for uucore.
Replace nix pipe/splice/vmsplice wrappers with rustix equivalents
in uucore's pipes module. Also migrate cat's splice.rs to use
rustix::io::{read, write} instead of nix::unistd.

The return types change from nix::Result to std::io::Result, which
is more idiomatic and compatible with the broader ecosystem.
Replace nix process functions with rustix equivalents:
- geteuid/getegid/getuid/getgid/getpid/getpgrp/getsid -> rustix::process
- kill/test_kill -> rustix::process::kill_process/test_kill_process
- Signal::try_from -> signal_from_raw helper using from_raw_unchecked
- SigHandler for send_signal_group -> csignal wrapper

The getsid return type changes from Result<pid_t, Errno> to
io::Result<pid_t>, which is more idiomatic.
Replace all nix APIs with rustix equivalents in the security-critical
TOCTOU-safe filesystem traversal module:

- nix::dir::Dir -> rustix::fs::Dir (uses Dir::read_from which borrows fd)
- nix::fcntl::{OFlag, openat} -> rustix::fs::{OFlags, openat}
- nix::sys::stat::{fstat, fstatat, fchmod, fchmodat, mkdirat} -> rustix::fs
- nix::unistd::{fchown, fchownat, unlinkat} -> rustix::fs
- FchmodatFlags/UnlinkatFlags -> rustix::fs::AtFlags
- Error handling simplified: rustix Errno implements Into<io::Error>

Also update rm's unix platform code to use the new Stat type.

All 31 safe_traversal unit tests pass.
…ustix

- mode.rs: nix::sys::stat::{Mode, umask} -> rustix::process::umask, rustix::fs::Mode
- fs.rs: nix::sys::stat::{fstat, stat, lstat, FileStat} -> rustix::fs equivalents
- buf_copy/linux.rs: nix::unistd::{read, write} -> rustix::io::{read, write},
  nix::Error -> rustix::io::Errno
Replace all nix signal and poll APIs in uucore:
- signals.rs: nix::sys::signal -> csignal wrappers
- signals.rs: nix::poll -> rustix::event::poll
- signals.rs: nix::sys::stat -> rustix::fs::fstat + libc constants
- lib.rs: nix sigaction -> csignal::set_signal_action
- dd/progress.rs: update install_sigusr1_handler to use libc::SIGUSR1

Return types change from nix::Result/Errno to std::io::Result.
@sylvestre sylvestre force-pushed the rustix branch 2 times, most recently from 789a64f to be64e4a Compare March 31, 2026 13:18
Migrate 19 utility crates from nix to rustix and direct libc calls:

- kill, timeout, env: signal handling via csignal wrappers + libc
- sync, cat, tail, dd, tsort: file operations via rustix::fs
- touch: futimens via rustix::fs::futimens
- stty, tty: terminal ops via rustix::termios + libc ioctl
- sort: getrlimit via rustix::process, sysconf via libc
- wc, cp, df: stat/fstat via rustix::fs
- nice: priority via rustix::process
- mkfifo, mknod: via direct libc calls

Also add rustix::io::Errno conversions to uucore error.rs.
- Remove nix dependency from uucore Cargo.toml
- Remove nix error conversion impls from error.rs, replace with rustix
- Migrate date's clock_settime/clock_getres from nix to rustix::time
- Replace nix dependency with rustix in date's Cargo.toml
- Update test nix features for test utilities that still need it

The nix crate is now completely removed from all source code (src/).
It remains only as a dev-dependency for test code.
Replace the single unsafe libc::kill() call with safe rustix
equivalents: kill_process, kill_process_group,
kill_current_process_group, and their test_kill_* variants for
signal 0.
Replace unsafe libc::mknod() with safe rustix::fs::mknodat(CWD, ...)
and unsafe libc::umask() with safe rustix::process::umask().
@github-actions
Copy link
Copy Markdown

GNU testsuite comparison:

GNU test failed: tests/chmod/symlinks. tests/chmod/symlinks is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/misc/sync. tests/misc/sync is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/date/date-locale-hour (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/tty/tty-eof (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/rm/isatty (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/follow-name (passes in this run but fails in the 'main' branch)
Note: The gnu test tests/cp/nfs-removal-race is now being skipped but was previously passing.
Note: The gnu test tests/dd/nocache_fail is now being skipped but was previously passing.
Note: The gnu test tests/stty/bad-speed is now being skipped but was previously passing.
Congrats! The gnu test tests/csplit/csplit-heap is now passing!
Congrats! The gnu test tests/env/env-signal-handler is now passing!

@oech3
Copy link
Copy Markdown
Contributor

oech3 commented Mar 31, 2026

splice()

$ truncate -s 9EB huge
$ cat-nix huge|pv>/dev/null
^C.0GiB 0:00:02 [22.3GiB/s]
$ cat-rustix-use-libc huge|pv>/dev/null
^C.9GiB 0:00:03 [23.3GiB/s]
$ cat-rustix huge|pv>/dev/null
^C.4GiB 0:00:03 [15.5GiB/s] 

It might changed if we 100 removed libc too and inline everything.
We can still drop one of a crate needed to build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants