mirror of
https://github.com/uutils/coreutils
synced 2024-07-23 19:04:18 +00:00
sync: Verify that the files can be opened
This commit is contained in:
parent
fc1c7755b9
commit
6edf8ebf41
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2834,6 +2834,7 @@ version = "0.0.15"
|
|||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
"nix",
|
||||
"uucore",
|
||||
"winapi",
|
||||
]
|
||||
|
|
|
@ -19,6 +19,9 @@ clap = { version = "3.2", features = ["wrap_help", "cargo"] }
|
|||
libc = "0.2.132"
|
||||
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]
|
||||
winapi = { version = "0.3", features = ["errhandlingapi", "fileapi", "handleapi", "std", "winbase", "winerror"] }
|
||||
|
||||
|
|
|
@ -10,6 +10,12 @@
|
|||
extern crate libc;
|
||||
|
||||
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 uucore::display::Quotable;
|
||||
use uucore::error::{UResult, USimpleError};
|
||||
|
@ -174,11 +180,40 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
}
|
||||
|
||||
for f in &files {
|
||||
if !Path::new(&f).exists() {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("cannot stat {}: No such file or directory", f.quote()),
|
||||
));
|
||||
// Use the Nix open to be able to set the NONBLOCK flags for fifo files
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
{
|
||||
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()
|
||||
.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…
Reference in a new issue