1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

dd: don't error when outfile is /dev/null

Prevent `dd` from terminating with an error when given the
command-line argument `of=/dev/null`. This commit allows the call to
`File::set_len()` to result in an error without causing the process to
terminate prematurely.
This commit is contained in:
Jeffrey Finkelstein 2022-02-16 21:32:38 -05:00
parent 1a7e5c4cc5
commit 6900638ac6
2 changed files with 16 additions and 2 deletions

View file

@ -521,10 +521,17 @@ impl OutputTrait for Output<File> {
let mut dst = open_dst(Path::new(&fname), &cflags, &oflags)
.map_err_context(|| format!("failed to open {}", fname.quote()))?;
// Seek to the index in the output file, truncating if requested.
//
// Calling `set_len()` may result in an error (for
// example, when calling it on `/dev/null`), but we don't
// want to terminate the process when that happens.
// Instead, we suppress the error by calling
// `Result::ok()`. This matches the behavior of GNU `dd`
// when given the command-line argument `of=/dev/null`.
let i = seek.unwrap_or(0).try_into().unwrap();
if !cflags.notrunc {
dst.set_len(i)
.map_err_context(|| "failed to truncate output file".to_string())?;
dst.set_len(i).ok();
}
dst.seek(io::SeekFrom::Start(i))
.map_err_context(|| "failed to seek in output file".to_string())?;

View file

@ -1095,3 +1095,10 @@ fn test_truncated_record() {
.stdout_is("ac")
.stderr_is("0+1 records in\n0+1 records out\n2 truncated records\n");
}
/// Test that the output file can be `/dev/null`.
#[cfg(unix)]
#[test]
fn test_outfile_dev_null() {
new_ucmd!().arg("of=/dev/null").succeeds().no_stdout();
}