From b561e1355474284ea0375e621c0b026479809fe8 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Sun, 18 Oct 2026 18:12:14 +0100 Subject: [PATCH 1/2] refactor(tests): replace rustix::process dependency with rlimit --- Cargo.lock | 11 +++++++++++ Cargo.toml | 2 ++ tests/by-util/test_cat.rs | 9 ++++----- tests/by-util/test_cp.rs | 10 +++++----- tests/by-util/test_dd.rs | 10 +++++----- tests/by-util/test_expand.rs | 4 ++-- tests/by-util/test_ls.rs | 6 +++--- tests/by-util/test_pr.rs | 4 ++-- tests/by-util/test_sort.rs | 27 ++++++++++++--------------- tests/by-util/test_split.rs | 9 ++++----- tests/by-util/test_tee.rs | 8 ++++---- tests/uutests/Cargo.toml | 3 ++- tests/uutests/src/lib/util.rs | 14 ++++---------- 13 files changed, 60 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08443ecba14..bbe29f85a92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -523,6 +523,7 @@ dependencies = [ "pretty_assertions", "rand 0.10.3", "regex", + "rlimit", "rstest", "rstest_reuse", "rustc-hash", @@ -2477,6 +2478,15 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" +[[package]] +name = "rlimit" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f35ee2729c56bb610f6dba436bf78135f728b7373bdffae2ec815b2d3eb98cc3" +dependencies = [ + "libc", +] + [[package]] name = "roff" version = "1.1.1" @@ -4488,6 +4498,7 @@ dependencies = [ "pretty_assertions", "rand 0.10.3", "regex", + "rlimit", "rustix", "tempfile", "uucore", diff --git a/Cargo.toml b/Cargo.toml index ecba1f96c43..0c83279c1e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -113,6 +113,7 @@ rand = { version = "0.10.1", features = ["std_rng"] } rand_chacha = { version = "0.10.0" } rayon = "1.10" regex = "1.10.4" +rlimit = "0.11.0" rstest = "0.28.0" rstest_reuse = "0.7.0" rustc-hash = "2.1.1" @@ -392,6 +393,7 @@ runcon = { optional = true, version = "0.13.0", package = "uu_runcon", path = "s [target.'cfg(unix)'.dev-dependencies] nix = { workspace = true, features = ["fs", "signal"] } +rlimit = { workspace = true } rustix = { workspace = true, features = ["net", "process"] } [build-dependencies] diff --git a/tests/by-util/test_cat.rs b/tests/by-util/test_cat.rs index 877d361bc51..002fcdc1049 100644 --- a/tests/by-util/test_cat.rs +++ b/tests/by-util/test_cat.rs @@ -3,10 +3,10 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore Nofile nonewline cmdline setrlimit ELOOP bcde acde +// spell-checker:ignore NOFILE nonewline cmdline setrlimit ELOOP bcde acde -#[cfg(any(target_os = "linux", target_os = "android"))] -use rustix::process::Resource; +#[cfg(target_os = "linux")] +use rlimit::Resource; #[cfg(unix)] use std::fs::File; use std::fs::OpenOptions; @@ -121,7 +121,6 @@ fn test_fifo_symlink() { #[test] // TODO(#7542): Re-enable on Android once we figure out why setting limit is broken. -// #[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(target_os = "linux")] #[cfg_attr(wasi_runner, ignore = "WASI: rlimit/setrlimit not supported")] fn test_closes_file_descriptors() { @@ -135,7 +134,7 @@ fn test_closes_file_descriptors() { "alpha.txt", "alpha.txt", ]) - .limit(Resource::Nofile, 9, 9) + .limit(Resource::NOFILE, 9, 9) .succeeds(); } diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index f0400cc3d26..57ea5225e1c 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (flags) reflink (fs) tmpfs (linux) filefrag rlimit Rlim Nofile Fsize SIGXFSZ clob btrfs neve ROOTDIR USERDIR outfile subvolume uufs xattrs ELOOP +// spell-checker:ignore (flags) reflink (fs) tmpfs (linux) filefrag rlimit Rlim NOFILE FSIZE SIGXFSZ clob btrfs neve ROOTDIR USERDIR outfile subvolume uufs xattrs ELOOP // spell-checker:ignore bdfl hlsl IRWXO IRWXG nconfined matchpathcon libselinux-devel prwx doesnotexist reftests subdirs mksocket srwx dstlink mcstransd use rstest::rstest; @@ -3370,7 +3370,7 @@ fn test_cp_reflink_insufficient_permission() { #[cfg(target_os = "linux")] #[test] fn test_closes_file_descriptors() { - use rustix::process::Resource; + use rlimit::Resource; let pid = std::process::id(); let fd_path = format!("/proc/{pid}/fd"); @@ -3390,7 +3390,7 @@ fn test_closes_file_descriptors() { .arg("--reflink=auto") .arg("dir_with_10_files/") .arg("dir_with_10_files_new/") - .limit(Resource::Nofile, limit_fd, limit_fd) + .limit(Resource::NOFILE, limit_fd, limit_fd) .succeeds(); } @@ -3400,7 +3400,7 @@ fn test_closes_file_descriptors() { #[cfg(not(wasi_runner))] // linux specific #[test] fn test_cp_failed_write_does_not_spill_into_next_file() { - use rustix::process::Resource; + use rlimit::Resource; const CAP: u64 = 100 * 1024; @@ -3410,7 +3410,7 @@ fn test_cp_failed_write_does_not_spill_into_next_file() { at.write("small2", "another small file\n"); at.mkdir("out"); ucmd.args(&["--reflink=never", "big", "small", "small2", "out"]) - .limit(Resource::Fsize, CAP, CAP) + .limit(Resource::FSIZE, CAP, CAP) .ignore_sigxfsz() .fails() .stderr_contains("'big'"); diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index 6b344eb8863..e8b9172beb5 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, availible, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat abcdefghijklm abcdefghi nabcde nabcdefg abcdefg fifoname FADV DONTNEED Fsize SIGXFSZ rusage maxrss cdefg ncdefg cdefh memfd ftruncate +// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, availible, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat abcdefghijklm abcdefghi nabcde nabcdefg abcdefg fifoname FADV DONTNEED FSIZE SIGXFSZ rusage maxrss cdefg ncdefg cdefh memfd ftruncate use rstest::rstest; use uutests::at_and_ucmd; @@ -2381,14 +2381,14 @@ fn test_count_bytes_with_expanding_block_conv() { #[test] #[cfg(all(unix, not(target_vendor = "apple")))] fn test_stats_are_reported_when_a_write_fails() { - use rustix::process::Resource; + use rlimit::Resource; const CAP: u64 = 768 * 1024; let (at, mut ucmd) = at_and_ucmd!(); let result = ucmd .args(&["if=/dev/zero", "of=capped.bin", "bs=512K", "count=3"]) - .limit(Resource::Fsize, CAP, CAP) + .limit(Resource::FSIZE, CAP, CAP) .ignore_sigxfsz() .fails(); @@ -2404,7 +2404,7 @@ fn test_stats_are_reported_when_a_write_fails() { #[test] #[cfg(all(unix, not(target_vendor = "apple")))] fn test_block_stats_are_reported_when_a_write_fails() { - use rustix::process::Resource; + use rlimit::Resource; const CAP: u64 = 200 * 1024; @@ -2412,7 +2412,7 @@ fn test_block_stats_are_reported_when_a_write_fails() { let result = ucmd .args(&["conv=block", "cbs=1M", "obs=64K", "of=capped.bin"]) .pipe_in("x\n") - .limit(Resource::Fsize, CAP, CAP) + .limit(Resource::FSIZE, CAP, CAP) .ignore_sigxfsz() .fails(); diff --git a/tests/by-util/test_expand.rs b/tests/by-util/test_expand.rs index c943854b8ba..22b2ac35e04 100644 --- a/tests/by-util/test_expand.rs +++ b/tests/by-util/test_expand.rs @@ -248,12 +248,12 @@ fn test_tabs_with_too_large_size() { )] #[test] fn test_large_tab_stop_without_tabs_does_not_allocate() { - use rustix::process::Resource; + use rlimit::Resource; const AS_LIMIT: u64 = 200 * 1024 * 1024; new_ucmd!() - .limit(Resource::As, AS_LIMIT, AS_LIMIT) + .limit(Resource::AS, AS_LIMIT, AS_LIMIT) .arg("--tabs=267672676527678256") .pipe_in("hello\n") .succeeds() diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 97f925a4de2..54bea7dec8f 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -4,7 +4,7 @@ // file that was distributed with this source code. // spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline onetwo somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile tabsize aaaaaaaa bbbb cccc dddddddd ncccc neee naaaaa nbcdef nfffff dired subdired tmpfs mdir COLORTERM mexe bcdef mfoo timefile -// spell-checker:ignore (words) fakeroot setcap drwxr bcdlps mdangling mentry awith acolons Nofile NOTCAPABLE iproduct newfstatat isox +// spell-checker:ignore (words) fakeroot setcap drwxr bcdlps mdangling mentry awith acolons NOFILE NOTCAPABLE iproduct newfstatat isox #![allow( clippy::similar_names, @@ -14,7 +14,7 @@ use regex::Regex; #[cfg(unix)] -use rustix::process::Resource; +use rlimit::Resource; #[cfg(not(target_os = "openbsd"))] use std::collections::HashMap; #[cfg(target_os = "linux")] @@ -8260,7 +8260,7 @@ fn test_ls_recursive_no_fd_leak() { .ucmd() .arg("-R") .arg("1") - .limit(Resource::Nofile, 20, 20) + .limit(Resource::NOFILE, 20, 20) .succeeds() .no_stderr(); } diff --git a/tests/by-util/test_pr.rs b/tests/by-util/test_pr.rs index e626f0cc55c..d47e7e69b32 100644 --- a/tests/by-util/test_pr.rs +++ b/tests/by-util/test_pr.rs @@ -563,13 +563,13 @@ fn test_large_page_width_does_not_panic() { ignore = "WASI: wasmtime itself needs more memory than the guest's rlimit allows" )] fn test_offset_large_value_does_not_abort_under_memory_limit() { - use rustix::process::Resource; + use rlimit::Resource; use std::process::Stdio; const AS_LIMIT: u64 = 200 * 1024 * 1024; new_ucmd!() - .limit(Resource::As, AS_LIMIT, AS_LIMIT) + .limit(Resource::AS, AS_LIMIT, AS_LIMIT) .set_stdout(Stdio::null()) .args(&["-t", "-o", "999999999"]) .pipe_in("hi\n") diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index 28f5acd2b65..b9490d629e1 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (words) ints (linux) Nofile dfgi abmon avril naab +// spell-checker:ignore (words) ints (linux) NOFILE dfgi abmon avril naab #![allow(clippy::cast_possible_wrap)] @@ -14,6 +14,9 @@ use std::fmt::Write as FmtWrite; use std::process::Command; use std::time::Duration; +#[cfg(target_os = "linux")] +use rlimit::Resource; + use uutests::at_and_ucmd; use uutests::new_ucmd; use uutests::util::TestScenario; @@ -1779,14 +1782,13 @@ fn test_merge_batch_size() { // #[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(target_os = "linux")] fn test_merge_batch_size_with_limit() { - use rustix::process::Resource; // Currently need... // 3 descriptors for stdin, stdout, stderr // 2 descriptors for CTRL+C handling logic (to be reworked at some point) // 2 descriptors for the input files (i.e. batch-size of 2). let limit_fd = 3 + 2 + 2; new_ucmd!() - .limit(Resource::Nofile, limit_fd, limit_fd) + .limit(Resource::NOFILE, limit_fd, limit_fd) .arg("--batch-size=2") .arg("-m") .arg("--unique") @@ -1804,13 +1806,12 @@ fn test_merge_batch_size_with_limit() { // TODO(#7542): Re-enable on Android once we figure out why setting limit is broken. #[cfg(target_os = "linux")] fn test_batch_size_above_fd_limit_is_rejected() { - use rustix::process::Resource; // Only stdin, stdout and stderr are unavailable for merge inputs, so the // largest acceptable --batch-size is the soft limit minus 3, here 27 - 3. let limit_fd = 27; let (at, mut ucmd) = at_and_ucmd!(); at.write("gamma.txt", "delta\nalpha\n"); - ucmd.limit(Resource::Nofile, limit_fd, limit_fd) + ucmd.limit(Resource::NOFILE, limit_fd, limit_fd) .arg("--batch-size=31") .arg("gamma.txt") .fails_with_code(2) @@ -1822,12 +1823,11 @@ fn test_batch_size_above_fd_limit_is_rejected() { #[test] #[cfg(target_os = "linux")] fn test_batch_size_at_fd_limit_is_accepted() { - use rustix::process::Resource; let limit_fd = 27; let (at, mut ucmd) = at_and_ucmd!(); at.write("gamma.txt", "delta\nalpha\n"); // 24 is the largest value the limit above allows, and sorting must still happen. - ucmd.limit(Resource::Nofile, limit_fd, limit_fd) + ucmd.limit(Resource::NOFILE, limit_fd, limit_fd) .arg("--batch-size=24") .arg("gamma.txt") .succeeds() @@ -1837,7 +1837,6 @@ fn test_batch_size_at_fd_limit_is_accepted() { #[test] #[cfg(target_os = "linux")] fn test_merge_more_files_than_fd_limit() { - use rustix::process::Resource; let (at, mut ucmd) = at_and_ucmd!(); // 40 single-line files cannot all be open at once with a soft limit of 24, // so sort has to merge them in several batches through temporary files. @@ -1853,7 +1852,7 @@ fn test_merge_more_files_than_fd_limit() { writeln!(expected, "{i:02}").unwrap(); } let limit_fd = 24; - ucmd.limit(Resource::Nofile, limit_fd, limit_fd) + ucmd.limit(Resource::NOFILE, limit_fd, limit_fd) .arg("-m") .args(&names) .succeeds() @@ -1863,7 +1862,6 @@ fn test_merge_more_files_than_fd_limit() { #[test] #[cfg(target_os = "linux")] fn test_more_files_than_fd_limit() { - use rustix::process::Resource; let (at, mut ucmd) = at_and_ucmd!(); // The inputs are read one after another, so sorting must not need more open // file descriptors than the soft limit allows, no matter how many inputs there are. @@ -1879,7 +1877,7 @@ fn test_more_files_than_fd_limit() { writeln!(expected, "{i:02}").unwrap(); } let limit_fd = 24; - ucmd.limit(Resource::Nofile, limit_fd, limit_fd) + ucmd.limit(Resource::NOFILE, limit_fd, limit_fd) .args(&names) .succeeds() .stdout_only(expected); @@ -1888,7 +1886,6 @@ fn test_more_files_than_fd_limit() { #[test] #[cfg(target_os = "linux")] fn test_temporary_files_with_few_file_descriptors() { - use rustix::process::Resource; let ts = TestScenario::new("sort"); // Each input is larger than what the merge reads ahead, so it stays open. let mut names = Vec::new(); @@ -1907,20 +1904,20 @@ fn test_temporary_files_with_few_file_descriptors() { // Stdin, stdout, stderr, two merge inputs and the merge output. ts.ucmd() - .limit(Resource::Nofile, 6, 6) + .limit(Resource::NOFILE, 6, 6) .arg("-m") .args(&names) .succeeds() .stdout_only(&expected); ts.ucmd() - .limit(Resource::Nofile, 6, 6) + .limit(Resource::NOFILE, 6, 6) .args(&["-S", "64K", "unsorted"]) .succeeds() .stdout_only(&expected); // Starting the compress program can take two more for a moment: on musl and // glibc before 2.24, a failed exec is reported through a pipe. ts.ucmd() - .limit(Resource::Nofile, 10, 10) + .limit(Resource::NOFILE, 10, 10) .args(&["-S", "64K", "--compress-program", "gzip", "unsorted"]) .succeeds() .stdout_only(&expected); diff --git a/tests/by-util/test_split.rs b/tests/by-util/test_split.rs index 0a320ad6ed0..fb39a91b045 100644 --- a/tests/by-util/test_split.rs +++ b/tests/by-util/test_split.rs @@ -3,12 +3,12 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore xzaaa sixhundredfiftyonebytes ninetyonebytes threebytes asciilowercase ghijkl mnopq rstuv wxyz fivelines twohundredfortyonebytes onehundredlines nbbbb dxen ncccc rlimit Nofile +// spell-checker:ignore xzaaa sixhundredfiftyonebytes ninetyonebytes threebytes asciilowercase ghijkl mnopq rstuv wxyz fivelines twohundredfortyonebytes onehundredlines nbbbb dxen ncccc rlimit NOFILE use rand::{RngExt as _, SeedableRng, rng}; use regex::Regex; -#[cfg(any(target_os = "linux", target_os = "android"))] -use rustix::process::Resource; +#[cfg(target_os = "linux")] +use rlimit::Resource; #[cfg(target_os = "linux")] use std::os::unix::ffi::OsStringExt; use std::path::Path; @@ -1749,12 +1749,11 @@ fn test_round_robin() { #[test] // TODO(#7542): Re-enable on Android once we figure out why rlimit is broken. -// #[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(target_os = "linux")] fn test_round_robin_limited_file_descriptors() { new_ucmd!() .args(&["-n", "r/40", "onehundredlines.txt"]) - .limit(Resource::Nofile, 9, 9) + .limit(Resource::NOFILE, 9, 9) .succeeds(); } diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index 00e30eada05..3595e22c8ed 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore nopipe Fsize Nofile sigxfsz +// spell-checker:ignore nopipe FSIZE NOFILE sigxfsz #![allow(clippy::borrow_as_ptr)] @@ -702,7 +702,7 @@ mod linux_only { /// Runs tee with 2 outputs that fail part-way, and checks that the bytes they did /// not take do not end up in the other outputs. fn check_failed_outputs_do_not_spill(open_file_limit: Option) { - use rustix::process::Resource; + use rlimit::Resource; const CAP: u64 = 100 * 1024; let (at, mut ucmd) = at_and_ucmd!(); @@ -713,10 +713,10 @@ mod linux_only { // through tee's 2nd pipe, which stdout and /dev/null keep using after it fails; // "capped2", the last output, through its 1st. ucmd.args(&["capped", "/dev/null", "capped2"]) - .limit(Resource::Fsize, CAP, CAP) + .limit(Resource::FSIZE, CAP, CAP) .ignore_sigxfsz(); if let Some(limit) = open_file_limit { - ucmd.limit(Resource::Nofile, limit, limit); + ucmd.limit(Resource::NOFILE, limit, limit); } let mut child = ucmd .set_stdin(std::fs::File::open(at.plus("in")).unwrap()) diff --git a/tests/uutests/Cargo.toml b/tests/uutests/Cargo.toml index ee810110c32..36ba7a39bc7 100644 --- a/tests/uutests/Cargo.toml +++ b/tests/uutests/Cargo.toml @@ -37,7 +37,8 @@ uucore = { workspace = true, features = [ [target.'cfg(unix)'.dependencies] nix = { workspace = true, features = ["fs", "term"] } -rustix = { workspace = true, features = ["process", "pty", "termios"] } +rlimit = { workspace = true } +rustix = { workspace = true, features = ["pty", "termios"] } [target.'cfg(any(target_os = "freebsd", target_os = "hurd", target_os = "linux", target_os = "android", target_os = "netbsd"))'.dependencies] xattr = { workspace = true } diff --git a/tests/uutests/src/lib/util.rs b/tests/uutests/src/lib/util.rs index dae3df62f34..17caacfb43e 100644 --- a/tests/uutests/src/lib/util.rs +++ b/tests/uutests/src/lib/util.rs @@ -4,7 +4,7 @@ // file that was distributed with this source code. // spell-checker:ignore (linux) rlimit prlimit coreutil ggroups uchild uncaptured scmd SHLVL canonicalized openpty openpt grantpt unlockpt ptsname tcsetwinsize CLOEXEC RDWR SETFD -// spell-checker:ignore (linux) winsize xpixel ypixel setrlimit Fsize SIGBUS SIGSEGV SIGXFSZ EFBIG sigbus tmpfs mksocket +// spell-checker:ignore (linux) winsize xpixel ypixel setrlimit FSIZE SIGBUS SIGSEGV SIGXFSZ EFBIG sigbus tmpfs mksocket // spell-checker:ignore (ToDO) ttyname #![allow(dead_code)] @@ -25,7 +25,7 @@ use nix::sys; use nix::sys::stat::{self, SFlag}; use pretty_assertions::assert_eq; #[cfg(unix)] -use rustix::process::{Resource, Rlimit, setrlimit}; +use rlimit::{Resource, setrlimit}; use std::borrow::Cow; use std::collections::{BTreeMap, VecDeque}; use std::ffi::{OsStr, OsString}; @@ -2093,13 +2093,7 @@ impl UCommand { let limits_copy = self.limits.clone(); let closure = move || -> Result<()> { for &(resource, soft_limit, hard_limit) in &limits_copy { - setrlimit( - resource, - Rlimit { - current: Some(soft_limit), - maximum: Some(hard_limit), - }, - )?; + setrlimit(resource, soft_limit, hard_limit)?; } Ok(()) }; @@ -3786,7 +3780,7 @@ mod tests { let ts = TestScenario::new("util"); ts.cmd("sh") .args(&["-c", "ulimit -Sf; ulimit -Hf"]) - .limit(Resource::Fsize, 8 * unit_size_bytes, 16 * unit_size_bytes) + .limit(Resource::FSIZE, 8 * unit_size_bytes, 16 * unit_size_bytes) .succeeds() .no_stderr() .stdout_is("8\n16\n"); From c415bfc0808b682c0d8292a64484bb66af05de29 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Mon, 28 Sep 2026 16:25:05 +0100 Subject: [PATCH 2/2] refactor(sort): replace rustix::process dependency with rlimit --- Cargo.lock | 1 + fuzz/Cargo.lock | 10 ++++++++++ src/uu/sort/Cargo.toml | 1 + src/uu/sort/src/sort.rs | 40 +++++++--------------------------------- 4 files changed, 19 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbe29f85a92..1275ebc6a11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4069,6 +4069,7 @@ dependencies = [ "memchr", "rand 0.10.3", "rayon", + "rlimit", "rustix", "self_cell", "tempfile", diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index b6cae9a026b..056eda839bc 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -1325,6 +1325,15 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" +[[package]] +name = "rlimit" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f35ee2729c56bb610f6dba436bf78135f728b7373bdffae2ec815b2d3eb98cc3" +dependencies = [ + "libc", +] + [[package]] name = "rustc-hash" version = "2.1.3" @@ -1767,6 +1776,7 @@ dependencies = [ "memchr", "rand", "rayon", + "rlimit", "rustix", "self_cell", "tempfile", diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index d38f9efaf28..42005948226 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -45,6 +45,7 @@ ctrlc = { workspace = true } [target.'cfg(unix)'.dependencies] libc = { workspace = true } rustix = { workspace = true, features = ["fs"] } +rlimit = { workspace = true } [dev-dependencies] divan = { workspace = true } diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 7992959b0b5..1e41c16eaec 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (misc) kKMGTPEZYRQ HFKJFK Mbdfhn getrlimit Nofile rlim bigdecimal extendedbigdecimal hexdigit behaviour keydef GETFD localeconv foldhash +// spell-checker:ignore (misc) kKMGTPEZYRQ HFKJFK Mbdfhn getrlimit NOFILE rlim bigdecimal extendedbigdecimal hexdigit behaviour keydef GETFD localeconv foldhash // spell-checker:ignore (misc) uppercased qsort getmonth juin juil // Although these links don't always seem to describe reality, check out the POSIX and GNU specs: @@ -1521,49 +1521,23 @@ fn make_sort_mode_arg(mode: &'static str, short: char, help: String) -> Arg { .action(ArgAction::SetTrue) } -#[cfg(all( - unix, - not(any( - target_os = "redox", - target_os = "fuchsia", - target_os = "haiku", - target_os = "solaris", - target_os = "illumos" - )) -))] +#[cfg(unix)] fn get_rlimit() -> UResult { - use rustix::process::{Resource, getrlimit}; + use rlimit::{Resource, getrlimit}; - let rlim_cur = getrlimit(Resource::Nofile) - .current - .ok_or_else(|| UUsageError::new(2, translate!("sort-failed-fetch-rlimit")))?; + let (rlim_cur, _) = getrlimit(Resource::NOFILE) + .map_err(|_| UUsageError::new(2, translate!("sort-failed-fetch-rlimit")))?; usize::try_from(rlim_cur) .map_err(|_| UUsageError::new(2, translate!("sort-failed-fetch-rlimit"))) } -#[cfg(all( - unix, - not(any( - target_os = "redox", - target_os = "fuchsia", - target_os = "haiku", - target_os = "solaris", - target_os = "illumos" - )) -))] +#[cfg(unix)] pub(crate) fn fd_soft_limit() -> Option { get_rlimit().ok() } -#[cfg(any( - not(unix), - target_os = "redox", - target_os = "fuchsia", - target_os = "haiku", - target_os = "solaris", - target_os = "illumos" -))] +#[cfg(not(unix))] pub(crate) fn fd_soft_limit() -> Option { None }