Skip to content

Commit e8d7844

Browse files
committed
tee: improve throughput by raw syscall
1 parent 9bf907d commit e8d7844

2 files changed

Lines changed: 24 additions & 21 deletions

File tree

src/uu/tee/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ doctest = false
2121

2222
[dependencies]
2323
clap = { workspace = true }
24-
uucore = { workspace = true, features = ["libc", "parser", "signals"] }
24+
rustix = { workspace = true, features = ["stdio", "fs"] }
25+
uucore = { workspace = true, features = ["fs", "libc", "parser", "signals"] }
2526
fluent = { workspace = true }
2627

2728
[dev-dependencies]
2829
divan = { workspace = true }
29-
rustix = { workspace = true, features = ["stdio", "fs"] }
3030
tempfile = { workspace = true }
3131
uucore = { workspace = true, features = ["benchmark"] }
3232

src/uu/tee/src/tee.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ fn tee(options: &Options) -> Result<()> {
8080
0,
8181
NamedWriter {
8282
name: translate!("tee-standard-output").into(),
83+
#[cfg(any(unix, target_os = "wasi"))]
84+
inner: Writer::Stdout(uucore::io::RawWriter(stdout())),
85+
#[cfg(not(any(unix, target_os = "wasi")))]
8386
inner: Writer::Stdout(stdout()),
8487
},
8588
);
@@ -197,21 +200,16 @@ impl MultiWriter {
197200

198201
fn write_flush(&mut self, buf: &[u8]) -> Result<()> {
199202
let mode = self.output_error_mode;
200-
self.writers.retain_mut(|writer| {
201-
let res = (|| {
202-
writer.inner.write_all(buf)?;
203-
writer.inner.flush()
204-
})();
205-
match res {
203+
self.writers
204+
.retain_mut(|writer| match writer.inner.write_all(buf) {
206205
Ok(()) => true,
207206
Err(e) => {
208207
if let Err(e) = process_error(mode, e, writer, &mut self.ignored_errors) {
209208
self.aborted.get_or_insert(e);
210209
}
211210
false
212211
}
213-
}
214-
});
212+
});
215213
self.aborted.take().map_or(
216214
if self.writers.is_empty() {
217215
// This error kind will never be raised by the standard
@@ -251,21 +249,26 @@ fn process_error(
251249

252250
enum Writer {
253251
File(std::fs::File),
252+
// remove buffering for posix requirement and improve throughput
253+
#[cfg(any(unix, target_os = "wasi"))]
254+
Stdout(uucore::io::RawWriter),
255+
#[cfg(not(any(unix, target_os = "wasi")))]
254256
Stdout(std::io::Stdout),
255257
}
256258

257-
impl Write for Writer {
258-
fn write(&mut self, buf: &[u8]) -> Result<usize> {
259-
match self {
260-
Self::File(f) => f.write(buf),
261-
Self::Stdout(s) => s.write(buf),
262-
}
263-
}
264-
265-
fn flush(&mut self) -> Result<()> {
259+
impl Writer {
260+
pub fn write_all(&mut self, buf: &[u8]) -> Result<()> {
266261
match self {
267-
Self::File(f) => f.flush(),
268-
Self::Stdout(s) => s.flush(),
262+
// File does not have line buffering
263+
Self::File(f) => f.write_all(buf),
264+
#[cfg(any(unix, target_os = "wasi"))]
265+
Self::Stdout(s) => s.write_all(buf),
266+
#[cfg(not(any(unix, target_os = "wasi")))]
267+
Self::Stdout(s) => {
268+
s.write_all(buf)?;
269+
// needs unsafe to remove buffering... flush after write_all to keep overhead minimal
270+
s.flush()
271+
}
269272
}
270273
}
271274
}

0 commit comments

Comments
 (0)