mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
dd: buffer partial blocks in the output writer
Add buffering of partial blocks in the output block writer until they are completed.
This commit is contained in:
parent
f343b7e964
commit
ceccd2ecc6
3 changed files with 194 additions and 30 deletions
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, availible, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat abcdefghijklm abcdefghi nabcde nabcdefg abcdefg
|
||||
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, availible, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat abcdefghijklm abcdefghi nabcde nabcdefg abcdefg fifoname
|
||||
|
||||
#[cfg(unix)]
|
||||
use crate::common::util::run_ucmd_as_root_with_stdin_stdout;
|
||||
|
@ -15,6 +15,8 @@ use regex::Regex;
|
|||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{BufReader, Read, Write};
|
||||
use std::path::PathBuf;
|
||||
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "freebsd")))]
|
||||
use std::process::{Command, Stdio};
|
||||
#[cfg(not(windows))]
|
||||
use std::thread::sleep;
|
||||
#[cfg(not(windows))]
|
||||
|
@ -1582,3 +1584,77 @@ fn test_seek_past_dev() {
|
|||
print!("TEST SKIPPED");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "freebsd")))]
|
||||
fn test_reading_partial_blocks_from_fifo() {
|
||||
// Create the FIFO.
|
||||
let ts = TestScenario::new(util_name!());
|
||||
let at = ts.fixtures.clone();
|
||||
at.mkfifo("fifo");
|
||||
let fifoname = at.plus_as_string("fifo");
|
||||
|
||||
// Start a `dd` process that reads from the fifo (so it will wait
|
||||
// until the writer process starts).
|
||||
let mut reader_command = Command::new(TESTS_BINARY);
|
||||
let child = reader_command
|
||||
.args(["dd", "ibs=3", "obs=3", &format!("if={}", fifoname)])
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
// Start different processes to write to the FIFO, with a small
|
||||
// pause in between.
|
||||
let mut writer_command = Command::new("sh");
|
||||
writer_command
|
||||
.args([
|
||||
"-c",
|
||||
&format!("(printf \"ab\"; sleep 0.1; printf \"cd\") > {}", fifoname),
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
let output = child.wait_with_output().unwrap();
|
||||
assert_eq!(output.stdout, b"abcd");
|
||||
let expected = b"0+2 records in\n1+1 records out\n4 bytes copied";
|
||||
assert!(output.stderr.starts_with(expected));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "freebsd")))]
|
||||
fn test_reading_partial_blocks_from_fifo_unbuffered() {
|
||||
// Create the FIFO.
|
||||
let ts = TestScenario::new(util_name!());
|
||||
let at = ts.fixtures.clone();
|
||||
at.mkfifo("fifo");
|
||||
let fifoname = at.plus_as_string("fifo");
|
||||
|
||||
// Start a `dd` process that reads from the fifo (so it will wait
|
||||
// until the writer process starts).
|
||||
//
|
||||
// `bs=N` takes precedence over `ibs=N` and `obs=N`.
|
||||
let mut reader_command = Command::new(TESTS_BINARY);
|
||||
let child = reader_command
|
||||
.args(["dd", "bs=3", "ibs=1", "obs=1", &format!("if={}", fifoname)])
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
// Start different processes to write to the FIFO, with a small
|
||||
// pause in between.
|
||||
let mut writer_command = Command::new("sh");
|
||||
writer_command
|
||||
.args([
|
||||
"-c",
|
||||
&format!("(printf \"ab\"; sleep 0.1; printf \"cd\") > {}", fifoname),
|
||||
])
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
let output = child.wait_with_output().unwrap();
|
||||
assert_eq!(output.stdout, b"abcd");
|
||||
let expected = b"0+2 records in\n0+2 records out\n4 bytes copied";
|
||||
assert!(output.stderr.starts_with(expected));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue