From ae1f446473524510e1edd8b60c7a474f6f2b7a00 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Wed, 14 Oct 2026 23:25:07 +0100 Subject: [PATCH 1/3] fixup! uutests: open simulated terminals close-on-exec --- tests/uutests/src/lib/util.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/tests/uutests/src/lib/util.rs b/tests/uutests/src/lib/util.rs index dae3df62f34..c2c7339db39 100644 --- a/tests/uutests/src/lib/util.rs +++ b/tests/uutests/src/lib/util.rs @@ -3058,12 +3058,7 @@ pub fn whoami() -> String { /// other tests in the meantime don't inherit them. #[cfg(all(unix, not(target_os = "redox")))] fn open_pty(size: Option<&libc::winsize>) -> OpenptyResult { - #[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "netbsd" - ))] + #[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd"))] { use rustix::fs::{Mode, OFlags, open}; use rustix::pty::{OpenptFlags, grantpt, openpt, ptsname, unlockpt}; @@ -3094,12 +3089,7 @@ fn open_pty(size: Option<&libc::winsize>) -> OpenptyResult { // Elsewhere a PTY can't be opened close-on-exec, so a command started // between openpty and fcntl can still inherit it. - #[cfg(not(any( - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "netbsd" - )))] + #[cfg(not(any(target_os = "linux", target_os = "android", target_os = "freebsd")))] { use nix::fcntl::{FcntlArg, FdFlag, fcntl}; From 13017cddeb1a015e168918a29a3c564006905613 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/3] refactor(uutests): replace rustix::process with rlimit depenedency --- Cargo.lock | 11 +++++++++++ Cargo.toml | 2 ++ tests/by-util/test_cat.rs | 6 +++--- tests/by-util/test_cp.rs | 6 +++--- 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 | 6 +++--- tests/by-util/test_tee.rs | 8 ++++---- tests/uutests/Cargo.toml | 3 ++- tests/uutests/src/lib/util.rs | 14 ++++---------- 13 files changed, 56 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f6c59ca9a87..1a3b3a81326 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" @@ -4489,6 +4499,7 @@ dependencies = [ "pretty_assertions", "rand 0.10.3", "regex", + "rlimit", "rustix", "tempfile", "uucore", diff --git a/Cargo.toml b/Cargo.toml index 2516e91ea15..bc3417cb739 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.27.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..f4b8ff1356d 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; +use rlimit::Resource; #[cfg(unix)] use std::fs::File; use std::fs::OpenOptions; @@ -135,7 +135,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 d4675689717..ace2eaa54c5 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 clob btrfs neve ROOTDIR USERDIR outfile subvolume uufs xattrs ELOOP +// spell-checker:ignore (flags) reflink (fs) tmpfs (linux) filefrag rlimit Rlim NOFILE 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)] @@ -3448,7 +3448,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"); @@ -3468,7 +3468,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(); } diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index f47bf4ffc3c..8be88d5f51b 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; @@ -2508,14 +2508,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(); @@ -2531,7 +2531,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; @@ -2539,7 +2539,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 775c4797ec9..9133f9066fe 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 +// spell-checker:ignore (words) ints (linux) NOFILE dfgi abmon avril #![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; @@ -1822,14 +1825,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") @@ -1847,13 +1849,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) @@ -1865,12 +1866,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() @@ -1880,7 +1880,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. @@ -1896,7 +1895,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() @@ -1906,7 +1905,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. @@ -1922,7 +1920,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); @@ -1931,7 +1929,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(); @@ -1950,20 +1947,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..8b299c49a5c 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; +use rlimit::Resource; #[cfg(target_os = "linux")] use std::os::unix::ffi::OsStringExt; use std::path::Path; @@ -1736,7 +1736,7 @@ fn test_round_robin() { 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 c2c7339db39..f4fc36548a2 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(()) }; @@ -3776,7 +3770,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 f80ae6344828b131f86aa3606aff8f3b466860cd Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Sat, 29 Aug 2026 22:24:19 +0100 Subject: [PATCH 3/3] uutests: gate by target support ```sh RUSTC_BOOTSTRAP=1 cargo clippy -q -Zbuild-std=std,panic_abort -p uutests --all-features --target=powerpc64-ibm-aix --target=x86_64-linux-android --target=x86_64-pc-cygwin --target=aarch64-apple-darwin --target=x86_64-unknown-freebsd --target=x86_64-unknown-haiku --target=x86_64-unknown-hermit --target=x86_64-unknown-hurd-gnu --target=aarch64-unknown-illumos --target=x86_64-unknown-linux-gnu --target=i686-unknown-netbsd --target=x86_64-unknown-openbsd --target=x86_64-unknown-redox --target=x86_64-pc-solaris --target=wasm32-wasip1 --target=x86_64-pc-windows-gnu ``` --- Cargo.toml | 4 +++- tests/uutests/Cargo.toml | 12 ++++++---- tests/uutests/src/lib/lib.rs | 2 ++ tests/uutests/src/lib/util.rs | 43 ++++++++++++++++++++--------------- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bc3417cb739..aaa8e98c81c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -395,9 +395,11 @@ 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"] } +[target.'cfg(all(unix, not(target_os = "fuchsia")))'.dev-dependencies] +rlimit = { workspace = true } + [build-dependencies] phf_codegen.workspace = true diff --git a/tests/uutests/Cargo.toml b/tests/uutests/Cargo.toml index 36ba7a39bc7..d4b6f5c8052 100644 --- a/tests/uutests/Cargo.toml +++ b/tests/uutests/Cargo.toml @@ -18,8 +18,7 @@ all-features = true [lib] path = "src/lib/lib.rs" -[dependencies] -ctor = { workspace = true } +[target.'cfg(not(any(target_os = "aix", target_os = "horizon")))'.dependencies] libc = { workspace = true } pretty_assertions = { workspace = true } rand = { workspace = true } @@ -35,13 +34,18 @@ uucore = { workspace = true, features = [ [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] -[target.'cfg(unix)'.dependencies] -nix = { workspace = true, features = ["fs", "term"] } +[target.'cfg(all(unix, not(any(target_os = "aix", target_os = "fuchsia", target_os = "horizon"))))'.dependencies] rlimit = { workspace = true } + +[target.'cfg(all(unix, not(any(target_os = "aix", target_os = "horizon"))))'.dependencies] +nix = { workspace = true, features = ["fs", "term"] } 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 } +[target.'cfg(not(any(target_os = "aix", target_os = "horizon")))'.dev-dependencies] +ctor = { workspace = true } + [lints] workspace = true diff --git a/tests/uutests/src/lib/lib.rs b/tests/uutests/src/lib/lib.rs index afd8f1a3939..91777f33fdf 100644 --- a/tests/uutests/src/lib/lib.rs +++ b/tests/uutests/src/lib/lib.rs @@ -3,6 +3,8 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. +#![cfg(not(any(target_os = "aix", target_os = "horizon")))] + #[macro_use] pub mod macros; pub mod random; diff --git a/tests/uutests/src/lib/util.rs b/tests/uutests/src/lib/util.rs index f4fc36548a2..ce109b4484c 100644 --- a/tests/uutests/src/lib/util.rs +++ b/tests/uutests/src/lib/util.rs @@ -17,14 +17,14 @@ use core::str; #[cfg(unix)] use libc::mode_t; -#[cfg(all(unix, not(target_os = "redox")))] +#[cfg(all(unix, not(any(target_os = "fuchsia", target_os = "redox"))))] use nix::pty::OpenptyResult; #[cfg(unix)] use nix::sys; -#[cfg(not(windows))] +#[cfg(unix)] use nix::sys::stat::{self, SFlag}; use pretty_assertions::assert_eq; -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "fuchsia")))] use rlimit::{Resource, setrlimit}; use std::borrow::Cow; use std::collections::{BTreeMap, VecDeque}; @@ -353,8 +353,11 @@ impl CmdResult { /// /// # Platform specific behavior /// - /// This assertion method is only available on unix systems, except for fuchsia. - #[cfg(all(unix, not(target_os = "fuchsia")))] + /// This assertion method is only available on unix systems, except for fuchsia, haiku and hurd. + #[cfg(all( + unix, + not(any(target_os = "fuchsia", target_os = "haiku", target_os = "hurd")) + ))] #[track_caller] pub fn signal_name_is(&self, name: &str) -> &Self { use uucore::signals::signal_by_name_or_value; @@ -1216,7 +1219,7 @@ impl AtPath { File::create(self.plus(file)).unwrap(); } - #[cfg(not(windows))] + #[cfg(unix)] pub fn mkfifo(&self, fifo: &str) { // rustix::fs::mkfifoat is linux only use nix::sys::stat::Mode; @@ -1234,13 +1237,13 @@ impl AtPath { UnixListener::bind(full_path).expect("Socket file creation failed."); } - #[cfg(not(windows))] + #[cfg(unix)] pub fn is_fifo(&self, fifo: &str) -> bool { stat::stat(&self.plus(fifo)) .is_ok_and(|s| SFlag::from_bits_truncate(s.st_mode).contains(SFlag::S_IFIFO)) } - #[cfg(not(windows))] + #[cfg(unix)] pub fn is_char_device(&self, char_dev: &str) -> bool { stat::stat(&self.plus(char_dev)) .is_ok_and(|s| SFlag::from_bits_truncate(s.st_mode).contains(SFlag::S_IFCHR)) @@ -1258,6 +1261,7 @@ impl AtPath { hard_link(self.plus(original), self.plus(link)).unwrap(); } + #[cfg(any(unix, windows))] pub fn symlink_file(&self, original: &str, link: &str) { log_info( "symlink", @@ -1270,6 +1274,7 @@ impl AtPath { symlink_file(self.plus(original), self.plus(link)).unwrap(); } + #[cfg(any(unix, windows))] pub fn relative_symlink_file(&self, original: &str, link: &str) { #[cfg(windows)] let original = original.replace('/', MAIN_SEPARATOR_STR); @@ -1280,6 +1285,7 @@ impl AtPath { symlink_file(original, self.plus(link)).unwrap(); } + #[cfg(any(unix, windows))] pub fn symlink_dir(&self, original: &str, link: &str) { log_info( "symlink", @@ -1292,6 +1298,7 @@ impl AtPath { symlink_dir(self.plus(original), self.plus(link)).unwrap(); } + #[cfg(any(unix, windows))] pub fn relative_symlink_dir(&self, original: &str, link: &str) { #[cfg(windows)] let original = original.replace('/', MAIN_SEPARATOR_STR); @@ -1403,7 +1410,7 @@ impl AtPath { /// /// This function panics if there is an error loading the metadata /// or setting the permissions of the file. - #[cfg(not(windows))] + #[cfg(unix)] pub fn set_mode(&self, filename: &str, mode: u32) { let path = self.plus(filename); let mut perms = fs::metadata(&path).unwrap().permissions(); @@ -1562,7 +1569,7 @@ pub struct UCommand { stdout: Option, stderr: Option, bytes_into_stdin: Option>, - #[cfg(unix)] + #[cfg(all(unix, not(target_os = "fuchsia")))] limits: Vec<(Resource, u64, u64)>, #[cfg(unix)] ignore_sigxfsz: bool, @@ -1727,7 +1734,7 @@ impl UCommand { self } - #[cfg(unix)] + #[cfg(all(unix, not(target_os = "fuchsia")))] pub fn limit(&mut self, resource: Resource, soft_limit: u64, hard_limit: u64) -> &mut Self { self.limits.push((resource, soft_limit, hard_limit)); self @@ -2000,9 +2007,9 @@ impl UCommand { let mut captured_stdout = None; let mut captured_stderr = None; - #[cfg(all(unix, not(target_os = "redox")))] + #[cfg(all(unix, not(any(target_os = "fuchsia", target_os = "redox"))))] let mut stdin_pty: Option = None; - #[cfg(not(all(unix, not(target_os = "redox"))))] + #[cfg(not(all(unix, not(any(target_os = "fuchsia", target_os = "redox")))))] let stdin_pty: Option = None; if self.stderr_to_stdout { let mut output = CapturedOutput::default(); @@ -2037,7 +2044,7 @@ impl UCommand { .stderr(stderr); } - #[cfg(all(unix, not(target_os = "redox")))] + #[cfg(all(unix, not(any(target_os = "fuchsia", target_os = "redox"))))] if let Some(simulated_terminal) = &self.terminal_simulation { let terminal_size = simulated_terminal.size.unwrap_or(libc::winsize { ws_col: 80, @@ -2086,7 +2093,7 @@ impl UCommand { } } - #[cfg(unix)] + #[cfg(all(unix, not(target_os = "fuchsia")))] if !self.limits.is_empty() { // just to be safe: move a copy of the limits list into the closure. // this way the closure is fully self-contained. @@ -3050,7 +3057,7 @@ pub fn whoami() -> String { /// Open a PTY whose two ends are close-on-exec, so that commands started by /// other tests in the meantime don't inherit them. -#[cfg(all(unix, not(target_os = "redox")))] +#[cfg(all(unix, not(any(target_os = "fuchsia", target_os = "redox"))))] fn open_pty(size: Option<&libc::winsize>) -> OpenptyResult { #[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd"))] { @@ -3101,7 +3108,7 @@ fn open_pty(size: Option<&libc::winsize>) -> OpenptyResult { /// - path: The filesystem path to the PTY replica device /// - controller: The controller file /// - replica: The replica file -#[cfg(all(unix, not(target_os = "redox")))] +#[cfg(all(unix, not(any(target_os = "fuchsia", target_os = "redox"))))] pub fn pty_path() -> (String, File, File) { use nix::unistd::ttyname; let pty = open_pty(None); @@ -3758,7 +3765,7 @@ mod tests { .stdout_is("unlimited\nunlimited\n"); } - #[cfg(unix)] + #[cfg(all(unix, not(target_os = "fuchsia")))] #[test] fn test_application_of_process_resource_limits_limited_file_size() { let unit_size_bytes = if cfg!(target_vendor = "apple") {