Skip to content

Commit 09e1aa1

Browse files
committed
sort: make compression program failures non-fatal, warn and fallback to plain files
Should fix tests/sort/sort-compress.sh
1 parent d432131 commit 09e1aa1

File tree

6 files changed

+55
-27
lines changed

6 files changed

+55
-27
lines changed

src/uu/sort/locales/en-US.ftl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ sort-open-failed = open failed: {$path}: {$error}
1515
sort-parse-key-error = failed to parse key {$key}: {$msg}
1616
sort-cannot-read = cannot read: {$path}: {$error}
1717
sort-open-tmp-file-failed = failed to open temporary file: {$error}
18-
sort-compress-prog-execution-failed = couldn't execute compress program: errno {$code}
18+
sort-compress-prog-execution-failed = could not run compress program '{$prog}': {$error}
1919
sort-compress-prog-terminated-abnormally = {$prog} terminated abnormally
2020
sort-cannot-create-tmp-file = cannot create temporary file in '{$path}':
2121
sort-file-operands-combined = extra operand '{$file}'

src/uu/sort/locales/fr-FR.ftl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ sort-open-failed = échec d'ouverture : {$path} : {$error}
1515
sort-parse-key-error = échec d'analyse de la clé {$key} : {$msg}
1616
sort-cannot-read = impossible de lire : {$path} : {$error}
1717
sort-open-tmp-file-failed = échec d'ouverture du fichier temporaire : {$error}
18-
sort-compress-prog-execution-failed = impossible d'exécuter le programme de compression : errno {$code}
18+
sort-compress-prog-execution-failed = impossible d'exécuter le programme de compression '{$prog}' : {$error}
1919
sort-compress-prog-terminated-abnormally = {$prog} s'est terminé anormalement
2020
sort-cannot-create-tmp-file = impossible de créer un fichier temporaire dans '{$path}' :
2121
sort-file-operands-combined = opérande supplémentaire '{$file}'

src/uu/sort/src/ext_sort.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::{
2020
};
2121

2222
use itertools::Itertools;
23-
use uucore::error::UResult;
23+
use uucore::error::{UResult, strip_errno};
2424

2525
use crate::Output;
2626
use crate::chunks::RecycledChunk;
@@ -52,10 +52,37 @@ pub fn ext_sort(
5252
let settings = settings.clone();
5353
move || sorter(&recycled_receiver, &sorted_sender, &settings)
5454
});
55-
if settings.compress_prog.is_some() {
55+
56+
// Test if compression program exists and works, disable if not
57+
let mut effective_settings = settings.clone();
58+
if let Some(ref prog) = settings.compress_prog {
59+
// Test the compression program by trying to spawn it
60+
match std::process::Command::new(prog)
61+
.stdin(std::process::Stdio::null())
62+
.stdout(std::process::Stdio::null())
63+
.stderr(std::process::Stdio::null())
64+
.spawn()
65+
{
66+
Ok(mut child) => {
67+
// Kill the test process immediately
68+
let _ = child.kill();
69+
}
70+
Err(err) => {
71+
// Print the error and disable compression
72+
eprintln!(
73+
"sort: could not run compress program '{}': {}",
74+
prog,
75+
strip_errno(&err)
76+
);
77+
effective_settings.compress_prog = None;
78+
}
79+
}
80+
}
81+
82+
if effective_settings.compress_prog.is_some() {
5683
reader_writer::<_, WriteableCompressedTmpFile>(
5784
files,
58-
settings,
85+
&effective_settings,
5986
&sorted_receiver,
6087
recycled_sender,
6188
output,
@@ -64,7 +91,7 @@ pub fn ext_sort(
6491
} else {
6592
reader_writer::<_, WriteablePlainTmpFile>(
6693
files,
67-
settings,
94+
&effective_settings,
6895
&sorted_receiver,
6996
recycled_sender,
7097
output,

src/uu/sort/src/merge.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,8 @@ impl WriteableTmpFile for WriteableCompressedTmpFile {
488488
let mut child = command
489489
.spawn()
490490
.map_err(|err| SortError::CompressProgExecutionFailed {
491-
code: err.raw_os_error().unwrap(),
491+
prog: compress_prog.to_owned(),
492+
error: err,
492493
})?;
493494
let child_stdin = child.stdin.take().unwrap();
494495
Ok(Self {
@@ -522,7 +523,8 @@ impl ClosedTmpFile for ClosedCompressedTmpFile {
522523
let mut child = command
523524
.spawn()
524525
.map_err(|err| SortError::CompressProgExecutionFailed {
525-
code: err.raw_os_error().unwrap(),
526+
prog: self.compress_prog.clone(),
527+
error: err,
526528
})?;
527529
let child_stdout = child.stdout.take().unwrap();
528530
Ok(CompressedTmpMergeInput {

src/uu/sort/src/sort.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ pub enum SortError {
152152
#[error("{}", translate!("sort-open-tmp-file-failed", "error" => strip_errno(.error)))]
153153
OpenTmpFileFailed { error: std::io::Error },
154154

155-
#[error("{}", translate!("sort-compress-prog-execution-failed", "code" => .code))]
156-
CompressProgExecutionFailed { code: i32 },
155+
#[error("{}", translate!("sort-compress-prog-execution-failed", "prog" => .prog, "error" => strip_errno(.error)))]
156+
CompressProgExecutionFailed { prog: String, error: std::io::Error },
157157

158158
#[error("{}", translate!("sort-compress-prog-terminated-abnormally", "prog" => .prog.quote()))]
159159
CompressProgTerminatedAbnormally { prog: String },

tests/by-util/test_sort.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,8 +1002,7 @@ fn test_compress_merge() {
10021002
#[test]
10031003
#[cfg(not(target_os = "android"))]
10041004
fn test_compress_fail() {
1005-
#[cfg(not(windows))]
1006-
new_ucmd!()
1005+
let result = new_ucmd!()
10071006
.args(&[
10081007
"ext_sort.txt",
10091008
"-n",
@@ -1012,22 +1011,22 @@ fn test_compress_fail() {
10121011
"-S",
10131012
"10",
10141013
])
1015-
.fails()
1016-
.stderr_only("sort: couldn't execute compress program: errno 2\n");
1017-
// With coverage, it fails with a different error:
1018-
// "thread 'main' panicked at 'called `Option::unwrap()` on ...
1019-
// So, don't check the output
1014+
.succeeds();
1015+
1016+
#[cfg(not(windows))]
1017+
result.stderr_contains(
1018+
"sort: could not run compress program 'nonexistent-program': No such file or directory",
1019+
);
1020+
10201021
#[cfg(windows)]
1021-
new_ucmd!()
1022-
.args(&[
1023-
"ext_sort.txt",
1024-
"-n",
1025-
"--compress-program",
1026-
"nonexistent-program",
1027-
"-S",
1028-
"10",
1029-
])
1030-
.fails();
1022+
result.stderr_contains("could not run compress program");
1023+
1024+
// Check that it still produces correct sorted output to stdout
1025+
let expected = new_ucmd!()
1026+
.args(&["ext_sort.txt", "-n"])
1027+
.succeeds()
1028+
.stdout_move_str();
1029+
assert_eq!(result.stdout_str(), expected);
10311030
}
10321031

10331032
#[test]

0 commit comments

Comments
 (0)