diff --git a/Cargo.lock b/Cargo.lock index 5d52f9b1d..e0413c73c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -618,9 +618,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.23.2" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17" +checksum = "ab9f7409c70a38a56216480fba371ee460207dd8926ccf5b4160591759559170" dependencies = [ "bitflags", "crossterm_winapi", @@ -802,14 +802,14 @@ checksum = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" [[package]] name = "filetime" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" +checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", - "winapi 0.3.9", + "windows-sys", ] [[package]] @@ -1286,9 +1286,9 @@ checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" [[package]] name = "onig" -version = "6.3.1" +version = "6.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ddfe2c93bb389eea6e6d713306880c7f6dcc99a75b659ce145d962c861b225" +checksum = "1eb3502504c9c8b06634b38bfdda86a9a8cef6277f3dec4d8b17c115110dd2a3" dependencies = [ "bitflags", "lazy_static", @@ -1298,9 +1298,9 @@ dependencies = [ [[package]] name = "onig_sys" -version = "69.7.1" +version = "69.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd3eee045c84695b53b20255bb7317063df090b68e18bfac0abb6c39cf7f33e" +checksum = "8bf3fbc9b931b6c9af85d219c7943c274a6ad26cff7488a2210215edd5f49bf8" dependencies = [ "cc", "pkg-config", diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index d4b81ee37..abde1bf7b 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -14,6 +14,7 @@ use std::path::Path; use uucore::display::Quotable; use uucore::error::{ExitCode, UResult, USimpleError, UUsageError}; use uucore::fs::display_permissions_unix; +use uucore::fs::is_symlink; use uucore::libc::mode_t; #[cfg(not(windows))] use uucore::mode; @@ -380,10 +381,3 @@ impl Chmoder { } } } - -pub fn is_symlink>(path: P) -> bool { - match fs::symlink_metadata(path) { - Ok(m) => m.file_type().is_symlink(), - Err(_) => false, - } -} diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 3a9f06ac6..9f93d8f64 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -56,7 +56,7 @@ use std::str::FromStr; use std::string::ToString; use uucore::backup_control::{self, BackupMode}; use uucore::error::{set_exit_code, ExitCode, UClapError, UError, UResult}; -use uucore::fs::{canonicalize, MissingHandling, ResolveMode}; +use uucore::fs::{canonicalize, is_symlink, MissingHandling, ResolveMode}; use walkdir::WalkDir; quick_error! { @@ -1075,7 +1075,7 @@ fn copy_directory( }; let local_to_target = target.join(&local_to_root_parent); - if is_symlink(&path) && !options.dereference { + if is_symlink(p.path()) && !options.dereference { copy_link(&path, &local_to_target, symlinked_files)?; } else if path.is_dir() && !local_to_target.exists() { if target.is_file() { @@ -1097,7 +1097,7 @@ fn copy_directory( ) { Ok(_) => Ok(()), Err(err) => { - if is_symlink(&source) { + if is_symlink(source) { // silent the error with a symlink // In case we do --archive, we might copy the symlink // before the file itself diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index 5d7639d61..ac1280117 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -14,6 +14,7 @@ use clap::{crate_version, Arg, Command}; use uucore::display::Quotable; use uucore::error::{UError, UResult}; use uucore::format_usage; +use uucore::fs::is_symlink; use std::borrow::Cow; use std::error::Error; @@ -533,10 +534,3 @@ pub fn symlink, P2: AsRef>(src: P1, dst: P2) -> Result<()> symlink_file(src, dst) } } - -pub fn is_symlink>(path: P) -> bool { - match fs::symlink_metadata(path) { - Ok(m) => m.file_type().is_symlink(), - Err(_) => false, - } -} diff --git a/src/uu/numfmt/src/numfmt.rs b/src/uu/numfmt/src/numfmt.rs index e8a4fd557..b87dc1122 100644 --- a/src/uu/numfmt/src/numfmt.rs +++ b/src/uu/numfmt/src/numfmt.rs @@ -211,7 +211,7 @@ pub fn uu_app<'a>() -> Command<'a> { .arg( Arg::new(options::FIELD) .long(options::FIELD) - .help("replace the numbers in these input fields (default=1) see FIELDS below") + .help("replace the numbers in these input fields; see FIELDS below") .value_name("FIELDS") .default_value(options::FIELD_DEFAULT), ) @@ -256,7 +256,7 @@ pub fn uu_app<'a>() -> Command<'a> { .long(options::ROUND) .help( "use METHOD for rounding when scaling; METHOD can be: up,\ - down, from-zero (default), towards-zero, nearest", + down, from-zero, towards-zero, nearest", ) .value_name("METHOD") .default_value("from-zero") diff --git a/src/uu/rmdir/src/rmdir.rs b/src/uu/rmdir/src/rmdir.rs index be4e53780..4318f5429 100644 --- a/src/uu/rmdir/src/rmdir.rs +++ b/src/uu/rmdir/src/rmdir.rs @@ -16,6 +16,9 @@ use std::io; use std::path::Path; use uucore::display::Quotable; use uucore::error::{set_exit_code, strip_errno, UResult}; + +#[cfg(unix)] +use uucore::fs::is_symlink; use uucore::{format_usage, util_name}; static ABOUT: &str = "Remove the DIRECTORY(ies), if they are empty."; @@ -65,10 +68,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; - fn is_symlink(path: &Path) -> io::Result { - Ok(path.symlink_metadata()?.file_type().is_symlink()) - } - fn points_to_directory(path: &Path) -> io::Result { Ok(path.metadata()?.file_type().is_dir()) } @@ -77,9 +76,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if error.raw_os_error() == Some(libc::ENOTDIR) && bytes.ends_with(b"/") { // Strip the trailing slash or .symlink_metadata() will follow the symlink let no_slash: &Path = OsStr::from_bytes(&bytes[..bytes.len() - 1]).as_ref(); - if is_symlink(no_slash).unwrap_or(false) - && points_to_directory(no_slash).unwrap_or(true) - { + if is_symlink(no_slash) && points_to_directory(no_slash).unwrap_or(true) { show_error!( "failed to remove {}: Symbolic link not followed", path.quote() diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index 764015f5f..8fc89ec82 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" path = "src/touch.rs" [dependencies] -filetime = "0.2.1" +filetime = "0.2.17" clap = { version = "3.1", features = ["wrap_help", "cargo"] } time = { version = "0.3", features = ["parsing", "formatting", "local-offset", "macros"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["libc"] } diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs index 3963d865c..fe8726575 100644 --- a/src/uucore/src/lib/features/fs.rs +++ b/src/uucore/src/lib/features/fs.rs @@ -8,6 +8,8 @@ //! Set of functions to manage files and symlinks +// spell-checker:ignore backport + #[cfg(unix)] use libc::{ mode_t, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK, S_IRGRP, @@ -221,6 +223,16 @@ pub fn normalize_path(path: &Path) -> PathBuf { ret } +/// Decide whether the given path is a symbolic link. +/// +/// This function is essentially a backport of the +/// [`std::path::Path::is_symlink`] function that exists in Rust +/// version 1.58 and greater. This can be removed when the minimum +/// supported version of Rust is 1.58. +pub fn is_symlink>(path: P) -> bool { + fs::symlink_metadata(path).map_or(false, |m| m.file_type().is_symlink()) +} + fn resolve>(original: P) -> Result { const MAX_LINKS_FOLLOWED: u32 = 255; let mut followed = 0; diff --git a/src/uucore/src/lib/features/perms.rs b/src/uucore/src/lib/features/perms.rs index 4574ba96c..1d2fe04cf 100644 --- a/src/uucore/src/lib/features/perms.rs +++ b/src/uucore/src/lib/features/perms.rs @@ -10,7 +10,7 @@ use crate::error::strip_errno; use crate::error::UResult; use crate::error::USimpleError; pub use crate::features::entries; -use crate::fs::resolve_relative_path; +use crate::fs::{is_symlink, resolve_relative_path}; use crate::show_error; use clap::Arg; use clap::ArgMatches; @@ -274,12 +274,7 @@ impl ChownExecutor { let root = root.as_ref(); // walkdir always dereferences the root directory, so we have to check it ourselves - // TODO: replace with `root.is_symlink()` once it is stable - if self.traverse_symlinks == TraverseSymlinks::None - && std::fs::symlink_metadata(root) - .map(|m| m.file_type().is_symlink()) - .unwrap_or(false) - { + if self.traverse_symlinks == TraverseSymlinks::None && is_symlink(root) { return 0; }