Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/uucore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,12 @@ tempfile = { workspace = true }
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
selinux = { workspace = true, optional = true }

[target.'cfg(any(target_vendor = "apple", target_os = "cygwin", target_os = "freebsd", target_os = "linux", target_os = "netbsd"))'.dependencies]
dns-lookup = { workspace = true, optional = true }

[target.'cfg(unix)'.dependencies]
# utmpx is unix-only, so its dependencies must not be pulled into other targets
# (the uptime feature enables utmpx and now builds on windows too).
dns-lookup = { workspace = true, optional = true }
time = { workspace = true, optional = true, features = [
"formatting",
"local-offset",
Expand Down
33 changes: 24 additions & 9 deletions src/uucore/src/lib/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub mod proc_info;
pub mod process;
#[cfg(all(unix, feature = "safe-copy"))]
pub mod safe_copy;
#[cfg(all(unix, not(target_os = "redox")))]
#[cfg(all(unix, not(any(target_os = "hurd", target_os = "redox"))))]
pub mod safe_traversal;
#[cfg(all(target_os = "linux", feature = "tty"))]
pub mod tty;
Expand All @@ -100,21 +100,36 @@ pub mod hardware;
#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))]
pub mod selinux;
#[cfg(all(
any(windows, all(unix, not(target_os = "fuchsia"))),
feature = "signals"
feature = "signals",
any(
windows,
target_vendor = "apple",
target_os = "aix",
target_os = "android",
target_os = "cygwin",
target_os = "freebsd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
target_os = "redox",
target_os = "solaris"
)
))]
pub mod signals;
#[cfg(all(feature = "smack", target_os = "linux"))]
pub mod smack;
#[cfg(feature = "feat_systemd_logind")]
pub mod systemd_logind;
#[cfg(all(
unix,
not(target_os = "android"),
not(target_os = "fuchsia"),
not(target_os = "openbsd"),
not(target_os = "redox"),
feature = "utmpx"
feature = "utmpx",
any(
target_vendor = "apple",
target_os = "cygwin",
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd"
)
))]
pub mod utmpx;
// ** windows-only
Expand Down
17 changes: 9 additions & 8 deletions src/uucore/src/lib/features/process/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@
use libc::{gid_t, pid_t, uid_t};
#[cfg(not(target_os = "redox"))]
use nix::errno::Errno;
#[cfg(not(target_os = "fuchsia"))]
#[cfg(not(any(target_os = "fuchsia", target_os = "haiku")))]
use nix::sys::signal::{self as nix_signal, SigHandler};
use nix::sys::signal::{SigSet, Signal};
use nix::unistd::Pid;
use rustix::process::Signal as RixSignal;
use std::io;
#[cfg(not(target_os = "fuchsia"))]
#[cfg(not(any(target_os = "fuchsia", target_os = "haiku")))]
use std::process::Child;
#[cfg(not(target_os = "fuchsia"))]
#[cfg(not(any(target_os = "fuchsia", target_os = "haiku")))]
use std::time::{Duration, Instant};
#[cfg(not(target_os = "fuchsia"))]
#[cfg(not(any(target_os = "fuchsia", target_os = "haiku")))]
use timer::Timer;

#[cfg(not(target_os = "fuchsia"))]
#[cfg(not(any(target_os = "fuchsia", target_os = "haiku")))]
use super::{ChildExt, TimeoutRet};

/// `geteuid()` returns the effective user ID of the calling process.
Expand Down Expand Up @@ -83,7 +83,7 @@ pub fn getsid(pid: i32) -> Result<pid_t, Errno> {
nix::unistd::getsid(pid).map(Pid::as_raw)
}

#[cfg(not(target_os = "fuchsia"))]
#[cfg(not(any(target_os = "fuchsia", target_os = "haiku")))]
impl ChildExt for Child {
fn send_signal(&mut self, signal: usize) -> io::Result<()> {
let pid = Pid::from_raw(self.id() as pid_t);
Expand Down Expand Up @@ -180,7 +180,7 @@ pub fn unblock_signal(signal: RixSignal) -> io::Result<()> {
/// Ensures there is no overflow on time_t operations. Some BSDs (notably XNU)
/// will return EINVAL otherwise; POSIX only defines it up to 10e8, so we cap
/// it on all targets we do not trust to support the full integer range.
#[cfg(not(target_os = "fuchsia"))]
#[cfg(not(any(target_os = "fuchsia", target_os = "haiku")))]
const MAX_KTIME_T: Duration = if cfg!(target_os = "linux") {
Duration::from_secs(9_223_372_036)
} else {
Expand All @@ -193,6 +193,7 @@ const MAX_KTIME_T: Duration = if cfg!(target_os = "linux") {
#[cfg(not(any(
target_vendor = "apple",
target_os = "fuchsia",
target_os = "haiku",
target_os = "openbsd",
windows
)))]
Expand Down Expand Up @@ -348,7 +349,7 @@ mod timer {
}
}

#[cfg(not(target_os = "fuchsia"))]
#[cfg(not(any(target_os = "fuchsia", target_os = "haiku")))]
impl Timer {
fn timed_sigwait(&mut self, timeout: Duration) -> io::Result<Option<Signal>> {
self.arm(timeout)?;
Expand Down
33 changes: 24 additions & 9 deletions src/uucore/src/lib/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,35 @@ pub use crate::features::pipes;
pub use crate::features::process;
#[cfg(all(unix, feature = "safe-copy"))]
pub use crate::features::safe_copy;
#[cfg(all(unix, not(target_os = "redox")))]
#[cfg(all(unix, not(any(target_os = "hurd", target_os = "redox"))))]
pub use crate::features::safe_traversal;
#[cfg(all(
any(windows, all(unix, not(target_os = "fuchsia"))),
feature = "signals"
feature = "signals",
any(
windows,
target_vendor = "apple",
target_os = "aix",
target_os = "android",
target_os = "cygwin",
target_os = "freebsd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
target_os = "redox",
target_os = "solaris"
)
))]
pub use crate::features::signals;
#[cfg(all(
unix,
not(target_os = "android"),
not(target_os = "fuchsia"),
not(target_os = "openbsd"),
not(target_os = "redox"),
feature = "utmpx"
feature = "utmpx",
any(
target_vendor = "apple",
target_os = "cygwin",
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd"
)
))]
pub use crate::features::utmpx;
// ** windows-only
Expand Down
4 changes: 2 additions & 2 deletions src/uucore_procs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn main(args: TokenStream, stream: TokenStream) -> TokenStream {
// Initialize SIGPIPE state capture at process startup (Unix only).
// This must be at module level to set up the .init_array static that runs
// before main() to capture whether SIGPIPE was ignored by the parent process.
#[cfg(all(#signals, unix, not(target_os = "fuchsia")))]
#[cfg(all(#signals, unix, not(any(target_os = "fuchsia", target_os = "hurd"))))]
uucore::init_startup_state_capture!();

pub fn uumain(args: impl uucore::Args) -> i32 {
Expand All @@ -42,7 +42,7 @@ pub fn main(args: TokenStream, stream: TokenStream) -> TokenStream {
// The Rust runtime ignores SIGPIPE, but we need to respect the parent's
// signal disposition for proper pipeline behavior (GNU compatibility).
// needed even for true --version
#[cfg(all(unix, not(target_os = "fuchsia")))]
#[cfg(all(unix, not(any(target_os = "fuchsia", target_os = "hurd"))))]
if !uucore::signals::sigpipe_was_ignored() {
let _ = uucore::signals::enable_pipe_errors();
}
Expand Down
12 changes: 6 additions & 6 deletions tests/uutests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ all-features = true
[lib]
path = "src/lib/lib.rs"

[dependencies]
[target.'cfg(not(target_os = "aix"))'.dependencies]
ctor = { workspace = true }
libc = { workspace = true }
pretty_assertions = { workspace = true }
Expand All @@ -33,14 +33,14 @@ uucore = { workspace = true, features = [
"utmpx",
] }

[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]

[target.'cfg(unix)'.dependencies]
nix = { workspace = true, features = ["process", "signal", "term", "user"] }
[target.'cfg(all(unix, not(any(target_os = "aix", target_os = "fuchsia"))))'.dependencies]
rlimit = { workspace = true }

[target.'cfg(all(unix, not(any(target_vendor = "apple", target_os = "openbsd"))))'.dependencies]
[target.'cfg(all(unix, not(any(target_vendor = "apple", target_os = "aix", target_os = "openbsd"))))'.dependencies]
xattr = { workspace = true }

[target.'cfg(all(unix, not(target_os = "aix")))'.dependencies]
nix = { workspace = true, features = ["process", "signal", "term", "user"] }

[lints]
workspace = true
3 changes: 3 additions & 0 deletions tests/uutests/src/lib/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

#![cfg(not(target_os = "aix"))]

#[macro_use]
pub mod macros;
pub mod random;
Expand Down
41 changes: 24 additions & 17 deletions tests/uutests/src/lib/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
use core::str;
#[cfg(unix)]
use libc::mode_t;
#[cfg(unix)]
#[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::setrlimit;
use std::borrow::Cow;
use std::collections::VecDeque;
Expand Down Expand Up @@ -340,8 +340,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
#[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;
Expand Down Expand Up @@ -1197,7 +1200,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;
Expand All @@ -1215,13 +1218,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))
Expand All @@ -1239,6 +1242,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",
Expand All @@ -1251,6 +1255,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);
Expand All @@ -1261,6 +1266,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",
Expand All @@ -1273,6 +1279,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);
Expand Down Expand Up @@ -1376,7 +1383,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();
Expand Down Expand Up @@ -1535,7 +1542,7 @@ pub struct UCommand {
stdout: Option<Stdio>,
stderr: Option<Stdio>,
bytes_into_stdin: Option<Vec<u8>>,
#[cfg(unix)]
#[cfg(all(unix, not(target_os = "fuchsia")))]
limits: Vec<(rlimit::Resource, u64, u64)>,
stderr_to_stdout: bool,
timeout: Option<Duration>,
Expand Down Expand Up @@ -1698,7 +1705,7 @@ impl UCommand {
self
}

#[cfg(unix)]
#[cfg(all(unix, not(target_os = "fuchsia")))]
pub fn limit(
&mut self,
resource: rlimit::Resource,
Expand Down Expand Up @@ -1956,9 +1963,9 @@ impl UCommand {

let mut captured_stdout = None;
let mut captured_stderr = None;
#[cfg(unix)]
#[cfg(all(unix, not(any(target_os = "fuchsia", target_os = "redox"))))]
let mut stdin_pty: Option<File> = None;
#[cfg(not(unix))]
#[cfg(not(all(unix, not(any(target_os = "fuchsia", target_os = "redox")))))]
let stdin_pty: Option<File> = None;
if self.stderr_to_stdout {
let mut output = CapturedOutput::default();
Expand Down Expand Up @@ -1993,7 +2000,7 @@ impl UCommand {
.stderr(stderr);
}

#[cfg(unix)]
#[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,
Expand Down Expand Up @@ -2038,7 +2045,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.
Expand Down Expand Up @@ -2994,7 +3001,7 @@ pub fn whoami() -> String {
/// - path: The filesystem path to the PTY replica device
/// - controller: The controller file
/// - replica: The replica file
#[cfg(unix)]
#[cfg(all(unix, not(any(target_os = "fuchsia", target_os = "redox"))))]
pub fn pty_path() -> (String, File, File) {
use nix::pty::openpty;
use nix::unistd::ttyname;
Expand Down Expand Up @@ -3646,7 +3653,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") {
Expand Down
Loading