From f989cb7d824163f3ddfcb59396dfe03b8653c0a7 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Thu, 22 Oct 2026 17:39:10 +0100 Subject: [PATCH 1/3] build: use shared bsd cfg alias --- Cargo.lock | 1 + Cargo.toml | 1 + build.rs | 5 +++ cfg_aliases.rs | 16 ++++++++ src/uu/stty/build.rs | 13 ++----- tests/by-util/test_sort.rs | 80 +++++--------------------------------- tests/by-util/test_stty.rs | 48 +++-------------------- 7 files changed, 42 insertions(+), 122 deletions(-) create mode 100644 cfg_aliases.rs diff --git a/Cargo.lock b/Cargo.lock index bf434e39514..bd1c75d9235 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -505,6 +505,7 @@ name = "coreutils" version = "0.13.0" dependencies = [ "bytecount", + "cfg_aliases", "clap", "clap_complete", "clap_mangen", diff --git a/Cargo.toml b/Cargo.toml index 24b4c700b6e..d198226a396 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -398,6 +398,7 @@ nix = { workspace = true, features = ["fs", "signal"] } rustix = { workspace = true, features = ["net", "process"] } [build-dependencies] +cfg_aliases.workspace = true phf_codegen.workspace = true [features] diff --git a/build.rs b/build.rs index 923b2f44d1a..794eaeae992 100644 --- a/build.rs +++ b/build.rs @@ -10,11 +10,16 @@ use std::fs::File; use std::io::Write; use std::path::Path; +#[path = "cfg_aliases.rs"] +mod cfg_aliases; + pub fn main() { const ENV_FEATURE_PREFIX: &str = "CARGO_FEATURE_"; const FEATURE_PREFIX: &str = "feat_"; const OVERRIDE_PREFIX: &str = "uu_"; + cfg_aliases::register(); + // Do not rebuild build script unless the script itself or the enabled features are modified // See println!("cargo:rerun-if-changed=build.rs"); diff --git a/cfg_aliases.rs b/cfg_aliases.rs new file mode 100644 index 00000000000..6ca2abbe9ef --- /dev/null +++ b/cfg_aliases.rs @@ -0,0 +1,16 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +pub fn register() { + cfg_aliases::cfg_aliases! { + bsd: { any( + target_vendor = "apple", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd", + target_os = "openbsd" + ) }, + } +} diff --git a/src/uu/stty/build.rs b/src/uu/stty/build.rs index 320a109d007..1eb27b004b4 100644 --- a/src/uu/stty/build.rs +++ b/src/uu/stty/build.rs @@ -3,16 +3,9 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -use cfg_aliases::cfg_aliases; +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; fn main() { - cfg_aliases! { - bsd: { any( - target_vendor = "apple", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "netbsd", - target_os = "openbsd" - ) }, - }; + cfg_aliases::register(); } diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index 4bd8de32e0e..53be3178c68 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -705,13 +705,7 @@ fn test_month_default2() { /// Query the system for abbreviated month names via `locale abmon`. /// Returns a vector of 12 month abbreviations in order (Jan..Dec), /// or None if the command fails or returns unexpected output. -#[cfg(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" -))] +#[cfg(bsd)] fn get_system_abmon(locale: &str) -> Option> { let output = Command::new("locale") .env("LC_ALL", locale) @@ -734,13 +728,7 @@ fn get_system_abmon(locale: &str) -> Option> { } /// Build shuffled input and sorted expected output from month names. -#[cfg(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" -))] +#[cfg(bsd)] fn month_sort_input_expected(months: &[String]) -> (String, String) { // Shuffled order: May, Dec, Jan, Jun, Feb, Mar, Apr, Jul, Aug, Sep, Oct, Nov let shuffle_order = [4, 11, 0, 5, 1, 2, 3, 6, 7, 8, 9, 10]; @@ -764,26 +752,14 @@ fn test_month_sort_french_locale() { // spell-checker:disable // On BSD-like, abbreviated month names vary across OS versions (different CLDR data), // so we query the system dynamically. On other platforms, glibc values are stable. - #[cfg(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - ))] + #[cfg(bsd)] let (input, expected) = { let Some(months) = get_system_abmon(locale) else { return; }; month_sort_input_expected(&months) }; - #[cfg(not(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - )))] + #[cfg(not(bsd))] let (input, expected) = ( "mai\ndéc.\njanv.\njuin\nfévr.\nmars\navril\njuil.\naoût\nsept.\noct.\nnov.\n".to_string(), "janv.\nfévr.\nmars\navril\nmai\njuin\njuil.\naoût\nsept.\noct.\nnov.\ndéc.\n".to_string(), @@ -805,26 +781,14 @@ fn test_month_sort_hungarian_locale() { return; } // spell-checker:disable - #[cfg(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - ))] + #[cfg(bsd)] let (input, expected) = { let Some(months) = get_system_abmon(locale) else { return; }; month_sort_input_expected(&months) }; - #[cfg(not(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - )))] + #[cfg(not(bsd))] let (input, expected) = ( "máj\ndec\njan\njún\nfebr\nmárc\nápr\njúl\naug\nszept\nokt\nnov\n".to_string(), "jan\nfebr\nmárc\nápr\nmáj\njún\njúl\naug\nszept\nokt\nnov\ndec\n".to_string(), @@ -851,26 +815,14 @@ fn test_month_sort_french_embedded_blanks() { // Pick three locale months (indices 2=March, 3=April, 5=June) and verify // that inserting blanks into April's name causes a non-match. // On glibc these are "mars", "avril", "juin"; on other systems they vary. - #[cfg(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - ))] + #[cfg(bsd)] let months = { let Some(m) = get_system_abmon(locale) else { return; }; m }; - #[cfg(not(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - )))] + #[cfg(not(bsd))] let months = vec![ "janv.", "févr.", "mars", "avril", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc.", @@ -912,13 +864,7 @@ fn test_month_sort_japanese_locale() { return; } // On BSD-like, abbreviated month names may differ, so query dynamically. - #[cfg(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - ))] + #[cfg(bsd)] let (input, expected) = { let Some(months) = get_system_abmon(locale) else { return; @@ -926,13 +872,7 @@ fn test_month_sort_japanese_locale() { month_sort_input_expected(&months) }; // Japanese abbreviated months are numeric (1月..12月) on glibc - #[cfg(not(any( - target_vendor = "apple", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - )))] + #[cfg(not(bsd))] let (input, expected) = ( "5月\n12月\n1月\n6月\n2月\n3月\n4月\n7月\n8月\n9月\n10月\n11月\n".to_string(), "1月\n2月\n3月\n4月\n5月\n6月\n7月\n8月\n9月\n10月\n11月\n12月\n".to_string(), diff --git a/tests/by-util/test_stty.rs b/tests/by-util/test_stty.rs index 2161074d9b6..1b106bb6f58 100644 --- a/tests/by-util/test_stty.rs +++ b/tests/by-util/test_stty.rs @@ -153,13 +153,7 @@ fn invalid_setting() { #[test] fn invalid_baud_setting() { - #[cfg(not(any( - target_vendor = "apple", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "netbsd", - target_os = "openbsd" - )))] + #[cfg(not(bsd))] new_ucmd!() .args(&["100"]) .fails() @@ -180,25 +174,13 @@ fn invalid_baud_setting() { .fails() .stderr_contains("missing argument to 'ospeed'"); - #[cfg(not(any( - target_vendor = "apple", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "netbsd", - target_os = "openbsd" - )))] + #[cfg(not(bsd))] new_ucmd!() .args(&["ispeed", "995"]) .fails() .stderr_contains("invalid ispeed '995'"); - #[cfg(not(any( - target_vendor = "apple", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "netbsd", - target_os = "openbsd" - )))] + #[cfg(not(bsd))] new_ucmd!() .args(&["ospeed", "995"]) .fails() @@ -471,13 +453,7 @@ fn grouped_flag_removal() { #[ignore = "Fails because cargo test does not run in a tty"] fn baud_rate_validation() { // Test various baud rate formats - #[cfg(any( - target_vendor = "apple", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "netbsd", - target_os = "openbsd" - ))] + #[cfg(bsd)] { // BSD accepts numeric baud rates new_ucmd!().args(&["9600"]).fails(); // Fails due to no TTY, but validates parsing @@ -1473,13 +1449,7 @@ fn invalid_baud_rate() { // On non-BSD systems, test invalid numeric baud rate // On BSD systems, any u32 is accepted, so we skip this test - #[cfg(not(any( - target_vendor = "apple", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "netbsd", - target_os = "openbsd" - )))] + #[cfg(not(bsd))] { new_ucmd!() .args(&["ospeed", "999999999"]) @@ -1632,13 +1602,7 @@ fn test_ispeed_ospeed_valid_speeds() { } #[test] -#[cfg(not(any( - target_vendor = "apple", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "netbsd", - target_os = "openbsd" -)))] +#[cfg(not(bsd))] #[ignore = "Issue: #9547"] fn test_ispeed_ospeed_invalid_speeds() { let (path, _controller, _replica) = pty_path(); From faf1a6e2c2f39c1fb9a73f119213aa3a70c2ba08 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Sat, 31 Oct 2026 11:41:43 +0000 Subject: [PATCH 2/3] build: use shared `selinux` and `smack` cfg aliases --- .vscode/settings.json | 3 ++- Cargo.lock | 9 +++++++ cfg_aliases.rs | 2 ++ src/uu/cp/Cargo.toml | 3 +++ src/uu/cp/build.rs | 11 +++++++++ src/uu/cp/src/copydir.rs | 6 ++--- src/uu/cp/src/cp.rs | 16 ++++++------- src/uu/id/Cargo.toml | 3 +++ src/uu/id/build.rs | 11 +++++++++ src/uu/id/src/id.rs | 27 ++++++++------------- src/uu/install/Cargo.toml | 3 +++ src/uu/install/build.rs | 11 +++++++++ src/uu/install/src/install.rs | 43 ++++++++++++++++------------------ src/uu/ls/Cargo.toml | 3 +++ src/uu/ls/build.rs | 11 +++++++++ src/uu/ls/src/config.rs | 8 +++---- src/uu/ls/src/ls.rs | 4 ++-- src/uu/mkdir/Cargo.toml | 3 +++ src/uu/mkdir/build.rs | 11 +++++++++ src/uu/mkdir/src/mkdir.rs | 4 ++-- src/uu/mkfifo/Cargo.toml | 3 +++ src/uu/mkfifo/build.rs | 11 +++++++++ src/uu/mkfifo/src/mkfifo.rs | 4 ++-- src/uu/mknod/Cargo.toml | 3 +++ src/uu/mknod/build.rs | 11 +++++++++ src/uu/mknod/src/mknod.rs | 23 ++++++------------ src/uu/mv/Cargo.toml | 3 +++ src/uu/mv/build.rs | 11 +++++++++ src/uu/mv/src/mv.rs | 4 ++-- src/uu/stat/Cargo.toml | 3 +++ src/uu/stat/build.rs | 11 +++++++++ src/uu/stat/src/stat.rs | 16 ++++--------- src/uucore/build.rs | 21 ++++------------- src/uucore/src/lib/features.rs | 4 ++-- src/uucore/src/lib/lib.rs | 4 ++-- tests/by-util/test_chcon.rs | 2 +- tests/by-util/test_cp.rs | 28 +++++++++++----------- tests/by-util/test_id.rs | 2 +- tests/by-util/test_install.rs | 8 +++---- tests/by-util/test_ls.rs | 14 +++++------ tests/by-util/test_mkdir.rs | 6 ++--- tests/by-util/test_mkfifo.rs | 6 ++--- tests/by-util/test_mknod.rs | 8 +++---- tests/by-util/test_mv.rs | 4 ++-- tests/by-util/test_runcon.rs | 6 ++--- tests/by-util/test_stat.rs | 2 +- 46 files changed, 254 insertions(+), 156 deletions(-) create mode 100644 src/uu/cp/build.rs create mode 100644 src/uu/id/build.rs create mode 100644 src/uu/install/build.rs create mode 100644 src/uu/ls/build.rs create mode 100644 src/uu/mkdir/build.rs create mode 100644 src/uu/mkfifo/build.rs create mode 100644 src/uu/mknod/build.rs create mode 100644 src/uu/mv/build.rs create mode 100644 src/uu/stat/build.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 9667242395d..8c97fe720fd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,6 @@ "cSpell.import": [ "./.vscode/cSpell.json" ], - "rust-analyzer.check.command": "clippy" + "rust-analyzer.check.command": "clippy", + "rust-analyzer.vfs.extraIncludes": ["${workspaceFolder}/cfg_aliases.rs"] } diff --git a/Cargo.lock b/Cargo.lock index bd1c75d9235..074693f55c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3305,6 +3305,7 @@ dependencies = [ name = "uu_cp" version = "0.13.0" dependencies = [ + "cfg_aliases", "clap", "codspeed-divan-compat", "filetime", @@ -3579,6 +3580,7 @@ dependencies = [ name = "uu_id" version = "0.13.0" dependencies = [ + "cfg_aliases", "clap", "fluent", "rustix", @@ -3590,6 +3592,7 @@ dependencies = [ name = "uu_install" version = "0.13.0" dependencies = [ + "cfg_aliases", "clap", "fluent", "rustix", @@ -3658,6 +3661,7 @@ name = "uu_ls" version = "0.13.0" dependencies = [ "ansi-width", + "cfg_aliases", "clap", "codspeed-divan-compat", "fluent", @@ -3687,6 +3691,7 @@ dependencies = [ name = "uu_mkdir" version = "0.13.0" dependencies = [ + "cfg_aliases", "clap", "fluent", "uucore", @@ -3696,6 +3701,7 @@ dependencies = [ name = "uu_mkfifo" version = "0.13.0" dependencies = [ + "cfg_aliases", "clap", "fluent", "libc", @@ -3707,6 +3713,7 @@ dependencies = [ name = "uu_mknod" version = "0.13.0" dependencies = [ + "cfg_aliases", "clap", "fluent", "nix", @@ -3740,6 +3747,7 @@ dependencies = [ name = "uu_mv" version = "0.13.0" dependencies = [ + "cfg_aliases", "clap", "codspeed-divan-compat", "fluent", @@ -4103,6 +4111,7 @@ dependencies = [ name = "uu_stat" version = "0.13.0" dependencies = [ + "cfg_aliases", "clap", "fluent", "rustix", diff --git a/cfg_aliases.rs b/cfg_aliases.rs index 6ca2abbe9ef..64c1cc6f4ca 100644 --- a/cfg_aliases.rs +++ b/cfg_aliases.rs @@ -12,5 +12,7 @@ pub fn register() { target_os = "netbsd", target_os = "openbsd" ) }, + selinux: { all(feature = "selinux", any(target_os = "android", target_os = "linux")) }, + smack: { all(feature = "smack", target_os = "linux") }, } } diff --git a/src/uu/cp/Cargo.toml b/src/uu/cp/Cargo.toml index 43666874ca9..c9ad5305d66 100644 --- a/src/uu/cp/Cargo.toml +++ b/src/uu/cp/Cargo.toml @@ -62,6 +62,9 @@ divan = { workspace = true } tempfile = { workspace = true } uucore = { workspace = true, features = ["benchmark"] } +[build-dependencies] +cfg_aliases = { workspace = true } + [[bench]] name = "cp_bench" harness = false diff --git a/src/uu/cp/build.rs b/src/uu/cp/build.rs new file mode 100644 index 00000000000..c93ccb84575 --- /dev/null +++ b/src/uu/cp/build.rs @@ -0,0 +1,11 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; + +pub fn main() { + cfg_aliases::register(); +} diff --git a/src/uu/cp/src/copydir.rs b/src/uu/cp/src/copydir.rs index 0a0f12e6d51..fe1cac52b5a 100644 --- a/src/uu/cp/src/copydir.rs +++ b/src/uu/cp/src/copydir.rs @@ -28,7 +28,7 @@ use uucore::show; use uucore::translate; use walkdir::{DirEntry, WalkDir}; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use crate::set_selinux_context; use crate::{ CopyMode, CopyResult, CpError, Options, aligned_ancestors, copy_attributes, copy_file, @@ -582,7 +582,7 @@ pub(crate) fn copy_directory( options.set_selinux_context, )?; - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if options.set_selinux_context { set_selinux_context(&dir.dest, options.context.as_ref())?; } @@ -594,7 +594,7 @@ pub(crate) fn copy_directory( // Even after a failed copy, so that no `--parents` directory stays owner-only. let fixed = set_parent_dirs_attributes(&parent_dirs, options); - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] let fixed = fixed.and_then(|()| { if !options.set_selinux_context { return Ok(()); diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 8fe2f0b1a14..43f064f6993 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -915,11 +915,11 @@ impl Attributes { mode: Preserve::Yes { required: true }, timestamps: Preserve::Yes { required: true }, context: { - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] { Preserve::Yes { required: false } } - #[cfg(not(all(feature = "selinux", any(target_os = "linux", target_os = "android"))))] + #[cfg(not(selinux))] { Preserve::No { explicit: false } } @@ -1213,7 +1213,7 @@ impl Options { } } - #[cfg(not(all(feature = "selinux", any(target_os = "linux", target_os = "android"))))] + #[cfg(not(selinux))] if let Preserve::Yes { required } = attributes.context { let selinux_disabled_error = CpError::Error(translate!("cp-error-selinux-not-enabled")); if required { @@ -1227,9 +1227,9 @@ impl Options { matches.get_flag(options::SELINUX) || matches.contains_id(options::CONTEXT); let context = matches.get_one::(options::CONTEXT).cloned(); - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] let selinux_enabled = uucore::selinux::is_selinux_enabled(); - #[cfg(not(all(feature = "selinux", any(target_os = "linux", target_os = "android"))))] + #[cfg(not(selinux))] let selinux_enabled = false; if context.is_some() && !selinux_enabled { show_warning!("{}", translate!("cp-warning-context-ignored")); @@ -1794,7 +1794,7 @@ fn handle_preserve CopyResult<()>>(p: Preserve, f: F) -> CopyResult<( Ok(()) } -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] pub(crate) fn set_selinux_context(path: &Path, context: Option<&String>) -> CopyResult<()> { if !uucore::selinux::is_selinux_enabled() { return Ok(()); @@ -2029,7 +2029,7 @@ pub(crate) fn copy_attributes( Ok(()) })?; - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] handle_preserve(attributes.context, || -> CopyResult<()> { // Get the source context and apply it to the destination let context = selinux::SecurityContext::of_path(source, false, false).map_err(|_| { @@ -3052,7 +3052,7 @@ fn copy_file( } })?; - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if options.set_selinux_context { set_selinux_context(dest, options.context.as_ref())?; } diff --git a/src/uu/id/Cargo.toml b/src/uu/id/Cargo.toml index 71a6386c9d9..dc2a3005e8b 100644 --- a/src/uu/id/Cargo.toml +++ b/src/uu/id/Cargo.toml @@ -22,6 +22,9 @@ fluent = { workspace = true } rustix = { workspace = true, features = ["process"] } uucore = { workspace = true, features = ["entries", "process"] } +[build-dependencies] +cfg_aliases = { workspace = true } + [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] selinux = { workspace = true, optional = true } diff --git a/src/uu/id/build.rs b/src/uu/id/build.rs new file mode 100644 index 00000000000..c93ccb84575 --- /dev/null +++ b/src/uu/id/build.rs @@ -0,0 +1,11 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; + +pub fn main() { + cfg_aliases::register(); +} diff --git a/src/uu/id/src/id.rs b/src/uu/id/src/id.rs index 8f306b670e0..57cb6eadeaf 100644 --- a/src/uu/id/src/id.rs +++ b/src/uu/id/src/id.rs @@ -46,16 +46,9 @@ macro_rules! cstr2cow { } fn get_context_help_text() -> String { - #[cfg(any( - all(feature = "selinux", any(target_os = "android", target_os = "linux")), - all(feature = "smack", target_os = "linux"), - ))] + #[cfg(any(selinux, smack))] return translate!("id-context-help-enabled"); - - #[cfg(not(any( - all(feature = "selinux", any(target_os = "android", target_os = "linux")), - all(feature = "smack", target_os = "linux"), - )))] + #[cfg(not(any(selinux, smack)))] return translate!("id-context-help-disabled"); } @@ -89,9 +82,9 @@ struct State { rflag: bool, // --real zflag: bool, // --zero cflag: bool, // --context - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] selinux_supported: bool, - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] smack_supported: bool, ids: Option, // The behavior for calling GNU's `id` and calling GNU's `id $USER` is similar but different. @@ -130,9 +123,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { rflag: matches.get_flag(options::OPT_REAL_ID), zflag: matches.get_flag(options::OPT_ZERO), cflag: matches.get_flag(options::OPT_CONTEXT), - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] selinux_supported: uucore::selinux::is_selinux_enabled(), - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] smack_supported: uucore::smack::is_smack_enabled(), user_specified: !users.is_empty(), ids: None, @@ -168,7 +161,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if state.cflag { // SELinux context - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if state.selinux_supported { if let Ok(context) = selinux::SecurityContext::current(false) { let bytes = context.as_bytes(); @@ -182,7 +175,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } // SMACK label - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] if state.smack_supported { match uucore::smack::get_smack_label_for_self() { Ok(label) => { @@ -719,7 +712,7 @@ fn id_print(state: &State, groups: &[u32]) -> io::Result<()> { .join(",") )?; - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if state.selinux_supported && !state.user_specified && std::env::var_os("POSIXLY_CORRECT").is_none() @@ -731,7 +724,7 @@ fn id_print(state: &State, groups: &[u32]) -> io::Result<()> { } } - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] if state.smack_supported && !state.user_specified && std::env::var_os("POSIXLY_CORRECT").is_none() diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index 9336a6abb51..df94c68a93f 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -29,6 +29,9 @@ uucore = { workspace = true, default-features = true, features = [ "process", ] } +[build-dependencies] +cfg_aliases = { workspace = true } + [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] rustix = { workspace = true, features = ["fs"] } selinux = { workspace = true, optional = true } diff --git a/src/uu/install/build.rs b/src/uu/install/build.rs new file mode 100644 index 00000000000..c93ccb84575 --- /dev/null +++ b/src/uu/install/build.rs @@ -0,0 +1,11 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; + +pub fn main() { + cfg_aliases::register(); +} diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 4efed2f4a8c..3073f3ee689 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -11,7 +11,7 @@ mod mode; use clap::{Arg, ArgAction, ArgMatches, Command}; use rustix::process::{getegid, geteuid}; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use selinux::SecurityContext; use std::collections::HashSet; use std::ffi::OsString; @@ -32,7 +32,7 @@ use uucore::fs::{are_files_identical, dir_strip_dot_for_creation}; use uucore::perms::{Verbosity, VerbosityLevel, wrap_chown}; #[cfg(not(target_os = "redox"))] use uucore::safe_traversal::{DirFd, SymlinkBehavior, create_dir_all_safe}; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use uucore::selinux::{ SeLinuxError, contexts_differ, get_selinux_security_context, is_selinux_enabled, selinux_error_description, set_selinux_security_context, @@ -136,7 +136,7 @@ enum InstallError { #[error("{}", translate!("install-error-extra-operand", "operand" => .0.quote(), "usage" => .1))] ExtraOperand(OsString, String), - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] #[error("{}", .0)] SelinuxContextFailed(String), @@ -457,9 +457,9 @@ fn behavior(matches: &ArgMatches, diag_args: Option<&[OsString]>) -> UResult(OPT_CONTEXT).cloned(); @@ -534,7 +534,7 @@ fn directory(paths: &[OsString], b: &Behavior) -> UResult<()> { } // Set SELinux context for all created directories if needed - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if should_set_selinux_context(b) { let context = get_context_for_selinux(b); set_selinux_context_for_directories_install(path_to_create.as_path(), context); @@ -560,7 +560,7 @@ fn directory(paths: &[OsString], b: &Behavior) -> UResult<()> { } // Set SELinux context for directory if needed - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if b.privileged { if b.default_context { show_if_err!(set_selinux_default_context(path)); @@ -741,10 +741,7 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { } // Set SELinux context for all created directories if needed - #[cfg(all( - feature = "selinux", - any(target_os = "linux", target_os = "android") - ))] + #[cfg(selinux)] if should_set_selinux_context(b) { let context = get_context_for_selinux(b); set_selinux_context_for_directories_install(to_create, context); @@ -1205,7 +1202,7 @@ fn finalize_installed_file( preserve_timestamps(from, to)?; } - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if b.privileged { if b.preserve_context { uucore::selinux::preserve_security_context(from, to) @@ -1260,7 +1257,7 @@ fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> { finalize_installed_file(from, to, b, backup_path) } -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn get_context_for_selinux(b: &Behavior) -> Option<&String> { if b.default_context { None @@ -1269,7 +1266,7 @@ fn get_context_for_selinux(b: &Behavior) -> Option<&String> { } } -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn should_set_selinux_context(b: &Behavior) -> bool { b.privileged && (b.context.is_some() || b.default_context) } @@ -1371,7 +1368,7 @@ fn need_copy(from: &Path, to: &Path, b: &Behavior) -> bool { } if b.privileged { - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if b.preserve_context && contexts_differ(from, to) { return true; } @@ -1413,7 +1410,7 @@ fn need_copy(from: &Path, to: &Path, b: &Behavior) -> bool { /// # Returns /// /// Returns `Ok(())` if the context was successfully set, or a `SeLinuxError` if the operation failed. -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] pub fn set_selinux_default_context(path: &Path) -> Result<(), SeLinuxError> { if !is_selinux_enabled() { return Err(SeLinuxError::SELinuxNotEnabled); @@ -1453,7 +1450,7 @@ pub fn set_selinux_default_context(path: &Path) -> Result<(), SeLinuxError> { /// * `Ok(Some(String))` - The default context string if successfully determined /// * `Ok(None)` - No default context could be determined /// * `Err(SeLinuxError)` - An error occurred while determining the context -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn get_default_context_for_path(path: &Path) -> Result, SeLinuxError> { if !is_selinux_enabled() { return Err(SeLinuxError::SELinuxNotEnabled); @@ -1494,7 +1491,7 @@ fn get_default_context_for_path(path: &Path) -> Result, SeLinuxEr /// This is a heuristic function that attempts to generate an appropriate /// context for a file based on its parent directory's context and file type. /// The goal is to mimic what `restorecon` would do based on `SELinux` policy. -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn derive_context_from_parent(parent_context: &str) -> String { // Parse the parent context (format: user:role:type:level) let parts: Vec<&str> = parent_context.split(':').collect(); @@ -1526,7 +1523,7 @@ fn derive_context_from_parent(parent_context: &str) -> String { /// /// Traverses from the given starting path up to existing parent directories. /// Returns a vector of paths in reverse order (from parent to child). -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn collect_paths_for_context_setting(starting_path: &Path) -> Vec<&Path> { let mut paths: Vec<&Path> = starting_path .ancestors() @@ -1569,7 +1566,7 @@ fn collect_paths_for_context_setting(starting_path: &Path) -> Vec<&Path> { /// // let context = String::from("user_u:object_r:tmp_t:s0"); /// // set_selinux_context_for_directories(Path::new("/tmp/new/deep/dir"), Some(&context)); /// ``` -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn set_selinux_context_for_directories(target_path: &Path, context: Option<&String>) { for path in collect_paths_for_context_setting(target_path) { show_if_err!(set_selinux_security_context(path, context)); @@ -1585,7 +1582,7 @@ fn set_selinux_context_for_directories(target_path: &Path, context: Option<&Stri /// /// * `target_path` - The target path (typically the deepest directory in a hierarchy) /// * `context` - Optional `SELinux` context string to set. If None, uses install's default derivation. -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] pub fn set_selinux_context_for_directories_install(target_path: &Path, context: Option<&String>) { if context.is_some() { // Use the standard function for explicit contexts @@ -1600,10 +1597,10 @@ pub fn set_selinux_context_for_directories_install(target_path: &Path, context: #[cfg(test)] mod tests { - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] use super::derive_context_from_parent; - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] #[test] fn test_derive_context_from_parent() { // Test cases: (input_context, file_type, expected_output, description) diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index afb85b99e21..d1352e72202 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -60,6 +60,9 @@ divan = { workspace = true } tempfile = { workspace = true } uucore = { workspace = true, features = ["benchmark"] } +[build-dependencies] +cfg_aliases = { workspace = true } + [[bench]] name = "ls_bench" harness = false diff --git a/src/uu/ls/build.rs b/src/uu/ls/build.rs new file mode 100644 index 00000000000..c93ccb84575 --- /dev/null +++ b/src/uu/ls/build.rs @@ -0,0 +1,11 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; + +pub fn main() { + cfg_aliases::register(); +} diff --git a/src/uu/ls/src/config.rs b/src/uu/ls/src/config.rs index 29f4d9415af..40339aeeeb7 100644 --- a/src/uu/ls/src/config.rs +++ b/src/uu/ls/src/config.rs @@ -237,9 +237,9 @@ pub struct Config { pub(crate) time_format_recent: String, // Time format for recent dates pub(crate) time_format_older: Option, // Time format for older dates (optional, if not present, time_format_recent is used) pub(crate) context: bool, - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] pub(crate) selinux_supported: bool, - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] pub(crate) smack_supported: bool, pub(crate) group_directories_first: bool, pub(crate) line_ending: LineEnding, @@ -974,9 +974,9 @@ impl Config { time_format_recent, time_format_older, context, - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] selinux_supported: uucore::selinux::is_selinux_enabled(), - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] smack_supported: uucore::smack::is_smack_enabled(), group_directories_first: options.get_flag(options::GROUP_DIRECTORIES_FIRST), line_ending: LineEnding::from_zero_flag(options.get_flag(options::ZERO)), diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index c7e6fd48804..2de23d97cc4 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -1708,7 +1708,7 @@ fn get_security_context<'a>( return Cow::Borrowed(SUBSTITUTE_STRING); } - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if config.selinux_supported { use uucore::show_warning; @@ -1750,7 +1750,7 @@ fn get_security_context<'a>( } } - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] if config.smack_supported { // For SMACK, use the path to get the label // If must_dereference is true, we follow the symlink diff --git a/src/uu/mkdir/Cargo.toml b/src/uu/mkdir/Cargo.toml index 37b4ef66b63..bc9a7399299 100644 --- a/src/uu/mkdir/Cargo.toml +++ b/src/uu/mkdir/Cargo.toml @@ -26,6 +26,9 @@ uucore = { workspace = true, features = [ "quoting-style", ] } +[build-dependencies] +cfg_aliases = { workspace = true } + [features] diagnostics = ["uucore/diagnostics"] selinux = ["uucore/selinux"] diff --git a/src/uu/mkdir/build.rs b/src/uu/mkdir/build.rs new file mode 100644 index 00000000000..c93ccb84575 --- /dev/null +++ b/src/uu/mkdir/build.rs @@ -0,0 +1,11 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; + +pub fn main() { + cfg_aliases::register(); +} diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index 09989d0a77e..52eccc4b84b 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -292,7 +292,7 @@ fn create_single_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<( let (mkdir_mode, shaped_umask) = (config.mode.unwrap_or(DEFAULT_PERM), 0u32); // Label the directory at creation, as GNU does; relabelling after leaves a window. - #[cfg(all(feature = "selinux", any(target_os = "android", target_os = "linux")))] + #[cfg(selinux)] let _selinux_guard = if config.set_security_context && uucore::selinux::is_selinux_enabled() { let mode = uucore::libc::S_IFDIR | mkdir_mode as uucore::libc::mode_t; match uucore::selinux::FsCreateContext::new(path, Some(mode), config.context) { @@ -314,7 +314,7 @@ fn create_single_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<( } // Apply SMACK context if requested - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] if config.set_security_context { uucore::smack::set_smack_label_and_cleanup(path, config.context, |p| { std::fs::remove_dir(p) diff --git a/src/uu/mkfifo/Cargo.toml b/src/uu/mkfifo/Cargo.toml index 97b3429871d..a81b387fd2a 100644 --- a/src/uu/mkfifo/Cargo.toml +++ b/src/uu/mkfifo/Cargo.toml @@ -21,6 +21,9 @@ clap = { workspace = true } fluent = { workspace = true } uucore = { workspace = true, features = ["fs", "mode"] } +[build-dependencies] +cfg_aliases = { workspace = true } + [target.'cfg(unix)'.dependencies] rustix = { workspace = true, features = ["fs"] } diff --git a/src/uu/mkfifo/build.rs b/src/uu/mkfifo/build.rs new file mode 100644 index 00000000000..c93ccb84575 --- /dev/null +++ b/src/uu/mkfifo/build.rs @@ -0,0 +1,11 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; + +pub fn main() { + cfg_aliases::register(); +} diff --git a/src/uu/mkfifo/src/mkfifo.rs b/src/uu/mkfifo/src/mkfifo.rs index 5656a578469..7cd1e987cf3 100644 --- a/src/uu/mkfifo/src/mkfifo.rs +++ b/src/uu/mkfifo/src/mkfifo.rs @@ -56,7 +56,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { for f in fifos { // Label the FIFO at creation, as GNU does; relabelling after leaves a window. - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] let _selinux_guard = { let set_security_context = matches.get_flag(options::SECURITY_CONTEXT); let context = matches.get_one::(options::CONTEXT); @@ -94,7 +94,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { )); } else { // Apply SMACK context if requested - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] { let set_security_context = matches.get_flag(options::SECURITY_CONTEXT); let context = matches.get_one::(options::CONTEXT); diff --git a/src/uu/mknod/Cargo.toml b/src/uu/mknod/Cargo.toml index f25823b9ec1..10a5a40e7a8 100644 --- a/src/uu/mknod/Cargo.toml +++ b/src/uu/mknod/Cargo.toml @@ -23,6 +23,9 @@ fluent = { workspace = true } nix = { workspace = true, features = ["fs"] } uucore = { workspace = true, features = ["fs", "mode"] } +[build-dependencies] +cfg_aliases = { workspace = true } + [features] diagnostics = ["uucore/diagnostics"] selinux = ["uucore/selinux"] diff --git a/src/uu/mknod/build.rs b/src/uu/mknod/build.rs new file mode 100644 index 00000000000..c93ccb84575 --- /dev/null +++ b/src/uu/mknod/build.rs @@ -0,0 +1,11 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; + +pub fn main() { + cfg_aliases::register(); +} diff --git a/src/uu/mknod/src/mknod.rs b/src/uu/mknod/src/mknod.rs index f293a5c8d3d..83be80fb052 100644 --- a/src/uu/mknod/src/mknod.rs +++ b/src/uu/mknod/src/mknod.rs @@ -59,10 +59,7 @@ struct Config { dev: dev_t, /// Set security context (SELinux/SMACK). - #[cfg(any( - all(feature = "selinux", any(target_os = "android", target_os = "linux")), - all(feature = "smack", target_os = "linux"), - ))] + #[cfg(any(selinux, smack))] set_security_context: bool, /// Specific security context (SELinux/SMACK). @@ -70,9 +67,9 @@ struct Config { } fn mknod(file_name: &str, config: Config) -> i32 { - #[cfg(all(feature = "selinux", any(target_os = "android", target_os = "linux")))] + #[cfg(selinux)] let selinux_enabled = uucore::selinux::is_selinux_enabled(); - #[cfg(not(all(feature = "selinux", any(target_os = "android", target_os = "linux"))))] + #[cfg(not(selinux))] let selinux_enabled = false; #[cfg(all(feature = "smack", target_os = "linux"))] let smack_enabled = uucore::smack::is_smack_enabled(); @@ -84,7 +81,7 @@ fn mknod(file_name: &str, config: Config) -> i32 { } // Label the node at creation, as GNU does; relabelling after leaves a window. - #[cfg(all(feature = "selinux", any(target_os = "android", target_os = "linux")))] + #[cfg(selinux)] let _selinux_guard = if config.set_security_context && selinux_enabled { let mode = config.file_type.as_sflag().bits() | config.mode.bits(); match uucore::selinux::FsCreateContext::new( @@ -128,7 +125,7 @@ fn mknod(file_name: &str, config: Config) -> i32 { } // Apply SMACK context if requested - #[cfg(all(feature = "smack", target_os = "linux"))] + #[cfg(smack)] if config.set_security_context && smack_enabled && let Err(e) = @@ -186,10 +183,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .expect("Missing argument 'NAME'"); // Extract the security context related flags and options - #[cfg(any( - all(feature = "selinux", any(target_os = "android", target_os = "linux")), - all(feature = "smack", target_os = "linux"), - ))] + #[cfg(any(selinux, smack))] let set_security_context = matches.get_flag(options::SECURITY_CONTEXT); let context = matches.get_one::(options::CONTEXT).cloned(); @@ -219,10 +213,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { file_type: file_type.clone(), use_umask, dev, - #[cfg(any( - all(feature = "selinux", any(target_os = "android", target_os = "linux")), - all(feature = "smack", target_os = "linux"), - ))] + #[cfg(any(selinux, smack))] set_security_context: set_security_context || context.is_some(), context, }; diff --git a/src/uu/mv/Cargo.toml b/src/uu/mv/Cargo.toml index f446311a32f..bd126cd9a01 100644 --- a/src/uu/mv/Cargo.toml +++ b/src/uu/mv/Cargo.toml @@ -53,6 +53,9 @@ divan = { workspace = true } tempfile = { workspace = true } uucore = { workspace = true, features = ["benchmark"] } +[build-dependencies] +cfg_aliases = { workspace = true } + [features] selinux = ["uucore/selinux"] diff --git a/src/uu/mv/build.rs b/src/uu/mv/build.rs new file mode 100644 index 00000000000..c93ccb84575 --- /dev/null +++ b/src/uu/mv/build.rs @@ -0,0 +1,11 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; + +pub fn main() { + cfg_aliases::register(); +} diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index d1009c6397b..7afcfbe91be 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -59,7 +59,7 @@ use uucore::fs::{ target_os = "netbsd" ))] use uucore::fsxattr; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use uucore::selinux::set_selinux_security_context; use uucore::translate; use uucore::update_control; @@ -910,7 +910,7 @@ fn rename( rename_with_fallback(from, to, display_manager, opts.verbose, None, None)?; } - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if let Some(ref context) = opts.context { set_selinux_security_context(to, Some(context)) .map_err(|e| io::Error::other(e.to_string()))?; diff --git a/src/uu/stat/Cargo.toml b/src/uu/stat/Cargo.toml index 939e53b62cd..96c63c6bd6b 100644 --- a/src/uu/stat/Cargo.toml +++ b/src/uu/stat/Cargo.toml @@ -30,6 +30,9 @@ uucore = { workspace = true, features = [ "i18n-common", ] } +[build-dependencies] +cfg_aliases = { workspace = true } + [features] selinux = ["uucore/selinux"] diff --git a/src/uu/stat/build.rs b/src/uu/stat/build.rs new file mode 100644 index 00000000000..c93ccb84575 --- /dev/null +++ b/src/uu/stat/build.rs @@ -0,0 +1,11 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[path = "../../../cfg_aliases.rs"] +mod cfg_aliases; + +pub fn main() { + cfg_aliases::register(); +} diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index 86ab0da667e..6770a2f7ce9 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -1154,10 +1154,8 @@ impl Stater { display_name: &str, file: &OsString, file_type: FileType, - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] - follow_symbolic_links: bool, - #[cfg(not(all(feature = "selinux", any(target_os = "linux", target_os = "android"))))] - _: bool, + #[cfg(selinux)] follow_symbolic_links: bool, + #[cfg(not(selinux))] _: bool, ) -> Result<(), i32> { match *t { Token::Byte(byte) => print_raw_byte(byte), @@ -1185,10 +1183,7 @@ impl Stater { 'B' => OutputType::Unsigned(512), // SELinux security context string 'C' => { - #[cfg(all( - feature = "selinux", - any(target_os = "linux", target_os = "android") - ))] + #[cfg(selinux)] { if uucore::selinux::is_selinux_enabled() { match uucore::selinux::get_selinux_security_context( @@ -1204,10 +1199,7 @@ impl Stater { OutputType::Str(translate!("stat-selinux-unsupported-system")) } } - #[cfg(not(all( - feature = "selinux", - any(target_os = "linux", target_os = "android") - )))] + #[cfg(not(selinux))] { OutputType::Str(translate!("stat-selinux-unsupported-os")) } diff --git a/src/uucore/build.rs b/src/uucore/build.rs index 5d968159706..8f67137f08c 100644 --- a/src/uucore/build.rs +++ b/src/uucore/build.rs @@ -5,29 +5,16 @@ // spell-checker:ignore tvos watchos visionos -use cfg_aliases::cfg_aliases; use std::env; use std::fs::File; use std::io::Write; use std::path::{Path, PathBuf}; +#[path = "../../cfg_aliases.rs"] +mod cfg_aliases; + pub fn main() -> Result<(), Box> { - cfg_aliases! { - // Directory open flags that grant search but not read access. - // tests/by-util/test_install.rs repeats the union of these targets. - has_o_path: { any(target_os = "linux", target_os = "android") }, - has_o_search: { any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - target_os = "freebsd", - target_os = "netbsd", - target_os = "illumos", - target_os = "solaris" - ) }, - } + cfg_aliases::register(); let out_dir = env::var("OUT_DIR")?; diff --git a/src/uucore/src/lib/features.rs b/src/uucore/src/lib/features.rs index 8cfa2d52808..29e966811d3 100644 --- a/src/uucore/src/lib/features.rs +++ b/src/uucore/src/lib/features.rs @@ -107,7 +107,7 @@ pub mod tty; pub mod fsxattr; #[cfg(feature = "hardware")] pub mod hardware; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] pub mod selinux; #[cfg(all( feature = "signals", @@ -129,7 +129,7 @@ pub mod selinux; ) ))] pub mod signals; -#[cfg(all(feature = "smack", target_os = "linux"))] +#[cfg(smack)] pub mod smack; #[cfg(all(feature = "systemd_logind", target_os = "linux"))] pub mod systemd_logind; diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index a27b014fec5..296f6a80dc6 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -167,10 +167,10 @@ pub use crate::features::fsext; ))] pub use crate::features::fsxattr; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] pub use crate::features::selinux; -#[cfg(all(feature = "smack", target_os = "linux"))] +#[cfg(smack)] pub use crate::features::smack; //## core functions diff --git a/tests/by-util/test_chcon.rs b/tests/by-util/test_chcon.rs index 5341063b6d4..3110736c100 100644 --- a/tests/by-util/test_chcon.rs +++ b/tests/by-util/test_chcon.rs @@ -6,7 +6,7 @@ // spell-checker:ignore (jargon) xattributes #![allow(clippy::missing_errors_doc, clippy::similar_names)] -#![cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#![cfg(selinux)] use std::ffi::CString; use std::path::Path; diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index eff7534b4c6..a408a27c987 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -8,7 +8,7 @@ use rstest::rstest; use uucore::display::Quotable; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use uucore::selinux::get_getfattr_output; use uutests::util::TestScenario; use uutests::{at_and_ucmd, new_ucmd, path, util_name}; @@ -8082,7 +8082,7 @@ fn test_cp_from_stream_permission() { #[test] fn test_cp_context_without_selinux() { - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if uucore::selinux::is_selinux_enabled() { println!("Test skipped: SELinux is enabled"); return; @@ -8117,7 +8117,7 @@ fn test_cp_context_without_selinux() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_selinux() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -8142,7 +8142,7 @@ fn test_cp_selinux() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_selinux_default_context_relative_dest() { // -Z labels the destination with the context the policy has for its path, // and the policy only lists absolute paths: a relative destination used to @@ -8182,7 +8182,7 @@ fn test_cp_selinux_default_context_relative_dest() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_selinux_invalid() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -8206,7 +8206,7 @@ fn test_cp_selinux_invalid() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_preserve_selinux() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -8244,7 +8244,7 @@ fn test_cp_preserve_selinux() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_preserve_selinux_admin_context() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -8303,7 +8303,7 @@ fn test_cp_preserve_selinux_admin_context() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_selinux_context_priority() { // This test verifies that -Z takes priority over --context @@ -8383,7 +8383,7 @@ fn test_cp_selinux_context_priority() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_selinux_empty_context() { // This test verifies that --context without a value works like -Z @@ -8429,7 +8429,7 @@ fn test_cp_selinux_empty_context() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_selinux_recursive() { // Test SELinux context preservation in recursive directory copies @@ -8483,7 +8483,7 @@ fn test_cp_selinux_recursive() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_preserve_context_root() { use uutests::util::run_ucmd_as_root; let scene = TestScenario::new(util_name!()); @@ -9644,7 +9644,7 @@ fn test_cp_gnu_preserve_mode() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_a_z_overrides_context() { // Verifies -aZ succeeds (-Z overrides implicit --preserve=context from -a) use uucore::selinux::set_selinux_security_context; @@ -9661,7 +9661,7 @@ fn test_cp_a_z_overrides_context() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_a_preserves_context() { use uucore::selinux::{get_selinux_security_context, set_selinux_security_context}; @@ -9681,7 +9681,7 @@ fn test_cp_a_preserves_context() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_cp_preserve_context_with_z_fails() { for arg in ["-Z", "--context"] { let (at, mut ucmd) = at_and_ucmd!(); diff --git a/tests/by-util/test_id.rs b/tests/by-util/test_id.rs index 30e4c1ac9a0..09c8b05c5fd 100644 --- a/tests/by-util/test_id.rs +++ b/tests/by-util/test_id.rs @@ -417,7 +417,7 @@ fn test_id_zero() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_id_context() { if !uucore::selinux::is_selinux_enabled() { println!("test skipped: Kernel has no support for SElinux context"); diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 338af4ed786..28c7e6f1cab 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -16,7 +16,7 @@ use std::os::unix::fs::{MetadataExt, PermissionsExt}; #[cfg(any(target_os = "linux", target_os = "android"))] use std::thread::sleep; use uucore::error::strip_errno; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use uucore::selinux::get_getfattr_output; use uutests::util::{TestScenario, is_ci, run_ucmd_as_root}; use uutests::{at_and_ucmd, new_ucmd, util_name}; @@ -2363,7 +2363,7 @@ fn test_install_no_target_basic() { #[test] fn test_context_without_selinux() { - #[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] + #[cfg(selinux)] if uucore::selinux::is_selinux_enabled() { println!("Test skipped: SELinux is enabled"); return; @@ -2441,7 +2441,7 @@ fn test_selinux() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_selinux_invalid_args() { if !uucore::selinux::is_selinux_enabled() { println!("Test skipped: SELinux is not enabled"); @@ -2473,7 +2473,7 @@ fn test_selinux_invalid_args() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_selinux_default_context() { if !uucore::selinux::is_selinux_enabled() { println!("Test skipped: SELinux is not enabled"); diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 6b02b890d36..37841d5ac38 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -5265,7 +5265,7 @@ fn test_ls_long_self_referential_dir_lists_contents() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_ls_context1() { if !uucore::selinux::is_selinux_enabled() { println!("test skipped: Kernel has no support for SElinux context"); @@ -5280,7 +5280,7 @@ fn test_ls_context1() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_ls_context2() { if !uucore::selinux::is_selinux_enabled() { println!("test skipped: Kernel has no support for SElinux context"); @@ -5296,7 +5296,7 @@ fn test_ls_context2() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_ls_context_long() { if !uucore::selinux::is_selinux_enabled() { return; @@ -5315,7 +5315,7 @@ fn test_ls_context_long() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_ls_context_format() { if !uucore::selinux::is_selinux_enabled() { println!("test skipped: Kernel has no support for SElinux context"); @@ -5345,7 +5345,7 @@ fn test_ls_context_format() { } /// Helper function to validate `SELinux` context format -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn validate_selinux_context(context: &str) { assert!( context.contains(':'), @@ -5360,7 +5360,7 @@ fn validate_selinux_context(context: &str) { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_ls_selinux_context_format() { if !uucore::selinux::is_selinux_enabled() { println!("test skipped: Kernel has no support for SElinux context"); @@ -5393,7 +5393,7 @@ fn test_ls_selinux_context_format() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_ls_selinux_context_indicator() { if !uucore::selinux::is_selinux_enabled() { println!("test skipped: Kernel has no support for SElinux context"); diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index 64d2610c488..8fc21849fd8 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -11,7 +11,7 @@ use libc::mode_t; #[cfg(not(windows))] use std::os::unix::fs::PermissionsExt; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use uucore::selinux::get_getfattr_output; #[cfg(not(windows))] use uutests::at_and_ucmd; @@ -555,7 +555,7 @@ fn test_empty_argument() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_selinux() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -579,7 +579,7 @@ fn test_selinux() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_selinux_invalid() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; diff --git a/tests/by-util/test_mkfifo.rs b/tests/by-util/test_mkfifo.rs index 8fd208e02cb..c44788994ce 100644 --- a/tests/by-util/test_mkfifo.rs +++ b/tests/by-util/test_mkfifo.rs @@ -5,7 +5,7 @@ // spell-checker:ignore nconfined -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use uucore::selinux::get_getfattr_output; use uutests::new_ucmd; use uutests::util::TestScenario; @@ -168,7 +168,7 @@ fn test_create_fifo_permission_denied() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_mkfifo_selinux() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; @@ -192,7 +192,7 @@ fn test_mkfifo_selinux() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_mkfifo_selinux_invalid() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; diff --git a/tests/by-util/test_mknod.rs b/tests/by-util/test_mknod.rs index 2d1a3d98b1e..8758ae4f02a 100644 --- a/tests/by-util/test_mknod.rs +++ b/tests/by-util/test_mknod.rs @@ -7,7 +7,7 @@ use std::os::unix::fs::PermissionsExt; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use uucore::selinux::get_getfattr_output; use uutests::new_ucmd; use uutests::util::TestScenario; @@ -258,7 +258,7 @@ fn test_mknod_fifo_with_umask() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_mknod_selinux() { if !uucore::selinux::is_selinux_enabled() { println!("Test skipped: SELinux is not enabled"); @@ -294,7 +294,7 @@ fn test_mknod_selinux() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_mknod_selinux_invalid() { if !uucore::selinux::is_selinux_enabled() { println!("Test skipped: SELinux is not enabled"); @@ -326,7 +326,7 @@ fn test_mknod_selinux_invalid() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_mknod_selinux_invalid_cleanup() { if !uucore::selinux::is_selinux_enabled() { println!("Test skipped: SELinux is not enabled"); diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index ef769ee57b6..d10fef9d439 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -10,7 +10,7 @@ use rstest::rstest; use std::io::Write; #[cfg(not(windows))] use std::path::Path; -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] use uucore::selinux::get_getfattr_output; use uutests::new_ucmd; #[cfg(unix)] @@ -2812,7 +2812,7 @@ fn test_mv_cross_device_dir_refuses_symlink_at_recreated_dest() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_mv_selinux_context() { let test_cases = [ ("-Z", None), diff --git a/tests/by-util/test_runcon.rs b/tests/by-util/test_runcon.rs index 0814cb55a54..8464b54f042 100644 --- a/tests/by-util/test_runcon.rs +++ b/tests/by-util/test_runcon.rs @@ -5,7 +5,7 @@ // spell-checker:ignore (jargon) xattributes -#![cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#![cfg(selinux)] use uutests::new_ucmd; @@ -97,7 +97,7 @@ fn invalid() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn plain_context() { let ctx = "unconfined_u:unconfined_r:unconfined_t:s0-s0"; new_ucmd!().args(&[ctx, "/bin/true"]).succeeds(); @@ -116,7 +116,7 @@ fn plain_context() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn custom_context() { let t_ud = "unconfined_t"; let u_ud = "unconfined_u"; diff --git a/tests/by-util/test_stat.rs b/tests/by-util/test_stat.rs index 682c0e7d0d3..52904c21220 100644 --- a/tests/by-util/test_stat.rs +++ b/tests/by-util/test_stat.rs @@ -882,7 +882,7 @@ fn test_precision_splits_multibyte_char_in_value() { } #[test] -#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))] +#[cfg(selinux)] fn test_stat_selinux() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; From 07a5e95c54698c53028fe6cb1094e212abd7b5e7 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Sat, 31 Oct 2026 11:44:05 +0000 Subject: [PATCH 3/3] build: use shared `has_o_*` cfg aliases --- cfg_aliases.rs | 12 ++++++++++++ tests/by-util/test_install.rs | 17 +---------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/cfg_aliases.rs b/cfg_aliases.rs index 64c1cc6f4ca..86733bb7005 100644 --- a/cfg_aliases.rs +++ b/cfg_aliases.rs @@ -12,6 +12,18 @@ pub fn register() { target_os = "netbsd", target_os = "openbsd" ) }, + has_o_path: { any(target_os = "linux", target_os = "android") }, + has_o_search: { any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "visionos", + target_os = "freebsd", + target_os = "netbsd", + target_os = "illumos", + target_os = "solaris" + ) }, selinux: { all(feature = "selinux", any(target_os = "android", target_os = "linux")) }, smack: { all(feature = "smack", target_os = "linux") }, } diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 28c7e6f1cab..2de908a46d5 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -2796,22 +2796,7 @@ fn test_install_d_dangling_symlink_in_path_errors() { } #[test] -// The targets with O_PATH or O_SEARCH, as named by the `has_o_path` and -// `has_o_search` cfg aliases in src/uucore/build.rs. Elsewhere install cannot -// anchor on an unreadable directory and fails with EACCES. -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - target_os = "freebsd", - target_os = "netbsd", - target_os = "illumos", - target_os = "solaris" -))] +#[cfg(any(has_o_path, has_o_search))] fn test_install_d_leading_dirs_in_write_only_directory() { // mkdir needs write and execute on the parent, not read, so -D must be // able to create leading directories inside a directory it cannot read.