Skip to content

Commit 9bf907d

Browse files
oech3cakebaker
authored andcommitted
cat: dedup print_unbuffered
1 parent 74f7fb0 commit 9bf907d

2 files changed

Lines changed: 19 additions & 23 deletions

File tree

src/uu/cat/src/cat.rs

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -497,31 +497,13 @@ fn print_fast<R: FdReadable>(handle: &mut InputHandle<R>) -> CatResult<()> {
497497
}
498498

499499
#[cfg_attr(any(target_os = "linux", target_os = "android"), inline(never))] // splice fast-path does not require this allocation
500-
#[cfg(any(unix, target_os = "wasi"))]
501-
fn print_unbuffered<R: FdReadable>(
502-
handle: &mut InputHandle<R>,
503-
stdout: io::Stdout,
504-
) -> CatResult<()> {
505-
// todo: since there is no cost by 0-fill, we could use larger heap buffer for throughput
506-
let mut buf = [std::mem::MaybeUninit::<u8>::uninit(); 1024 * 64];
507-
// use raw syscall to remove buffering
508-
loop {
509-
match rustix::io::read(&handle.reader, &mut buf) {
510-
Ok(([], _)) => return Ok(()),
511-
Ok((filled, _)) => {
512-
uucore::io::write_all_raw(&stdout, filled).inspect_err(handle_broken_pipe)?;
513-
}
514-
Err(e) if e.kind() != ErrorKind::Interrupted => return Err(e.into()),
515-
_ => {}
516-
}
517-
}
518-
}
519-
520-
#[cfg(not(any(unix, target_os = "wasi")))]
521500
fn print_unbuffered<R: FdReadable>(
522501
handle: &mut InputHandle<R>,
523502
stdout: io::Stdout,
524503
) -> CatResult<()> {
504+
#[cfg(any(unix, target_os = "wasi"))]
505+
let mut stdout = uucore::io::RawWriter(stdout); // use raw syscall to remove buffering
506+
#[cfg(not(any(unix, target_os = "wasi")))]
525507
let mut stdout = stdout.lock();
526508
let mut buf = [0; 1024 * 64];
527509
loop {
@@ -531,8 +513,9 @@ fn print_unbuffered<R: FdReadable>(
531513
stdout
532514
.write_all(&buf[..n])
533515
.inspect_err(handle_broken_pipe)?;
534-
// we cannot use rustix::io on Windows
516+
// cannot use rustix::io on Windows
535517
// really bad workaround for unbuffered write <https://github.com/uutils/coreutils/issues/12188>
518+
#[cfg(not(any(unix, target_os = "wasi")))]
536519
stdout.flush().inspect_err(handle_broken_pipe)?;
537520
}
538521
Err(e) if e.kind() != ErrorKind::Interrupted => return Err(e.into()),

src/uucore/src/lib/mods/io.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,20 @@ type NativeType = OwnedHandle;
3030
#[cfg(not(windows))]
3131
type NativeType = OwnedFd;
3232

33-
// io::write_all but no buffering
33+
// create stdout without buffering
34+
#[cfg(any(unix, target_os = "wasi"))]
35+
pub struct RawWriter(pub io::Stdout);
36+
#[cfg(any(unix, target_os = "wasi"))]
37+
impl io::Write for RawWriter {
38+
fn write(&mut self, b: &[u8]) -> io::Result<usize> {
39+
rustix::io::write(&self.0, b).map_err(Into::into)
40+
}
41+
fn flush(&mut self) -> io::Result<()> {
42+
Ok(())
43+
}
44+
}
45+
46+
// io::write_all but no buffering (deprecated?)
3447
#[inline]
3548
#[cfg(any(unix, target_os = "wasi"))]
3649
pub fn write_all_raw(output: impl AsFd, buf: &[u8]) -> io::Result<()> {

0 commit comments

Comments
 (0)