Skip to content

Commit 8793377

Browse files
committed
tee: improve stdout performance
1 parent f65350a commit 8793377

1 file changed

Lines changed: 25 additions & 15 deletions

File tree

src/uu/tee/src/tee.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ fn tee(options: &Options) -> Result<()> {
8080
0,
8181
NamedWriter {
8282
name: translate!("tee-standard-output").into(),
83-
inner: Writer::Stdout(stdout()),
83+
inner: Writer::stdout_raw(),
8484
},
8585
);
8686

@@ -197,21 +197,16 @@ impl MultiWriter {
197197

198198
fn write_flush(&mut self, buf: &[u8]) -> Result<()> {
199199
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 {
200+
self.writers
201+
.retain_mut(|writer| match writer.inner.write_all(buf) {
206202
Ok(()) => true,
207203
Err(e) => {
208204
if let Err(e) = process_error(mode, e, writer, &mut self.ignored_errors) {
209205
self.aborted.get_or_insert(e);
210206
}
211207
false
212208
}
213-
}
214-
});
209+
});
215210
self.aborted.take().map_or(
216211
if self.writers.is_empty() {
217212
// This error kind will never be raised by the standard
@@ -251,22 +246,37 @@ fn process_error(
251246

252247
enum Writer {
253248
File(std::fs::File),
254-
Stdout(std::io::Stdout),
249+
StdoutRaw(core::mem::ManuallyDrop<std::fs::File>),
250+
}
251+
252+
impl Writer {
253+
#[cfg(not(windows))]
254+
fn stdout_raw() -> Self {
255+
let fd = std::os::fd::AsRawFd::as_raw_fd(&stdout());
256+
Self::StdoutRaw(core::mem::ManuallyDrop::new(unsafe {
257+
std::os::fd::FromRawFd::from_raw_fd(fd)
258+
}))
259+
}
260+
261+
#[cfg(windows)]
262+
fn stdout_raw() -> Self {
263+
let handle = std::os::windows::io::AsRawHandle::as_raw_handle(&stdout());
264+
Self::StdoutRaw(core::mem::ManuallyDrop::new(unsafe {
265+
std::os::windows::io::FromRawHandle::from_raw_handle(handle)
266+
}))
267+
}
255268
}
256269

257270
impl Write for Writer {
258271
fn write(&mut self, buf: &[u8]) -> Result<usize> {
259272
match self {
260273
Self::File(f) => f.write(buf),
261-
Self::Stdout(s) => s.write(buf),
274+
Self::StdoutRaw(s) => s.write(buf),
262275
}
263276
}
264277

265278
fn flush(&mut self) -> Result<()> {
266-
match self {
267-
Self::File(f) => f.flush(),
268-
Self::Stdout(s) => s.flush(),
269-
}
279+
Ok(())
270280
}
271281
}
272282

0 commit comments

Comments
 (0)