Rust Coreutils 0.8.0 Release:
We are excited to announce the release of Rust Coreutils 0.8.0 — a major release featuring significant performance gains across core utilities, expanded WebAssembly (WASI) support with a brand-new online playground, and continued hardening against edge-case panics, /dev/full aborts and start of a large-scale migration from nix to rustix** for lower-level syscall safety!
GNU Test Suite Compatibility:
| Result | 0.7.0 | 0.8.0 | Change 0.7.0 to 0.8.0 | % Total 0.7.0 | % Total 0.8.0 | % Change 0.7.0 to 0.8.0 |
|---|---|---|---|---|---|---|
| Pass | 629 | 630 | +1 | 94.59% | 94.74% | +0.15% |
| Skip | 13 | 14 | +1 | 1.95% | 2.11% | +0.16% |
| Fail | 23 | 21 | -2 | 3.46% | 3.16% | -0.30% |
| Error | 0 | 0 | 0 | 0% | 0% | 0% |
| Total | 665 | 665 | 0 |
Highlights:
-
GNU Compatibility & Upstream Collaboration
- 630 passing GNU tests, with 2 fewer failures than 0.7.0
- Continued contributing tests and bug reports upstream to GNU coreutils, strengthening both projects
- Our compatibility work regularly uncovers edge cases in GNU itself, leading to fixes on both sides
-
nix→rustixMigration- Replaced
nixcrate withrustixacross cat, df, wc, tty, tsort, tail, touch, date, mkdir, and uucore - Reduced range of unsafe code in hostname, logname, who, and nice
uucore: usesrustixforsplice(), restricted to Linux
- Replaced
-
Performance Improvements
uucore: Share fluent resources between threads — dd perf +45%uucore: Callrt_sigactiononce instead of 62 times — faster startupls: Replace recursion with iterative depth-first search; remove many unnecessary allocationssort: Performance improvements across sorting pathswc: Improved-cperformance with unextended pipe input (Linux)cat: Avoid unnecessarypipe()when stdout is already a pipe; don't lock stdout beforesplice()dd: Avoid zero-filling buffer atread_and_discardtee: Increased buffer size for large input; removedBoxanddynoverheadnumfmt: Protect name from argv[0] — +3% perfpr: AvoidStringconversion when storing lines to printtrue/false/echo: Avoiduu_app().render_version()for smaller binary
-
WebAssembly (WASI) Support & Online Playground
- New: Online Playground — try Rust Coreutils directly in your browser, powered by WebAssembly (blog post)
- Added WASI support for 70+ utilities including
ls,head,cat,cp,mv,sort,tail, and many more - Embedded all locales in the WASI binary
- Added WASI platform stubs for
FileInformationand IO module inuucore - Single-threaded sort path for WASI; disabled
rayonon WASI
-
Platform Support
- NetBSD: Multiple fixes,
stdbufsupport, expanded CI coverage pathchk: Now builds for Windowswc: Cross-platform building and 32-bit supportstdbuf: Fixed Cygwincfgblock; detect unsupported target at build timeuucore(fs): Madedisplay_permissions_unixcross-platformuucore: Support realtime signals (RTMIN/RTMAX) insignal_by_name_or_valueuucore: PermitDas decimal suffix modifier for GNU compatibility
- NetBSD: Multiple fixes,
-
Documentation & Manpages
- Manpages now include TL;DR examples, links to the source code, and open bugs — see for example
ls - Manpages are available in multiple languages including French and Spanish, refreshed daily
- Added manpage linting in CI to catch formatting issues early
- TL;DR attribution and disclaimer are now translatable
- Manpages now include TL;DR examples, links to the source code, and open bugs — see for example
-
Contributions: This release was made possible by 13 new contributors joining our community
Call to Action:
Try it in your browser — Online Playground powered by WebAssembly
Help us translate — Contribute to Rust Coreutils on Weblate or TL;DR pages
Sponsor us on GitHub to accelerate development: github.com/sponsors/uutils
What's Changed
cat
- cat: Drop a clone() and use clap's default value by @oech3 in #11298
- cat: replace nix with rustix by @oech3 in #11567
- cat: avoid pipe() if stdout is pipe, extend pipe by @oech3 in #11551
- cat: add bench for large size for splice by @oech3 in #11587
- cat: add WASI stub for is_unsafe_overwrite and add to feat_wasm by @sylvestre in #11573
- cat: fallback with pipe() failure by @oech3 in #11635
- cat: don't lock stdout before splice() by @oech3 in #11643
- cat: simplify splice & fix comment by @oech3 in #11627
- cat: add bench by @oech3 in #11525
- cat: remove some unnecessary
to_owned()calls by @cakebaker in #11676
chown
- chown(ref): parse_uid flattened syntax by @hlsxx in #11351
- chown: warn when '.' is used as owner:group separator by @eyupcanakman in #11438
cksum
- cksum family: #[allow(clippy::unwrap_used)] by @oech3 in #11307
- cksum: add length support for shake128 and shake256 validation by @AldanTanneo in #11320
- cksum: Bring back blake3 algorithm by @RenjiSann in #11316
- cksum: rework blake length validation, add tests by @RenjiSann in #11437
- cksum: Match GNU behavior for digest length errors in --check mode by @RenjiSann in #11499
- *sum: protect names against argv[0] by @oech3 in #11375
coreutils
- coreutils: --help >/dev/full panics by @oech3 in #11444
- coreutils: --list arg and no args should fail by @oech3 in #11385
- coreutils: Protect against env -a for security by @oech3 in #10773
- coreutils: strip errno by @oech3 in #11484
- yes, coreutils: backport(enable) 2 GnuTests by @oech3 in #11480
cp
- clippy(cp): fix collapsible_if lint by @mattsu2020 in #11288
- fix(cp): always create dest dirs with owner write bit before fixing permissions by @baa-ableton in #11318
- wasm: add support for cp & mv by @sylvestre in #11572
cut
- cut: Drop a clone() and use clap's default value by @oech3 in #11310
- cut: improve some error messages by @cakebaker in #11338
- cut: reject literal '' delimiter special-casing by @can1357 in #11399
- cut: honor only-delimited in newline-delimiter mode by @can1357 in #11394
- cut: use
?instead ofmatchby @cakebaker in #11461
date
- date: replace nix by rustix by @oech3 in #11646
- date: fix "unused variable" warning by @cakebaker in #11637
- date: fix date +%9223372036854775807c panic by @mattsu2020 in #11046
- date: fix %#P case-swap on lowercase am/pm by @vishakha1411 in #11671
- date: honor narrow width on wide default strftime fields by @vishakha1411 in #11670
- date: apply locale-aware localization before GNU modifier processing by @sylvestre in #11661
- date: add ignored tests for GNU compatibility gaps found by fuzz_date by @sylvestre in #11665
dd
- dd: fix ISO-8859-1 case conversion for conv=lcase/ucase by @sylvestre in #10830
- dd: catch OOM by @oech3 in #11562
- dd: avoid 0-filling buf at read_and_discard by @oech3 in #11583
- dd: do not show zero multiplier warning when zero is the multiplicand by @iburaky2 in #11673
df
- df: replace unsafe libc sync with nix crate by @mattsu2020 in #11279
- df: replace nix by rustix by @oech3 in #11576
env
- env: fix --version and protect against argv[0] by @oech3 in #11370
- env: Disallow ALL in --{ignore,default,block}-signal by @aweinstock314 in #11218
expand
expr
factor
- factor: fix crash on malformed input by @Alonely0 in #11190
- factor: deduplicate code, refactor & optimize parsing by @Alonely0 in #11292
head
- head: reset stale partial line state on reused buffers by @can1357 in #11407
- head: fix error message when input is a directory by @aguimaraes in #11541
- head: split head.rs by @oech3 in #11679
- feat_wasm: add head to the WASM-compatible utilities by @sylvestre in #11570
install
- install: refactor conditional expression by @xtqqczze in #11280
- install: rename
unprivilegedproperty by @cakebaker in #11283 - clippy(install): fix collapsible_if lint by @xtqqczze in #11285
- install: improve help texts by @cakebaker in #11290
ln
- ln: Avoid dereferencing target if --no-dereference is passed by @aweinstock314 in #11253
- ln: Restore backup to destination if linking fails by @aweinstock314 in #11355
- ln: simplify the code by @sylvestre in #11390
ls
- ls: replace recursion with depth-first search by @Alonely0 in #11386
- ls: remove many unnecessary allocations by @Alonely0 in #11447
- chore(ls): refactor codebase into new files by @Alonely0 in #11429
- ls: add header to new files by @cakebaker in #11442
- ls: Fix error message for ls file/missing-file by @oech3 in #11333
- ls: fall back to "." metadata for ".." on WASI by @sylvestre in #11633
- ls,dir,vdir: protect names against argv[0] by @oech3 in #11371
- simplify the ls code by @sylvestre in #11391
mkdir
nice
numfmt
- numfmt: protect name from argv[0], perf +3% by @oech3 in #11379
- numfmt: move duplicate code to function by @cakebaker in #11381
- numfmt: implement the last changes by @sylvestre in #11411
- numfmt: preserve fractional digits when --from-unit is used without suffix by @Eshwar1440 in #11674
- numfmt: add failing test cases by @sylvestre in #11668
- numfmt & others: Dedup some code by @sylvestre in #11645
od
pr
sort
- sort: fix infinite loop on --files0-from read error by @vitkyrka in #11504
- sort: fix warnings about unused stuff on Redox by @cakebaker in #11547
- Sort: improve some of the performances by @sylvestre in #11412
- sort: add locale-aware month sorting (-M) by @sylvestre in #11445
- sort: disable rayon on wasi by @sylvestre in #11595
- sort: add WASI single-threaded sort path & run most of the tests by @sylvestre in #11624
- docs(sort): fix random number generation example by @xtqqczze in #11295
split
stdbuf
- stdbuf: detect unsupported target at build time by @oech3 in #11476
- stdbuf: Fix cfg block for Cygwin by @oech3 in #11311
- stdbuf: remove clippy::unnecessary_wraps by @oech3 in #11545
- stdbuf: use .with_capacity for Vec storing searched paths by @oech3 in #11546
- Fix
stdbufon NetBSD by @0323pin in #11428 - libstdbuf: remove eprintln! causing 2>/dev/full abort by @oech3 in #11213
- uu_stdbuf_libstdbuf: add LICENSE by @michel-slm in #11417
stty
sync
- sync: fix exit code when fcntl failed & 2>/dev/full abort by @oech3 in #11508
- sync: fall back to full sync when --file-system has no operands by @can1357 in #11393
tail
- tail: increase retry delay and sleep interval for flaky test by @mattsu2020 in #11278
- tail: replace nix by rustix by @oech3 in #11606
- tail: add WASI support by disabling notify and pid features by @sylvestre in #11569
tee
- tee: remove Box and dyn by @oech3 in #11578
- tee: increase buf size for large input by @oech3 in #11441
- tee: fix < . message and strip errno by @oech3 in #11483
- tee: simplify by clap by @oech3 in #11582
- tee: reduce if block by @oech3 in #11472
- tee: split cli part of tee.rs by @oech3 in #11640
timeout
- timeout: return timed-out status after kill grace period by @can1357 in #11392
- feat(timeout): add benchmarking support with divan by @mattsu2020 in #9733
touch
tr
- tr: reject unknown character classes during sequence parsing by @can1357 in #11398
- tr: fix graph/print character class mapping by @can1357 in #11405
true/false
tsort
tty
wc
- wc: replace File::from_raw_fd with nix::sys::stat by @mattsu2020 in #11248
- wc: replace nix by rustix by @oech3 in #11575
- wc: improve wc -c perf with unextended pipe input (Linux only) by @oech3 in #11591
- wc: support cross-platform building and 32-bit by @YumeYuka in #11452
- wc: add bench for small file by @oech3 in #11526
- wc: drop #[allow(clippy::question_mark)] by @oech3 in #11638
yes
- yes: Refactor by clap's default value by @oech3 in #11296
- yes: dedup some logic by @oech3 in #11536
- yes: drop unused feat deps by @oech3 in #11518
uucore
- uucore: tr, nice -n . 2>/dev/full does not abort by @oech3 in #10762
- uucore: share a fluent resource between threads - dd perf + 45% by @oech3 in #11220
- uucore: Permit 'D' as a decimal suffix modifier in size parsing for GNU compatibility by @aweinstock314 in #11354
- uucore: use rustix'splice & restrict to Linux by @oech3 in #11566
- uucore: add WASI support for FileInformation and io module by @sylvestre in #11568
- uucore: pipes.rs replace != with > by @oech3 in #11629
- uucore: add a function returning /dev/null to use splice() for wc,dd,tail by @oech3 in #11601
- uucore: add missing feature of rustix by @oech3 in #11632
- uucore: support realtime signals (RTMIN/RTMAX) in signal_by_name_or_value by @kevinburkesegment in #11425
- uucore(fs): make display_permissions_unix cross-platform by @kaladron in #11538
- uucore: drop an unused function by @oech3 in #11460
- perf(uucore): call rt_sigaction once not 62 times by @danielzgtg in #11350
- utmpx.rs: Remove duplicated const by @oech3 in #11323
uudoc
- uudoc: make tldr attribution and disclaimer translatable by @sylvestre in #11450
- uudoc: drop legacy FA4
faclass from platform icons by @sylvestre in #11641 - Improve the manpages & lint them in github by @sylvestre in #11339
CI & Build
- CICD.yml: split jobs for make by @oech3 in #11269
- make.yml: Replace wrong *.yml ref by @oech3 in #11281
- make.yml: Switch to stable from MSRV by @oech3 in #11273
- CICD: Partial check for NetBSD by @oech3 in #11334
- CICD: Check more NetBSD progs by @oech3 in #11408
- CICD.yml: Bump cross for NetBSD by @oech3 in #11496
- l10n.yml: Simplify by @oech3 in #11335
- l10n.yml: drop cargo build covered by cargo {test,run} by @oech3 in #11349
- dedup env: CARGO_INCREMENTAL: 0 by @oech3 in #11360
- run-gnu-tests-smack-ci.sh: copy kernel from Ubuntu runner by @oech3 in #11376
- run-gnu-tests-smack-ci.sh: Use alpine busybox by @oech3 in #11431
- delay=1000 at test_tail::test_follow_name_multiple at non-linux by @oech3 in #11257
- CI: add GNU tests/rm/isatty to intermittent by @Alonely0 in #11486
- GNUmakefile: Do not depend on system tr for Gentoo by @oech3 in #11345
- GNUmakefile: Fix LN for cygwin by @oech3 in #11440
- pathchk: build for Windows by @oech3 in #11495
- github action: Move the clippy management in python + run it on wasm code too by @sylvestre in #11596
- tests: ensure getlimits is on PATH for reused GNU builds by @sylvestre in #11561
- pre-commit: add Cargo.lock sync check by @sylvestre in #11540
- pre-commit: exclude tests/fixtures from all hooks by @sylvestre in #11558
- pre-commit: update cargo-lock-check to suggest changes by @xtqqczze in #11622
- adjust the publish script to ship src/uu/checksum_common by @sylvestre in #11263
- NetBSD fixes by @0323pin in #11388
- Allow
feat_os_unixon NetBSD by @0323pin in #11470 - wasm: make ls pass and prepare more work by @sylvestre in #11563
- wasm: add 21 more utilities to feat_wasm and add WASI platform stubs by @sylvestre in #11574
- wasi: embedded all the locales + add the support in the binary by @sylvestre in #11631
Documentation
- docs(sort): fix random number generation example by @xtqqczze in #11295
- docs(performance): Use gnuls where ls is uutils by @danielzgtg in #11342
- ls,pr: wrap angle-bracket placeholders in backticks to fix mdbook HTML warnings by @sylvestre in #11520
- CONTRIBUTING.md: drop outdated hint, add policies and links by @oech3 in #11433
- arch, uname, Cargo.toml: update outdated info by @oech3 in #11556
- fr-FR: fix anglicisms (supporté→pris en charge, drapeau→option, removed→supprimé) by @sylvestre in #11651
- Remove useless translations by @sylvestre in #11652
Code Quality & Cleanup
- use var_os in a few places by @xtqqczze in #11242
- refactor: replace manual last()+pop() patterns with Vec::pop_if by @mattsu2020 in #11272
- Cargo.toml: dedup feat_require_unix_hostid dep by @oech3 in #11347
- Remove duplicated features by @oech3 in #11510
- hostid: reduce lines by @oech3 in #11502
- logname: reduce range of unsafe block by @oech3 in #11506
- hostname: reduce range of unsafe by @oech3 in #11515
- who: reduce range of unsafe by @oech3 in #11521
- nohup: #[allow(clippy::unwrap_used, reason = ...)] by @oech3 in #11361
- nohup: use LazyLock for FAILURE_CODE by @xtqqczze in #11524
- refactor(base32): use filter_map by @xtqqczze in #11463
- baseNM: protect names against argv[0] by @oech3 in #11373
- protect names against binary name by @oech3 in #11378
- fix(deps): refactor icu_ package configuration by @xtqqczze in #11374
- fix(deps): refactor crc-fast package configuration by @xtqqczze in #11372
- gate uucore::pipes::pipe to test by @oech3 in #11649
- uutests: add LICENSE by @michel-slm in #11356
- uu_stdbuf_libstdbuf: add LICENSE by @michel-slm in #11417
Version Management
- Revert "Cargo.toml: Avoid huge diff generation at version bump" by @sylvestre in #11259
- prepare release 0.8.0 by @sylvestre in #11449
Dependency Updates
- chore(deps): update actions/upload-artifact action to v7 by @renovate[bot] in #11275
- chore(deps): update dawidd6/action-download-artifact action to v16 by @renovate[bot] in #11277
- chore(deps): update rust crate tempfile to v3.27.0 by @renovate[bot] in #11289
- chore(deps): update reactivecircus/android-emulator-runner action to v2.36.0 by @renovate[bot] in #11293
- chore(deps): update rand and related crates to version 0.10 by @xtqqczze in #11172
- chore(deps): update dawidd6/action-download-artifact action to v17 by @renovate[bot] in #11300
- chore(deps): update rust crate nix to 0.31.2 by @xtqqczze in #11301
- chore(deps): update rust crate bitflags to 2.11.0 by @xtqqczze in #11303
- chore(deps): update rust crate getrandom to 0.4.2 by @xtqqczze in #11304
- chore(deps): update rust crate clap to v4.6.0 by @renovate[bot] in #11305
- chore(deps): update rust crate clap_complete to v4.6.0 by @renovate[bot] in #11306
- chore(deps): update rust crate clap_mangen to v0.2.33 by @renovate[bot] in #11308
- chore(deps): update rust crate console to v0.16.3 by @renovate[bot] in #11319
- chore(deps): update dawidd6/action-download-artifact action to v18 by @renovate[bot] in #11322
- chore(deps): update reactivecircus/android-emulator-runner action to v2.37.0 by @renovate[bot] in #11324
- chore(deps): update rust crate console to v0.16.3 by @xtqqczze in #11331
- chore(deps): update rust crate pretty_assertions to v1.4.1 by @xtqqczze in #11332
- chore(deps): update nick-fields/retry action to v4 by @renovate[bot] in #11426
- chore(deps): update rust crate zip to v8.3.0 by @renovate[bot] in #11418
- chore(deps): update rust crate itoa to v1.0.18 by @renovate[bot] in #11424
- chore(deps): update dawidd6/action-download-artifact action to v19 by @renovate[bot] in #11382
- chore(deps): update rust crate zip to v8.3.1 by @renovate[bot] in #11446
- chore(deps): update endbug/add-and-commit action to v10 by @renovate[bot] in #11459
- chore(deps): update rust crate zip to v8.4.0 by @renovate[bot] in #11462
- chore(deps): update rust crate terminal_size to v0.4.4 by @renovate[bot] in #11468
- chore(deps): update davidanson/markdownlint-cli2-action action to v23 by @renovate[bot] in #11501
- chore(deps): update codecov/codecov-action action to v6 by @renovate[bot] in #11509
- chore(deps): update rust crate clap_mangen to 0.3 by @renovate[bot] in #11527
- chore(deps): update rust crate uutils_term_grid to 0.8 by @renovate[bot] in #11267
- chore(deps): update rust crate rustc-hash to v2.1.2 by @renovate[bot] in #11533
- chore(deps): update rust crate ctor to 0.8.0 by @renovate[bot] in #11528
- Bump
sm3& add crates to skip list by @cakebaker in #11535 - Bump icu_* crates from
2.1.1to2.2.0& fix deprecation warnings by @cakebaker in #11590 - chore(deps): update rust crate blake3 to v1.8.4 by @renovate[bot] in #11550
- chore(deps): update rust crate platform-info to v2.1.0 by @renovate[bot] in #11552
- chore(deps): update rust crate zip to v8.5.0 by @renovate[bot] in #11586
- chore(deps): update rust crate icu_provider to v2.2.0 by @renovate[bot] in #11585
- fix(deps): update rust crate similar to v3 by @renovate[bot] in #11588
- chore(deps): update rust crate icu_calendar to v2.2.1 by @renovate[bot] in #11600
- chore(deps): update dawidd6/action-download-artifact action to v20 by @renovate[bot] in #11608
- chore(deps): update rust crate libredox to 0.1.15 by @xtqqczze in #11625
New Contributors
- @BAMF0 made their first contribution in #11284
- @AldanTanneo made their first contribution in #11320
- @danielzgtg made their first contribution in #11342
- @venoosoo made their first contribution in #11327
- @baa-ableton made their first contribution in #11318
- @can1357 made their first contribution in #11399
- @vitkyrka made their first contribution in #11504
- @kaladron made their first contribution in #11538
- @eyupcanakman made their first contribution in #11438
- @kevinburkesegment made their first contribution in #11425
- @YumeYuka made their first contribution in #11452
- @vishakha1411 made their first contribution in #11671
- @Eshwar1440 made their first contribution in #11674
Full Changelog: 0.7.0...0.8.0