diff --git a/Cargo.toml b/Cargo.toml index 6aba879..f16e72e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,9 @@ log-panic = ["log-panics"] timestamp = ["chrono"] [dependencies] -log = { version = "0.4", features = ["std"] } chrono = { version = "0.4", optional = true } +libc = { version = "0.2.58" } +log = { version = "0.4", features = ["std"] } log-panics = { version = "2", optional = true, features = ["with-backtrace"] } [dev-dependencies] diff --git a/src/lib.rs b/src/lib.rs index f29e428..e76efbe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -423,16 +423,52 @@ fn log_failure(err: io::Error) { // though the return type of the functions are different we only need them both // to implement `io::Write`. +#[cfg(not(test))] +struct Stdout; + +#[cfg(not(test))] +impl Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + match unsafe { libc::write(libc::STDOUT_FILENO, buf.as_ptr() as *const libc::c_void, buf.len()) } { + n if n < 0 => Err(io::Error::last_os_error()), + n => Ok(n as usize), + } + } + + fn flush(&mut self) -> io::Result<()> { + // Don't have to flush standard out. + Ok(()) + } +} + #[cfg(not(test))] #[inline(always)] -fn stdout() -> io::Stdout { - io::stdout() +fn stdout() -> Stdout { + Stdout +} + +#[cfg(not(test))] +struct Stderr; + +#[cfg(not(test))] +impl Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result { + match unsafe { libc::write(libc::STDERR_FILENO, buf.as_ptr() as *const libc::c_void, buf.len()) } { + n if n < 0 => Err(io::Error::last_os_error()), + n => Ok(n as usize), + } + } + + fn flush(&mut self) -> io::Result<()> { + // Don't have to flush standard error. + Ok(()) + } } #[cfg(not(test))] #[inline(always)] -fn stderr() -> io::Stderr { - io::stderr() +fn stderr() -> Stderr { + Stderr } // The testing variant of the functions.