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

Merge pull request #3076 from jfinkels/dd-seek-truncate

dd: truncate to specified seek length
This commit is contained in:
Sylvestre Ledru 2022-02-08 11:16:15 +01:00 committed by GitHub
commit 9c813be5f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 7 deletions

View file

@ -469,7 +469,6 @@ impl OutputTrait for Output<File> {
let mut opts = OpenOptions::new(); let mut opts = OpenOptions::new();
opts.write(true) opts.write(true)
.create(!cflags.nocreat) .create(!cflags.nocreat)
.truncate(!cflags.notrunc)
.create_new(cflags.excl) .create_new(cflags.excl)
.append(oflags.append); .append(oflags.append);
@ -489,13 +488,13 @@ impl OutputTrait for Output<File> {
let mut dst = open_dst(Path::new(&fname), &cflags, &oflags) let mut dst = open_dst(Path::new(&fname), &cflags, &oflags)
.map_err_context(|| format!("failed to open {}", fname.quote()))?; .map_err_context(|| format!("failed to open {}", fname.quote()))?;
if let Some(amt) = seek { let i = seek.unwrap_or(0).try_into().unwrap();
let amt: u64 = amt if !cflags.notrunc {
.try_into() dst.set_len(i)
.map_err(|_| USimpleError::new(1, "failed to parse seek amount"))?; .map_err_context(|| "failed to truncate output file".to_string())?;
dst.seek(io::SeekFrom::Start(amt))
.map_err_context(|| "failed to seek in output file".to_string())?;
} }
dst.seek(io::SeekFrom::Start(i))
.map_err_context(|| "failed to seek in output file".to_string())?;
Ok(Self { dst, obs, cflags }) Ok(Self { dst, obs, cflags })
} else { } else {

View file

@ -657,5 +657,27 @@ fn test_seek_bytes() {
.stdout_is("\0\0\0\0\0\0\0\0abcdefghijklm\n"); .stdout_is("\0\0\0\0\0\0\0\0abcdefghijklm\n");
} }
#[test]
fn test_seek_do_not_overwrite() {
let (at, mut ucmd) = at_and_ucmd!();
let mut outfile = at.make_file("outfile");
outfile.write_all(b"abc").unwrap();
// Skip the first byte of the input, seek past the first byte of
// the output, and write only one byte to the output.
ucmd.args(&[
"bs=1",
"skip=1",
"seek=1",
"count=1",
"status=noxfer",
"of=outfile",
])
.pipe_in("123")
.succeeds()
.stderr_is("1+0 records in\n1+0 records out\n")
.no_stdout();
assert_eq!(at.read("outfile"), "a2");
}
// conv=[ascii,ebcdic,ibm], conv=[ucase,lcase], conv=[block,unblock], conv=sync // conv=[ascii,ebcdic,ibm], conv=[ucase,lcase], conv=[block,unblock], conv=sync
// TODO: Move conv tests from unit test module // TODO: Move conv tests from unit test module