Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/uu/du/src/du.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,8 +642,7 @@ fn du_regular(

// Check symlink depth limit
if current_symlink_depth > MAX_SYMLINK_DEPTH {
print_tx.send(Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
print_tx.send(Err(std::io::Error::other(
"Too many levels of symbolic links",
).map_err_context(
|| translate!("du-error-cannot-access", "path" => entry_path.quote()),
Expand Down
3 changes: 1 addition & 2 deletions src/uu/mv/src/mv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,7 @@ fn parse_paths(files: &[OsString], opts: &Options) -> Vec<PathBuf> {
fn handle_two_paths(source: &Path, target: &Path, opts: &Options) -> UResult<()> {
// `mv` never follows a symlink source, so the guard must not either.
if backup_would_destroy_source(source, target, &opts.suffix, opts.backup, false) {
return Err(io::Error::new(
io::ErrorKind::NotFound,
return Err(io::Error::other(
translate!("mv-error-backup-might-destroy-source", "target" => target.quote(), "source" => source.quote()),
)
.into());
Expand Down
19 changes: 19 additions & 0 deletions src/uucore/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,25 @@ error-file-not-found = No such file or directory
error-invalid-argument = Invalid argument
error-is-a-directory = { $file }: Is a directory

uio-err-not-found = No such file or directory
uio-err-permission-denied = Permission denied
uio-err-conn-refused = Connection refused
uio-err-conn-reset = Connection reset
uio-err-conn-abort = Connection aborted
uio-err-not-connected = Not connected
uio-err-addr-in-use = Address in use
uio-err-addr-not-avail = Address not available
uio-err-broken-pipe = Broken pipe
uio-err-already-exists = Already exists
uio-err-would-block = Would block
uio-err-invalid-input = Invalid input
uio-err-invalid-data = Invalid data
uio-err-timed-out = Timed out
uio-err-write-zero = Write zero
uio-err-interrupted = Interrupted
uio-err-unexpected-eof = Unexpected end of file
uio-err-is-a-directory = Is a directory

# Common actions
action-copying = copying
action-moving = moving
Expand Down
19 changes: 19 additions & 0 deletions src/uucore/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,25 @@ error-file-not-found = Aucun fichier ou répertoire de ce type
error-invalid-argument = Argument invalide
error-is-a-directory = { $file }: Est un répertoire

uio-err-not-found = Aucun fichier ou répertoire de ce type
uio-err-permission-denied = Permission refusée
uio-err-conn-refused = Connexion refusée
uio-err-conn-reset = Connexion réinitialisée
uio-err-conn-abort = Connexion interrompue
uio-err-not-connected = Déconnecté
uio-err-addr-in-use = Address in use but in french
uio-err-addr-not-avail = Address indisponible
uio-err-broken-pipe = Broken pipe but in french
uio-err-already-exists = Already exists but in french
uio-err-would-block = Would block but in french
uio-err-invalid-input = Invalid input but in french
uio-err-invalid-data = Invalid data but in french
uio-err-timed-out = Timed out but in french
uio-err-write-zero = Write zero but in french
uio-err-interrupted = Interrupted but in french
uio-err-unexpected-eof = Unexpected end of file but in french
uio-err-is-a-directory = Est un répertoire

# Actions communes
action-copying = copie
action-moving = déplacement
Expand Down
14 changes: 4 additions & 10 deletions src/uucore/src/lib/features/checksum/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,20 +595,14 @@ fn get_input_file(filename: &OsStr) -> UResult<Box<dyn Read>> {
match File::open(filename) {
Ok(f) => {
if f.metadata()?.is_dir() {
Err(io::Error::other(
translate!("error-is-a-directory", "file" => filename.maybe_quote()),
)
.into())
Err(io::Error::from(io::ErrorKind::IsADirectory)
.map_err_context(|| filename.maybe_quote().to_string()))
} else {
Ok(Box::new(f))
}
}
Err(_) => Err(io::Error::other(format!(
"{}: {}",
filename.maybe_quote(),
translate!("error-file-not-found")
))
.into()),
Err(_) => Err(io::Error::from(io::ErrorKind::NotFound)
.map_err_context(|| filename.maybe_quote().to_string())),
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/uucore/src/lib/features/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::fs;
use std::fs::read_dir;
use std::hash::Hash;
use std::io::Stdin;
use std::io::{Error, ErrorKind, Result as IOResult};
use std::io::{Error, Result as IOResult};
#[cfg(any(unix, all(target_os = "wasi", target_env = "p2")))]
use std::os::fd::AsFd;
#[cfg(unix)]
Expand Down Expand Up @@ -435,10 +435,7 @@ pub fn canonicalize<P: AsRef<Path>>(
path_to_follow.push(part.as_os_str());
}
if !visited_files.insert((file_info, path_to_follow)) {
return Err(Error::new(
ErrorKind::InvalidInput,
"Too many levels of symbolic links",
)); // TODO use ErrorKind::FilesystemLoop when stable
return Err(Error::other("Too many levels of symbolic links")); // TODO use ErrorKind::FilesystemLoop when stable
}
}
result.pop();
Expand Down
68 changes: 29 additions & 39 deletions src/uucore/src/lib/mods/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ use std::{
sync::atomic::{AtomicI32, Ordering},
};

use crate::translate;

static EXIT_CODE: AtomicI32 = AtomicI32::new(0);

/// Get the last exit code set with [`set_exit_code`].
Expand Down Expand Up @@ -409,46 +411,34 @@ impl Display for UIoError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
use std::io::ErrorKind::*;

let message;
let message = if self.inner.raw_os_error().is_some() {
// These are errors that come directly from the OS.
// We want to normalize their messages across systems,
// and we want to strip the "(os error X)" suffix.
match self.inner.kind() {
NotFound => "No such file or directory",
PermissionDenied => "Permission denied",
ConnectionRefused => "Connection refused",
ConnectionReset => "Connection reset",
ConnectionAborted => "Connection aborted",
NotConnected => "Not connected",
AddrInUse => "Address in use",
AddrNotAvailable => "Address not available",
BrokenPipe => "Broken pipe",
AlreadyExists => "Already exists",
WouldBlock => "Would block",
InvalidInput => "Invalid input",
InvalidData => "Invalid data",
TimedOut => "Timed out",
WriteZero => "Write zero",
Interrupted => "Interrupted",
UnexpectedEof => "Unexpected end of file",
IsADirectory => "Is a directory",
_ => {
// TODO: When the new error variants
// (https://github.com/rust-lang/rust/issues/86442)
// are stabilized, we should add them to the match statement.
message = strip_errno(&self.inner);
&message
}
// These are errors that come directly from the OS.
// We want to normalize their messages across systems,
// and we want to strip the "(os error X)" suffix.
let message = match self.inner.kind() {
NotFound => translate!("uio-err-not-found"),
PermissionDenied => translate!("uio-err-permission-denied"),
ConnectionRefused => translate!("uio-err-conn-refused"),
ConnectionReset => translate!("uio-err-conn-reset"),
ConnectionAborted => translate!("uio-err-conn-abort"),
NotConnected => translate!("uio-err-not-connected"),
AddrInUse => translate!("uio-err-addr-in-use"),
AddrNotAvailable => translate!("uio-err-addr-not-avail"),
BrokenPipe => translate!("uio-err-broken-pipe"),
AlreadyExists => translate!("uio-err-already-exists"),
WouldBlock => translate!("uio-err-would-block"),
InvalidInput => translate!("uio-err-invalid-input"),
InvalidData => translate!("uio-err-invalid-data"),
TimedOut => translate!("uio-err-timed-out"),
WriteZero => translate!("uio-err-write-zero"),
Interrupted => translate!("uio-err-interrupted"),
UnexpectedEof => translate!("uio-err-unexpected-eof"),
IsADirectory => translate!("uio-err-is-a-directory"),
_ => {
// TODO: When the new error variants
// (https://github.com/rust-lang/rust/issues/86442)
// are stabilized, we should add them to the match statement.
strip_errno(&self.inner)
}
} else {
// These messages don't need as much normalization, and the above
// messages wouldn't always be a good substitute.
// For example, ErrorKind::NotFound doesn't necessarily mean it was
// a file that was not found.
// There are also errors with entirely custom messages.
message = self.inner.to_string();
&message
};
if let Some(ctx) = &self.context {
write!(f, "{ctx}: {message}")
Expand Down
2 changes: 1 addition & 1 deletion tests/by-util/test_cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4157,7 +4157,7 @@ fn test_copy_dir_preserve_permissions_inaccessible_file() {
// V V V V
ucmd.args(&["-p", "-R", "d1", "d2"])
.fails_with_code(1)
.stderr_only("cp: cannot open 'd1/f' for reading: permission denied\n");
.stderr_only("cp: cannot open 'd1/f' for reading: Permission denied\n");
assert!(at.dir_exists("d2"));
assert!(!at.file_exists("d2/f"));

Expand Down
Loading