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

Use dir_entry metadata for dereferenced bad fds to match GNU, add comments, clippy lints

This commit is contained in:
electricboogie 2022-01-16 10:20:50 -06:00
parent 37ca6edfdc
commit 15efba54c5
3 changed files with 44 additions and 33 deletions

View file

@ -83,7 +83,7 @@ pub fn main() {
mf.write_all( mf.write_all(
format!( format!(
"\tmap.insert(\"{k}\", ({krate}::uumain, {krate}::uu_app));\n", "\tmap.insert(\"{k}\", ({krate}::uumain, {krate}::uu_app));\n",
k = krate[override_prefix.len()..].to_string(), k = krate[override_prefix.len()..].to_owned(),
krate = krate krate = krate
) )
.as_bytes(), .as_bytes(),
@ -92,7 +92,7 @@ pub fn main() {
tf.write_all( tf.write_all(
format!( format!(
"#[path=\"{dir}/test_{k}.rs\"]\nmod test_{k};\n", "#[path=\"{dir}/test_{k}.rs\"]\nmod test_{k};\n",
k = krate[override_prefix.len()..].to_string(), k = krate[override_prefix.len()..].to_owned(),
dir = util_tests_dir, dir = util_tests_dir,
) )
.as_bytes(), .as_bytes(),

View file

@ -207,9 +207,10 @@ impl Display for LsError {
} }
_ => match errno { _ => match errno {
9i32 => { 9i32 => {
// only should ever occur on a read_dir on a bad fd
write!( write!(
f, f,
"cannot access '{}': Bad file descriptor", "cannot open directory '{}': Bad file descriptor",
p.to_string_lossy(), p.to_string_lossy(),
) )
} }
@ -1354,18 +1355,24 @@ impl PathData {
Err(err) => { Err(err) => {
let _ = out.flush(); let _ = out.flush();
let errno = err.raw_os_error().unwrap_or(1i32); let errno = err.raw_os_error().unwrap_or(1i32);
// Wait to enter "directory" to print error for a bad fd // Wait to enter "directory" to print error for any bad fd
if self.must_dereference && errno.eq(&9i32) { if self.must_dereference && errno.eq(&9i32) {
if let Ok(md) = get_metadata(&self.p_buf, false) { if let Some(parent) = self.p_buf.parent() {
Some(md) if let Ok(read_dir) = fs::read_dir(parent) {
} else { // this dir_entry metadata is different from the metadata call on the path
show!(LsError::IOErrorContext(err, self.p_buf.clone(),)); let res = read_dir
None .filter_map(|x| x.ok())
.filter(|x| self.p_buf.eq(&x.path()))
.filter_map(|x| x.metadata().ok())
.next();
if let Some(md) = res {
return Some(md);
}
}
} }
} else {
show!(LsError::IOErrorContext(err, self.p_buf.clone(),));
None
} }
show!(LsError::IOErrorContext(err, self.p_buf.clone(),));
None
} }
Ok(md) => Some(md), Ok(md) => Some(md),
}, },
@ -1565,7 +1572,8 @@ fn enter_directory(
let res = PathData::new(dir_entry.path(), Some(Ok(ft)), None, config, false); let res = PathData::new(dir_entry.path(), Some(Ok(ft)), None, config, false);
// metadata returned from a DirEntry matches GNU metadata for // metadata returned from a DirEntry matches GNU metadata for
// non-dereferenced files, and is *different* from the // non-dereferenced files, and is *different* from the
// metadata call on the path, see, for example, bad fds // metadata call on the path, see, for example, bad fds,
// so we use here when we will need metadata later anyway
if !res.must_dereference if !res.must_dereference
&& ((config.format == Format::Long) && ((config.format == Format::Long)
|| (config.sort == Sort::Name) || (config.sort == Sort::Name)

View file

@ -170,7 +170,7 @@ fn test_ls_io_errors() {
.stderr_contains("Permission denied") .stderr_contains("Permission denied")
.stdout_contains("some-dir4"); .stdout_contains("some-dir4");
// test we don't double print on dangling link metadata errors // don't double print on dangling link metadata errors
scene scene
.ucmd() .ucmd()
.arg("-iRL") .arg("-iRL")
@ -188,26 +188,29 @@ fn test_ls_io_errors() {
let rv1 = dup2(fd1, fd2); let rv1 = dup2(fd1, fd2);
let rv2 = close(fd1); let rv2 = close(fd1);
scene // dup and close work on the mac, but doesn't work in some linux containers
.ucmd() // so check to see that return values are non-error before proceeding
.arg("-alR") if rv1.is_ok() && rv2.is_ok() {
.arg(format!("/dev/fd/{}", fd2)) scene
.fails() .ucmd()
.stderr_contains(format!( .arg("-alR")
"cannot access '/dev/fd/{}': Bad file descriptor", .arg(format!("/dev/fd/{}", fd = fd2))
fd2 .fails()
)) .stderr_contains(format!(
.stdout_does_not_contain(format!("{}:\n", fd2)); "cannot open directory '/dev/fd/{fd}': Bad file descriptor",
fd = fd2
scene ))
.ucmd() .stdout_does_not_contain(format!("{fd}:\n", fd = fd2));
.arg("-RiL")
.arg(format!("/dev/fd/{}", fd2))
.fails()
.stderr_contains(format!("cannot access '/dev/fd/{}': Bad file descriptor", fd2))
// test we only print bad fd error once
.stderr_does_not_contain(format!("ls: cannot access '/dev/fd/{fd}': Bad file descriptor\nls: cannot access '/dev/fd/{fd}': Bad file descriptor", fd = fd2));
scene
.ucmd()
.arg("-RiL")
.arg(format!("/dev/fd/{fd}", fd = fd2))
.fails()
.stderr_contains(format!("cannot open directory '/dev/fd/{fd}': Bad file descriptor", fd = fd2))
// don't double print bad fd errors
.stderr_does_not_contain(format!("ls: cannot open directory '/dev/fd/{fd}': Bad file descriptor\nls: cannot open directory '/dev/fd/{fd}': Bad file descriptor", fd = fd2));
}
let _ = close(fd2); let _ = close(fd2);
} }
} }