mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
sync: Verify that the files can be opened
This commit is contained in:
parent
fc1c7755b9
commit
6edf8ebf41
4 changed files with 73 additions and 5 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2834,6 +2834,7 @@ version = "0.0.15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"libc",
|
"libc",
|
||||||
|
"nix",
|
||||||
"uucore",
|
"uucore",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
|
@ -19,6 +19,9 @@ clap = { version = "3.2", features = ["wrap_help", "cargo"] }
|
||||||
libc = "0.2.132"
|
libc = "0.2.132"
|
||||||
uucore = { version=">=0.0.15", package="uucore", path="../../uucore", features=["wide"] }
|
uucore = { version=">=0.0.15", package="uucore", path="../../uucore", features=["wide"] }
|
||||||
|
|
||||||
|
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
|
||||||
|
nix = "0.25"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["errhandlingapi", "fileapi", "handleapi", "std", "winbase", "winerror"] }
|
winapi = { version = "0.3", features = ["errhandlingapi", "fileapi", "handleapi", "std", "winbase", "winerror"] }
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,12 @@
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
use clap::{crate_version, Arg, Command};
|
use clap::{crate_version, Arg, Command};
|
||||||
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
|
use nix::errno::Errno;
|
||||||
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
|
use nix::fcntl::{open, OFlag};
|
||||||
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
|
use nix::sys::stat::Mode;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{UResult, USimpleError};
|
use uucore::error::{UResult, USimpleError};
|
||||||
|
@ -174,11 +180,40 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for f in &files {
|
for f in &files {
|
||||||
if !Path::new(&f).exists() {
|
// Use the Nix open to be able to set the NONBLOCK flags for fifo files
|
||||||
return Err(USimpleError::new(
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
1,
|
{
|
||||||
format!("cannot stat {}: No such file or directory", f.quote()),
|
match open(Path::new(&f), OFlag::O_NONBLOCK, Mode::empty()) {
|
||||||
));
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
if e == Errno::ENOENT {
|
||||||
|
return Err(USimpleError::new(
|
||||||
|
1,
|
||||||
|
format!("cannot stat {}: No such file or directory", f.quote()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if e == Errno::EACCES {
|
||||||
|
if Path::new(&f).is_dir() {
|
||||||
|
return Err(USimpleError::new(
|
||||||
|
1,
|
||||||
|
format!("error opening {}: Permission denied", f.quote()),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
// ignore the issue
|
||||||
|
// ./target/debug/coreutils sync --data file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||||
|
{
|
||||||
|
if !Path::new(&f).exists() {
|
||||||
|
return Err(USimpleError::new(
|
||||||
|
1,
|
||||||
|
format!("cannot stat {}: No such file or directory", f.quote()),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,3 +52,32 @@ fn test_sync_data_but_not_file() {
|
||||||
.fails()
|
.fails()
|
||||||
.stderr_contains("sync: --data needs at least one argument");
|
.stderr_contains("sync: --data needs at least one argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
|
#[cfg(feature = "chmod")]
|
||||||
|
#[test]
|
||||||
|
fn test_sync_no_permission_dir() {
|
||||||
|
let ts = TestScenario::new(util_name!());
|
||||||
|
let at = &ts.fixtures;
|
||||||
|
let dir = "foo";
|
||||||
|
at.mkdir_all(dir);
|
||||||
|
|
||||||
|
ts.ccmd("chmod").arg("0").arg(dir).succeeds();
|
||||||
|
let result = ts.ucmd().arg("--data").arg(dir).fails();
|
||||||
|
result.stderr_contains("sync: error opening 'foo': Permission denied");
|
||||||
|
let result = ts.ucmd().arg(dir).fails();
|
||||||
|
result.stderr_contains("sync: error opening 'foo': Permission denied");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
#[cfg(feature = "chmod")]
|
||||||
|
#[test]
|
||||||
|
fn test_sync_no_permission_file() {
|
||||||
|
let ts = TestScenario::new(util_name!());
|
||||||
|
let at = &ts.fixtures;
|
||||||
|
let f = "file";
|
||||||
|
at.touch(f);
|
||||||
|
|
||||||
|
ts.ccmd("chmod").arg("0200").arg(f).succeeds();
|
||||||
|
ts.ucmd().arg(f).succeeds();
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue