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)); +}