Skip to content

Commit bc18887

Browse files
committed
touch: use UIoError to report error causes and try to accommodate macos.
1 parent 6027636 commit bc18887

File tree

1 file changed

+14
-27
lines changed

1 file changed

+14
-27
lines changed

src/uu/touch/src/touch.rs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ use std::io::ErrorKind;
2424
use std::os::unix::fs::OpenOptionsExt;
2525
use std::path::{Path, PathBuf};
2626
use uucore::display::Quotable;
27-
use uucore::error::{FromIo, UResult, USimpleError};
27+
use uucore::error::{FromIo, UIoError, UResult, USimpleError};
2828
use uucore::format_usage;
29-
#[cfg(unix)]
29+
#[cfg(any(unix, target_os = "macos"))]
3030
use uucore::libc;
3131
use uucore::parser::shortcut_value_parser::ShortcutValueParser;
3232
use uucore::{show, translate};
@@ -482,38 +482,25 @@ fn touch_file(
482482
.open(path);
483483

484484
if let Err(e) = touched_file {
485-
// It's better to take the negative approach here, but there's an issue with
486-
// Rust's standard library when it comes to mapping certain OS errors to ErrorKind.
487-
// Those map to ErrorKind::Uncategorized, which is currently marked 'unstable'.
488-
// So, as a work-around, we look at raw_os_error for libc::ENXIO (6) directly on unix systems.
489-
// We always ignore IsADirectory since directories are fair game to be touched.
490-
#[cfg(unix)]
485+
// We have to check to see if the reason .open() failed above is something
486+
// that is fatal or something expected. The former is handled here, whereas
487+
// the latter is handled in update_times().
488+
let err_good_cause = e.kind() != ErrorKind::IsADirectory;
489+
490+
// For UNIX/MAC, we also have to check special files, like FIFOs.
491491
// If we can't unwrap a raw OS error, default it to 0 so that it's considered true
492492
// for the first Boolean condition.
493-
let err_good_cause =
494-
e.raw_os_error().unwrap_or(0) != libc::ENXIO && e.kind() != ErrorKind::IsADirectory;
495-
496-
#[cfg(not(unix))]
497-
let err_good_cause = e.kind() != ErrorKind::IsADirectory;
493+
#[cfg(any(unix, target_os = "macos"))]
494+
let err_good_cause = e.raw_os_error().unwrap_or(0) != libc::ENXIO && err_good_cause;
498495

499-
// Any errors that make it here are considered errors of file creation/opening, otherwise
500-
// we let update_times() handle them.
496+
// err_good_cause indicates that the error is not one we should ignore
501497
if err_good_cause {
502-
// Rust's e.kind().to_string() doesn't always give good descriptions for certain errors.
503-
let err_str: String = match e.kind() {
504-
ErrorKind::NotFound => "No such file or directory".to_string(),
505-
ErrorKind::TooManyLinks => "Too many links".to_string(),
506-
ErrorKind::PermissionDenied => "Permission denied".to_string(),
507-
ErrorKind::QuotaExceeded => "Quota exceeded".to_string(),
508-
ErrorKind::ReadOnlyFilesystem => "Read only file system".to_string(),
509-
_ => e.to_string(),
510-
};
511498
return Err(TouchError::TouchFileError {
512499
path: path.to_owned(),
513500
index: 0,
514501
error: USimpleError::new(
515502
1,
516-
translate!("touch-error-cannot-touch", "filename" => path.quote(), "error" => err_str),
503+
translate!("touch-error-cannot-touch", "filename" => path.quote(), "error" => UIoError::from(e)),
517504
),
518505
}.into());
519506
}
@@ -597,14 +584,14 @@ fn update_times(
597584
// but since it was removed to fix TOCTOU issues, we need to handle it here.
598585
if let Err(ref e) = result {
599586
if opts.no_create && e.kind() != ErrorKind::NotADirectory {
600-
#[cfg(unix)]
587+
#[cfg(any(unix, target_os = "macos"))]
601588
if e.raw_os_error() != Some(libc::ELOOP) {
602589
// ELOOP is returned when trying to stat a dangling symlink with -h/--no-dereference.
603590
// However, the ErrorKind is unstable in Rust, so we have to kind
604591
// of hack it like this.
605592
return Ok(());
606593
}
607-
#[cfg(not(unix))]
594+
#[cfg(not(any(unix, target_os = "macos")))]
608595
return Ok(());
609596
}
610597
return result.map_err_context(

0 commit comments

Comments
 (0)