From 129cfe12b826377a5eeb24577c492bcb0da02033 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Sun, 23 Jan 2022 11:14:48 -0500 Subject: [PATCH] truncate: create non-existent file by default Fix the behavior of truncate when given a non-existent file so that it correctly creates the file before truncating it (unless the `--no-create` option is also given). --- src/uu/truncate/src/truncate.rs | 13 ++++++++++--- tests/by-util/test_truncate.rs | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/uu/truncate/src/truncate.rs b/src/uu/truncate/src/truncate.rs index d9ffb31f7..b615cf495 100644 --- a/src/uu/truncate/src/truncate.rs +++ b/src/uu/truncate/src/truncate.rs @@ -278,9 +278,16 @@ fn truncate_size_only( Err(e) => crash!(1, "Invalid number: {}", e.to_string()), }; for filename in &filenames { - let fsize = usize::try_from(metadata(filename)?.len()).unwrap(); - let tsize = mode.to_size(fsize); - file_truncate(filename, create, tsize)?; + let fsize = match metadata(filename) { + Ok(m) => m.len(), + Err(_) => 0, + }; + let tsize = mode.to_size(fsize as usize); + match file_truncate(filename, create, tsize) { + Ok(_) => continue, + Err(e) if e.kind() == ErrorKind::NotFound && !create => continue, + Err(e) => return Err(e), + } } Ok(()) } diff --git a/tests/by-util/test_truncate.rs b/tests/by-util/test_truncate.rs index 4b2e9e502..bb76e8b94 100644 --- a/tests/by-util/test_truncate.rs +++ b/tests/by-util/test_truncate.rs @@ -321,3 +321,28 @@ fn test_truncate_bytes_size() { } } } + +/// Test that truncating a non-existent file creates that file. +#[test] +fn test_new_file() { + let (at, mut ucmd) = at_and_ucmd!(); + let filename = "new_file_that_does_not_exist_yet"; + ucmd.args(&["-s", "8", filename]) + .succeeds() + .no_stdout() + .no_stderr(); + assert!(at.file_exists(filename)); + assert_eq!(at.read_bytes(filename), vec![b'\0'; 8]); +} + +/// Test for not creating a non-existent file. +#[test] +fn test_new_file_no_create() { + let (at, mut ucmd) = at_and_ucmd!(); + let filename = "new_file_that_does_not_exist_yet"; + ucmd.args(&["-s", "8", "-c", filename]) + .succeeds() + .no_stdout() + .no_stderr(); + assert!(!at.file_exists(filename)); +}