1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

tail: fix handling of PermissionDenied Error

* add tests for opening unreadable files
This commit is contained in:
Jan Scheer 2022-05-26 12:53:50 +02:00
parent 6bd9a1d537
commit 4bbf708c81
No known key found for this signature in database
GPG key ID: C62AD4C29E2B9828
2 changed files with 86 additions and 32 deletions

View file

@ -383,30 +383,46 @@ fn uu_tail(mut settings: Settings) -> UResult<()> {
} }
} }
} else if path.is_tailable() { } else if path.is_tailable() {
if settings.verbose { match File::open(&path) {
files.print_header(&path, !first_header); Ok(mut file) => {
first_header = false; if settings.verbose {
} files.print_header(&path, !first_header);
let mut file = File::open(&path).unwrap(); first_header = false;
let mut reader; }
let mut reader;
if is_seekable(&mut file) && get_block_size(md.as_ref().unwrap()) > 0 { if is_seekable(&mut file) && get_block_size(md.as_ref().unwrap()) > 0 {
bounded_tail(&mut file, &settings); bounded_tail(&mut file, &settings);
reader = BufReader::new(file); reader = BufReader::new(file);
} else { } else {
reader = BufReader::new(file); reader = BufReader::new(file);
unbounded_tail(&mut reader, &settings)?; unbounded_tail(&mut reader, &settings)?;
} }
if settings.follow.is_some() { if settings.follow.is_some() {
// Insert existing/file `path` into `files.map`. // Insert existing/file `path` into `files.map`.
files.insert( files.insert(
path.canonicalize().unwrap(), path.canonicalize().unwrap(),
PathData { PathData {
reader: Some(Box::new(reader)), reader: Some(Box::new(reader)),
metadata: md, metadata: md,
display_name, display_name,
}, },
); );
}
}
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {
settings.return_code = 1;
show_error!(
"cannot open {} for reading: Permission denied",
display_name.quote()
);
}
Err(e) => {
return Err(USimpleError::new(
1,
format!("{}: {}", display_name.quote(), e),
));
}
} }
} else if settings.retry && settings.follow.is_some() { } else if settings.retry && settings.follow.is_some() {
if path.is_relative() { if path.is_relative() {
@ -931,15 +947,13 @@ fn handle_event(
); );
} }
} }
if event_path.is_orphan() { if event_path.is_orphan() && !orphans.contains(event_path) {
if !orphans.contains(event_path) { show_error!("directory containing watched file was removed");
show_error!("directory containing watched file was removed"); show_error!(
show_error!( "{} cannot be used, reverting to polling",
"{} cannot be used, reverting to polling", text::BACKEND
text::BACKEND );
); orphans.push(event_path.to_path_buf());
orphans.push(event_path.to_path_buf());
}
} }
let _ = watcher.unwatch(event_path); let _ = watcher.unwatch(event_path);
} else { } else {

View file

@ -97,6 +97,46 @@ fn test_stdin_redirect_file() {
assert!(buf_stderr.is_empty()); assert!(buf_stderr.is_empty());
} }
#[test]
#[cfg(not(target_os = "windows"))]
#[cfg(feature = "chmod")]
fn test_permission_denied() {
let ts = TestScenario::new(util_name!());
let at = &ts.fixtures;
at.touch("unreadable");
ts.ccmd("chmod").arg("0").arg("unreadable").succeeds();
ts.ucmd()
.set_stdin(Stdio::null())
.arg("unreadable")
.fails()
.stderr_is("tail: cannot open 'unreadable' for reading: Permission denied\n")
.no_stdout()
.code_is(1);
}
#[test]
#[cfg(not(target_os = "windows"))]
#[cfg(feature = "chmod")]
fn test_permission_denied_multiple() {
let ts = TestScenario::new(util_name!());
let at = &ts.fixtures;
at.touch("file1");
at.touch("file2");
at.touch("unreadable");
ts.ccmd("chmod").arg("0").arg("unreadable").succeeds();
ts.ucmd()
.set_stdin(Stdio::null())
.args(&["file1", "unreadable", "file2"])
.fails()
.stderr_is("tail: cannot open 'unreadable' for reading: Permission denied\n")
.stdout_is("==> file1 <==\n\n==> file2 <==\n")
.code_is(1);
}
#[test] #[test]
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn test_follow_redirect_stdin_name_retry() { fn test_follow_redirect_stdin_name_retry() {