Skip to content

Commit

Permalink
Change to non-line buffered output if output is not a TTY
Browse files Browse the repository at this point in the history
This matches glibc behavior.

This is determined using the `isatty` function on Unixes, and not
attempted at all for other operating systems.

Fixes rust-lang#60673.
  • Loading branch information
tbu- committed Sep 28, 2019
1 parent 78c16f8 commit fb48c55
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/libstd/io/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ impl Read for StdinRaw {
Initializer::nop()
}
}
impl StdoutRaw {
fn should_be_line_buffered(&self) -> bool {
self.0.should_be_line_buffered()
}
}
impl Write for StdoutRaw {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }

Expand Down Expand Up @@ -496,9 +501,6 @@ impl fmt::Debug for StdinLock<'_> {
/// [`io::stdout`]: fn.stdout.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stdout {
// FIXME: this should be LineWriter or BufWriter depending on the state of
// stdout (tty or not). Note that if this is not line buffered it
// should also flush-on-panic or some form of flush-on-abort.
inner: Arc<ReentrantMutex<RefCell<StdioWriter<StdoutRaw>>>>,
}

Expand Down Expand Up @@ -572,7 +574,14 @@ pub fn stdout() -> Stdout {
fn stdout_init() -> Arc<ReentrantMutex<RefCell<StdioWriter<StdoutRaw>>>> {
// This must not reentrantly access `INSTANCE`
let stdout = match stdout_raw() {
Ok(stdout) => StdioWriter::new(stdout, StdioBufferKind::LineBuffered),
Ok(stdout) => {
let buffering = if stdout.should_be_line_buffered() {
StdioBufferKind::LineBuffered
} else {
StdioBufferKind::Buffered
};
StdioWriter::new(stdout, buffering)
},
_ => StdioWriter::new_fake(),
};
Arc::new(ReentrantMutex::new(RefCell::new(stdout)))
Expand Down
3 changes: 3 additions & 0 deletions src/libstd/sys/cloudabi/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ impl Stdout {
pub fn new() -> io::Result<Stdout> {
Ok(Stdout(()))
}
pub fn should_be_line_buffered(&self) -> bool {
true
}
}

impl io::Write for Stdout {
Expand Down
4 changes: 4 additions & 0 deletions src/libstd/sys/sgx/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ impl io::Read for Stdin {

impl Stdout {
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
pub fn should_be_line_buffered(&self) -> bool {
// FIXME: Implement me.
true
}
}

impl io::Write for Stdout {
Expand Down
5 changes: 5 additions & 0 deletions src/libstd/sys/unix/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ impl io::Read for Stdin {

impl Stdout {
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
pub fn should_be_line_buffered(&self) -> bool {
unsafe {
libc::isatty(libc::STDOUT_FILENO) != 0
}
}
}

impl io::Write for Stdout {
Expand Down
4 changes: 4 additions & 0 deletions src/libstd/sys/vxworks/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ impl io::Read for Stdin {

impl Stdout {
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
pub fn should_be_line_buffered(&self) -> bool {
// FIXME: Implement me.
true
}
}

impl io::Write for Stdout {
Expand Down
6 changes: 6 additions & 0 deletions src/libstd/sys/wasi/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ impl Stdout {
pub fn flush(&self) -> io::Result<()> {
Ok(())
}

pub fn should_be_line_buffered(&self) -> bool {
// FIXME: Currently there seems to be no way to query whether stdout is
// a tty, `isatty` is not exposed by WASI.
true
}
}

impl Stderr {
Expand Down
4 changes: 4 additions & 0 deletions src/libstd/sys/wasm/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ impl io::Write for Stdout {
fn flush(&mut self) -> io::Result<()> {
Ok(())
}

fn should_be_line_buffered(&self) -> bool {
true
}
}

impl Stderr {
Expand Down
5 changes: 5 additions & 0 deletions src/libstd/sys/windows/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ impl Stdout {
pub fn new() -> io::Result<Stdout> {
Ok(Stdout)
}
pub fn should_be_line_buffered(&self) -> bool {
// FIXME: Fill in. I don't know how to check whether output is
// redirected on Windows.
true
}
}

impl io::Write for Stdout {
Expand Down
5 changes: 5 additions & 0 deletions src/libstd/sys/windows/stdio_uwp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ impl Stdout {
pub fn new() -> io::Result<Stdout> {
Ok(Stdout)
}
pub fn should_be_line_buffered(&self) -> bool {
// FIXME: Fill in. I don't know how to check whether output is
// redirected on Windows.
true
}
}

impl io::Write for Stdout {
Expand Down

0 comments on commit fb48c55

Please sign in to comment.