mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 20:47:46 +00:00
Merge branch 'main' into cp-preserve-perm-link
This commit is contained in:
commit
334a0c13ba
9 changed files with 35 additions and 43 deletions
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -618,9 +618,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossterm"
|
name = "crossterm"
|
||||||
version = "0.23.2"
|
version = "0.24.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17"
|
checksum = "ab9f7409c70a38a56216480fba371ee460207dd8926ccf5b4160591759559170"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"crossterm_winapi",
|
"crossterm_winapi",
|
||||||
|
@ -802,14 +802,14 @@ checksum = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.16"
|
version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c"
|
checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"winapi 0.3.9",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1286,9 +1286,9 @@ checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "onig"
|
name = "onig"
|
||||||
version = "6.3.1"
|
version = "6.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "67ddfe2c93bb389eea6e6d713306880c7f6dcc99a75b659ce145d962c861b225"
|
checksum = "1eb3502504c9c8b06634b38bfdda86a9a8cef6277f3dec4d8b17c115110dd2a3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -1298,9 +1298,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "onig_sys"
|
name = "onig_sys"
|
||||||
version = "69.7.1"
|
version = "69.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5dd3eee045c84695b53b20255bb7317063df090b68e18bfac0abb6c39cf7f33e"
|
checksum = "8bf3fbc9b931b6c9af85d219c7943c274a6ad26cff7488a2210215edd5f49bf8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
|
|
|
@ -14,6 +14,7 @@ use std::path::Path;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{ExitCode, UResult, USimpleError, UUsageError};
|
use uucore::error::{ExitCode, UResult, USimpleError, UUsageError};
|
||||||
use uucore::fs::display_permissions_unix;
|
use uucore::fs::display_permissions_unix;
|
||||||
|
use uucore::fs::is_symlink;
|
||||||
use uucore::libc::mode_t;
|
use uucore::libc::mode_t;
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use uucore::mode;
|
use uucore::mode;
|
||||||
|
@ -380,10 +381,3 @@ impl Chmoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_symlink<P: AsRef<Path>>(path: P) -> bool {
|
|
||||||
match fs::symlink_metadata(path) {
|
|
||||||
Ok(m) => m.file_type().is_symlink(),
|
|
||||||
Err(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ use std::str::FromStr;
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
use uucore::backup_control::{self, BackupMode};
|
use uucore::backup_control::{self, BackupMode};
|
||||||
use uucore::error::{set_exit_code, ExitCode, UClapError, UError, UResult};
|
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;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
quick_error! {
|
quick_error! {
|
||||||
|
@ -1075,7 +1075,7 @@ fn copy_directory(
|
||||||
};
|
};
|
||||||
|
|
||||||
let local_to_target = target.join(&local_to_root_parent);
|
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)?;
|
copy_link(&path, &local_to_target, symlinked_files)?;
|
||||||
} else if path.is_dir() && !local_to_target.exists() {
|
} else if path.is_dir() && !local_to_target.exists() {
|
||||||
if target.is_file() {
|
if target.is_file() {
|
||||||
|
@ -1097,7 +1097,7 @@ fn copy_directory(
|
||||||
) {
|
) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if is_symlink(&source) {
|
if is_symlink(source) {
|
||||||
// silent the error with a symlink
|
// silent the error with a symlink
|
||||||
// In case we do --archive, we might copy the symlink
|
// In case we do --archive, we might copy the symlink
|
||||||
// before the file itself
|
// before the file itself
|
||||||
|
|
|
@ -14,6 +14,7 @@ use clap::{crate_version, Arg, Command};
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{UError, UResult};
|
use uucore::error::{UError, UResult};
|
||||||
use uucore::format_usage;
|
use uucore::format_usage;
|
||||||
|
use uucore::fs::is_symlink;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
@ -533,10 +534,3 @@ pub fn symlink<P1: AsRef<Path>, P2: AsRef<Path>>(src: P1, dst: P2) -> Result<()>
|
||||||
symlink_file(src, dst)
|
symlink_file(src, dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_symlink<P: AsRef<Path>>(path: P) -> bool {
|
|
||||||
match fs::symlink_metadata(path) {
|
|
||||||
Ok(m) => m.file_type().is_symlink(),
|
|
||||||
Err(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -211,7 +211,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::FIELD)
|
Arg::new(options::FIELD)
|
||||||
.long(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")
|
.value_name("FIELDS")
|
||||||
.default_value(options::FIELD_DEFAULT),
|
.default_value(options::FIELD_DEFAULT),
|
||||||
)
|
)
|
||||||
|
@ -256,7 +256,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||||
.long(options::ROUND)
|
.long(options::ROUND)
|
||||||
.help(
|
.help(
|
||||||
"use METHOD for rounding when scaling; METHOD can be: up,\
|
"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")
|
.value_name("METHOD")
|
||||||
.default_value("from-zero")
|
.default_value("from-zero")
|
||||||
|
|
|
@ -16,6 +16,9 @@ use std::io;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{set_exit_code, strip_errno, UResult};
|
use uucore::error::{set_exit_code, strip_errno, UResult};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
use uucore::fs::is_symlink;
|
||||||
use uucore::{format_usage, util_name};
|
use uucore::{format_usage, util_name};
|
||||||
|
|
||||||
static ABOUT: &str = "Remove the DIRECTORY(ies), if they are empty.";
|
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::ffi::OsStr;
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
fn is_symlink(path: &Path) -> io::Result<bool> {
|
|
||||||
Ok(path.symlink_metadata()?.file_type().is_symlink())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn points_to_directory(path: &Path) -> io::Result<bool> {
|
fn points_to_directory(path: &Path) -> io::Result<bool> {
|
||||||
Ok(path.metadata()?.file_type().is_dir())
|
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"/") {
|
if error.raw_os_error() == Some(libc::ENOTDIR) && bytes.ends_with(b"/") {
|
||||||
// Strip the trailing slash or .symlink_metadata() will follow the symlink
|
// Strip the trailing slash or .symlink_metadata() will follow the symlink
|
||||||
let no_slash: &Path = OsStr::from_bytes(&bytes[..bytes.len() - 1]).as_ref();
|
let no_slash: &Path = OsStr::from_bytes(&bytes[..bytes.len() - 1]).as_ref();
|
||||||
if is_symlink(no_slash).unwrap_or(false)
|
if is_symlink(no_slash) && points_to_directory(no_slash).unwrap_or(true) {
|
||||||
&& points_to_directory(no_slash).unwrap_or(true)
|
|
||||||
{
|
|
||||||
show_error!(
|
show_error!(
|
||||||
"failed to remove {}: Symbolic link not followed",
|
"failed to remove {}: Symbolic link not followed",
|
||||||
path.quote()
|
path.quote()
|
||||||
|
|
|
@ -15,7 +15,7 @@ edition = "2021"
|
||||||
path = "src/touch.rs"
|
path = "src/touch.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
filetime = "0.2.1"
|
filetime = "0.2.17"
|
||||||
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
|
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
|
||||||
time = { version = "0.3", features = ["parsing", "formatting", "local-offset", "macros"] }
|
time = { version = "0.3", features = ["parsing", "formatting", "local-offset", "macros"] }
|
||||||
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["libc"] }
|
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["libc"] }
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
//! Set of functions to manage files and symlinks
|
//! Set of functions to manage files and symlinks
|
||||||
|
|
||||||
|
// spell-checker:ignore backport
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use libc::{
|
use libc::{
|
||||||
mode_t, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK, S_IRGRP,
|
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
|
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<P: AsRef<Path>>(path: P) -> bool {
|
||||||
|
fs::symlink_metadata(path).map_or(false, |m| m.file_type().is_symlink())
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve<P: AsRef<Path>>(original: P) -> Result<PathBuf, (bool, PathBuf, IOError)> {
|
fn resolve<P: AsRef<Path>>(original: P) -> Result<PathBuf, (bool, PathBuf, IOError)> {
|
||||||
const MAX_LINKS_FOLLOWED: u32 = 255;
|
const MAX_LINKS_FOLLOWED: u32 = 255;
|
||||||
let mut followed = 0;
|
let mut followed = 0;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::error::strip_errno;
|
||||||
use crate::error::UResult;
|
use crate::error::UResult;
|
||||||
use crate::error::USimpleError;
|
use crate::error::USimpleError;
|
||||||
pub use crate::features::entries;
|
pub use crate::features::entries;
|
||||||
use crate::fs::resolve_relative_path;
|
use crate::fs::{is_symlink, resolve_relative_path};
|
||||||
use crate::show_error;
|
use crate::show_error;
|
||||||
use clap::Arg;
|
use clap::Arg;
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
|
@ -274,12 +274,7 @@ impl ChownExecutor {
|
||||||
let root = root.as_ref();
|
let root = root.as_ref();
|
||||||
|
|
||||||
// walkdir always dereferences the root directory, so we have to check it ourselves
|
// 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 && is_symlink(root) {
|
||||||
if self.traverse_symlinks == TraverseSymlinks::None
|
|
||||||
&& std::fs::symlink_metadata(root)
|
|
||||||
.map(|m| m.file_type().is_symlink())
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue