From 43e72a0656a00ada315452ab3885b33028862637 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 8d0655551e2..9dcca7e3f4e 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 9edb70b98ba..8de747e34cd 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" @@ -394,6 +395,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 96cf173c0ff..7c088f246cd 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 #[cfg(unix)] @@ -3604,7 +3604,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"); @@ -3624,7 +3624,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(); } @@ -3634,7 +3634,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; @@ -3644,7 +3644,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 857a7ea25c3..a194d8260c1 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 uutests::at_and_ucmd; use uutests::new_ucmd; @@ -2539,14 +2539,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(); @@ -2562,7 +2562,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; @@ -2570,7 +2570,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 49d19bbe90e..5e702ba0cfa 100644 --- a/tests/by-util/test_expand.rs +++ b/tests/by-util/test_expand.rs @@ -276,12 +276,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 23833bfc1d4..42ee308bbdf 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")] @@ -8197,7 +8197,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 7099c2bcf3d..ad29cc5733e 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)] @@ -13,6 +13,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; @@ -1846,14 +1849,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") @@ -1871,13 +1873,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) @@ -1889,12 +1890,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() @@ -1904,7 +1904,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. @@ -1920,7 +1919,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() @@ -1930,7 +1929,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. @@ -1946,7 +1944,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); @@ -1955,7 +1953,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(); @@ -1974,20 +1971,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 29a6a7dad50..dc33b6f5b39 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; @@ -1731,12 +1731,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 f8a0e4bb0ba277a910284eed022a0d9a0cd12e6d 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 9dcca7e3f4e..93eb64fc45b 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 4a8505509e1..214a22428f3 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: @@ -1518,49 +1518,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 }