From 8bab5ce75c06f6412632f992f0d0df84dd7e8d34 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Tue, 15 Sep 2026 21:54:56 +0100 Subject: [PATCH] build(install): gate by target support Gate `install` to Unix targets. --- src/uu/install/Cargo.toml | 7 +++---- src/uu/install/src/install.rs | 38 +++++++++++++---------------------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index bee20905846..9336a6abb51 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -14,9 +14,10 @@ readme.workspace = true [lib] path = "src/install.rs" -[dependencies] +[target.'cfg(unix)'.dependencies] clap = { workspace = true } fluent = { workspace = true } +rustix = { workspace = true, features = ["process"] } thiserror = { workspace = true } uucore = { workspace = true, default-features = true, features = [ "backup-control", @@ -32,9 +33,6 @@ uucore = { workspace = true, default-features = true, features = [ rustix = { workspace = true, features = ["fs"] } selinux = { workspace = true, optional = true } -[target.'cfg(unix)'.dependencies] -rustix = { workspace = true, features = ["process"] } - [features] diagnostics = ["uucore/diagnostics"] selinux = ["dep:selinux", "uucore/selinux"] @@ -45,3 +43,4 @@ workspace = true [[bin]] name = "install" path = "src/main.rs" +required-features = ["uucore/default"] diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index cb938bf0f2b..333c8dfd29c 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -5,6 +5,8 @@ // spell-checker:ignore (ToDO) rwxr sourcepath targetpath Isnt uioerror matchpathcon +#![cfg(unix)] + mod mode; use clap::{Arg, ArgAction, ArgMatches, Command}; @@ -17,6 +19,8 @@ use std::fmt::Debug; use std::fs::{self, metadata}; use std::fs::{File, OpenOptions}; use std::io::{Write, stdout}; +use std::os::unix::fs::MetadataExt; +use std::os::unix::prelude::OsStrExt; use std::path::{MAIN_SEPARATOR, Path, PathBuf}; use std::process; use uucore::backup_control::{self, BackupMode, backup_would_destroy_source}; @@ -26,7 +30,7 @@ use uucore::entries::{grp2gid, usr2uid}; use uucore::error::{FromIo, UError, UResult, UUsageError, strip_errno}; use uucore::fs::{are_files_identical, dir_strip_dot_for_creation}; use uucore::perms::{Verbosity, VerbosityLevel, wrap_chown}; -#[cfg(all(unix, not(target_os = "redox")))] +#[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")))] use uucore::selinux::{ @@ -36,11 +40,6 @@ use uucore::selinux::{ use uucore::translate; use uucore::{format_usage, show, show_error, show_if_err}; -#[cfg(unix)] -use std::os::unix::fs::MetadataExt; -#[cfg(unix)] -use std::os::unix::prelude::OsStrExt; - const DEFAULT_MODE: u32 = 0o755; const DEFAULT_STRIP_PROGRAM: &str = "strip"; @@ -588,20 +587,11 @@ fn is_valid_target(path: &Path) -> bool { /// /// Returns true, if one of the conditions above is met; else false. /// -#[cfg(unix)] fn is_potential_directory_path(path: &Path) -> bool { let separator = MAIN_SEPARATOR as u8; path.as_os_str().as_bytes().last() == Some(&separator) || path.is_dir() } -#[cfg(not(unix))] -fn is_potential_directory_path(path: &Path) -> bool { - matches!( - path.as_os_str().as_encoded_bytes().last(), - Some(b'/') | Some(b'\\') - ) || path.is_dir() -} - /// Perform an install, given a list of paths and behavior. /// /// Returns a Result type with the Err variant containing the error message. @@ -644,9 +634,9 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { let sources = &paths.iter().map(PathBuf::from).collect::>(); - #[cfg(all(unix, not(target_os = "redox")))] + #[cfg(not(target_os = "redox"))] let mut target_parent_fd: Option = None; - #[cfg(all(unix, not(target_os = "redox")))] + #[cfg(not(target_os = "redox"))] let mut target_filename: Option = None; if b.create_leading { @@ -666,7 +656,7 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { } if let Some(to_create) = to_create { - #[cfg(all(unix, not(target_os = "redox")))] + #[cfg(not(target_os = "redox"))] let to_create_original = to_create; let to_create_owned; let to_create = match uucore::os_str_as_bytes(to_create.as_os_str()) { @@ -685,7 +675,7 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { let dir_exists = to_create.exists() && metadata(to_create).is_ok_and(|m| m.is_dir()); if dir_exists { - #[cfg(all(unix, not(target_os = "redox")))] + #[cfg(not(target_os = "redox"))] if b.target_dir.is_none() && sources.len() == 1 && !is_potential_directory_path(&target) @@ -712,7 +702,7 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { } } - #[cfg(all(unix, not(target_os = "redox")))] + #[cfg(not(target_os = "redox"))] { // Use DEFAULT_MODE (0o755) for created directories - this matches GNU install // behavior. The actual mode will be modified by umask at the kernel level. @@ -755,7 +745,7 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { } } } - #[cfg(any(not(unix), target_os = "redox"))] + #[cfg(target_os = "redox")] fs::create_dir_all(to_create) .map_err(|e| InstallError::CreateDirFailed(to_create.to_path_buf(), e))?; } @@ -790,7 +780,7 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { } if is_valid_target(&target) { - #[cfg(all(unix, not(target_os = "redox")))] + #[cfg(not(target_os = "redox"))] if let (Some(ref parent_fd), Some(ref filename)) = (target_parent_fd, target_filename) { if b.compare && !need_copy(source, &target, b) { return Ok(()); @@ -813,7 +803,7 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { } else { copy(source, &target, b) } - #[cfg(any(not(unix), target_os = "redox"))] + #[cfg(target_os = "redox")] { copy(source, &target, b) } @@ -976,7 +966,7 @@ fn perform_backup(from: &Path, to: &Path, b: &Behavior) -> UResult UResult<()> { let from_meta = metadata(from)?;