Forward some error messages and fix a bug

- The Err-variants will be used by e.g. wildcard, so might as well change it
  now.
- `create_directory` should now not infinitely loop until  it fails with an
  error message that isn't `EAGAIN`
This commit is contained in:
Henrik Hørlück Berg 2023-07-29 13:37:33 +02:00 committed by Peter Ammon
parent f4a5de1fbf
commit 4a4171c34a
4 changed files with 23 additions and 33 deletions

View File

@ -797,9 +797,9 @@ fn filter_path(opts: &Options, path: &wstr) -> bool {
let mut type_ok = false;
if t.contains(TypeFlags::LINK) {
let md = lwstat(path);
type_ok = md.is_some() && md.unwrap().is_symlink();
type_ok = md.is_ok() && md.unwrap().is_symlink();
}
let Some(md) = wstat(path) else {
let Ok(md) = wstat(path) else {
// Does not exist
return false;
};
@ -850,9 +850,8 @@ fn filter_path(opts: &Options, path: &wstr) -> bool {
}
// Permissions that require special handling
if perm.is_special() {
let Some(md) = wstat(path) else {
let Ok(md) = wstat(path) else {
// Does not exist, even though we just checked we can access it
// likely some kind of race condition
// We might want to warn the user about this?

View File

@ -653,7 +653,7 @@ impl IoChain {
let mut dname: &wstr = &spec.target;
while !dname.is_empty() {
let next: &wstr = wdirname(dname);
if let Some(md) = wstat(next) {
if let Ok(md) = wstat(next) {
if !md.is_dir() {
FLOGF!(
warning,

View File

@ -13,10 +13,10 @@ use crate::wutil::{
normalize_path, path_normalize_for_cd, waccess, wdirname, wgettext, wgettext_fmt, wmkdir, wstat,
};
use errno::{errno, set_errno, Errno};
use libc::{EACCES, EAGAIN, ENOENT, ENOTDIR, F_OK, X_OK};
use libc::{EACCES, ENOENT, ENOTDIR, F_OK, X_OK};
use once_cell::sync::Lazy;
use std::ffi::OsStr;
use std::io::Write;
use std::io::{ErrorKind, Write};
use std::os::unix::ffi::OsStrExt;
use std::os::unix::prelude::MetadataExt;
use widestring_suffix::widestrs;
@ -342,7 +342,7 @@ pub fn path_get_cdpath(dir: &wstr, wd: &wstr, vars: &dyn Environment) -> Option<
let paths = path_apply_cdpath(dir, wd, vars);
for a_dir in paths {
if let Some(md) = wstat(&a_dir) {
if let Ok(md) = wstat(&a_dir) {
if md.is_dir() {
return Some(a_dir);
}
@ -520,7 +520,7 @@ pub fn paths_are_same_file(path1: &wstr, path2: &wstr) -> bool {
}
match (wstat(path1), wstat(path2)) {
(Some(s1), Some(s2)) => s1.ino() == s2.ino() && s1.dev() == s2.dev(),
(Ok(s1), Ok(s2)) => s1.ino() == s2.ino() && s1.dev() == s2.dev(),
_ => false,
}
}
@ -627,29 +627,20 @@ fn make_base_directory(xdg_var: &wstr, non_xdg_homepath: &wstr) -> BaseDirectory
///
/// \return 0 if, at the time of function return the directory exists, -1 otherwise.
fn create_directory(d: &wstr) -> bool {
let mut md;
loop {
md = wstat(d);
if md.is_none() && errno().0 != EAGAIN {
break;
let md = loop {
match wstat(d) {
Err(md) if md.kind() == ErrorKind::Interrupted => continue,
md => break md,
}
}
};
match md {
Some(md) => {
if md.is_dir() {
return true;
}
}
None => {
if errno().0 == ENOENT {
let dir: &wstr = wdirname(d);
if create_directory(dir) && wmkdir(d, 0o700) == 0 {
return true;
}
}
Ok(md) if md.is_dir() => true,
Err(e) if e.kind() == ErrorKind::NotFound => {
let dir: &wstr = wdirname(d);
return create_directory(dir) && wmkdir(d, 0o700) == 0;
}
_ => false,
}
false
}
/// \return whether the given path is on a remote filesystem.

View File

@ -37,15 +37,15 @@ pub fn wopendir(name: &wstr) -> *mut libc::DIR {
}
/// Wide character version of stat().
pub fn wstat(file_name: &wstr) -> Option<fs::Metadata> {
pub fn wstat(file_name: &wstr) -> io::Result<fs::Metadata> {
let tmp = wcs2osstring(file_name);
fs::metadata(tmp).ok()
fs::metadata(tmp)
}
/// Wide character version of lstat().
pub fn lwstat(file_name: &wstr) -> Option<fs::Metadata> {
pub fn lwstat(file_name: &wstr) -> io::Result<fs::Metadata> {
let tmp = wcs2osstring(file_name);
fs::symlink_metadata(tmp).ok()
fs::symlink_metadata(tmp)
}
/// Wide character version of access().
@ -109,7 +109,7 @@ pub fn wgetcwd() -> WString {
/// Wide character version of readlink().
pub fn wreadlink(file_name: &wstr) -> Option<WString> {
let md = lwstat(file_name)?;
let md = lwstat(file_name).ok()?;
let bufsize = usize::try_from(md.len()).unwrap() + 1;
let mut target_buf = vec![b'\0'; bufsize];
let tmp = wcs2zstring(file_name);