1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

Merge pull request #6506 from Its-Just-Nans/touch-directory

`touch`: change message when directory
This commit is contained in:
Sylvestre Ledru 2024-06-30 20:54:48 +02:00 committed by GitHub
commit 9013265e47
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 32 additions and 2 deletions

View file

@ -15,6 +15,7 @@ use clap::{crate_version, Arg, ArgAction, ArgGroup, ArgMatches, Command};
use filetime::{set_file_times, set_symlink_file_times, FileTime};
use std::ffi::OsString;
use std::fs::{self, File};
use std::io::{Error, ErrorKind};
use std::path::{Path, PathBuf};
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError};
@ -126,7 +127,23 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
if let Err(e) = File::create(path) {
show!(e.map_err_context(|| format!("cannot touch {}", path.quote())));
// we need to check if the path is the path to a directory (ends with a separator)
// we can't use File::create to create a directory
// we cannot use path.is_dir() because it calls fs::metadata which we already called
// when stable, we can change to use e.kind() == std::io::ErrorKind::IsADirectory
let is_directory = if let Some(last_char) = path.to_string_lossy().chars().last() {
last_char == std::path::MAIN_SEPARATOR
} else {
false
};
if is_directory {
let custom_err = Error::new(ErrorKind::Other, "No such file or directory");
return Err(
custom_err.map_err_context(|| format!("cannot touch {}", filename.quote()))
);
} else {
show!(e.map_err_context(|| format!("cannot touch {}", path.quote())));
}
continue;
};

View file

@ -689,10 +689,23 @@ fn test_touch_system_fails() {
}
#[test]
#[cfg(not(target_os = "windows"))]
fn test_touch_trailing_slash() {
let (_at, mut ucmd) = at_and_ucmd!();
let file = "no-file/";
ucmd.args(&[file]).fails();
ucmd.args(&[file]).fails().stderr_only(format!(
"touch: cannot touch '{file}': No such file or directory\n"
));
}
#[test]
#[cfg(target_os = "windows")]
fn test_touch_trailing_slash_windows() {
let (_at, mut ucmd) = at_and_ucmd!();
let file = "no-file/";
ucmd.args(&[file]).fails().stderr_only(format!(
"touch: cannot touch '{file}': The filename, directory name, or volume label syntax is incorrect.\n"
));
}
#[test]