Skip to content

Commit fb48c55

Browse files
committed
Change to non-line buffered output if output is not a TTY
This matches glibc behavior. This is determined using the `isatty` function on Unixes, and not attempted at all for other operating systems. Fixes #60673.
1 parent 78c16f8 commit fb48c55

File tree

9 files changed

+49
-4
lines changed

9 files changed

+49
-4
lines changed

src/libstd/io/stdio.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ impl Read for StdinRaw {
8484
Initializer::nop()
8585
}
8686
}
87+
impl StdoutRaw {
88+
fn should_be_line_buffered(&self) -> bool {
89+
self.0.should_be_line_buffered()
90+
}
91+
}
8792
impl Write for StdoutRaw {
8893
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
8994

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

@@ -572,7 +574,14 @@ pub fn stdout() -> Stdout {
572574
fn stdout_init() -> Arc<ReentrantMutex<RefCell<StdioWriter<StdoutRaw>>>> {
573575
// This must not reentrantly access `INSTANCE`
574576
let stdout = match stdout_raw() {
575-
Ok(stdout) => StdioWriter::new(stdout, StdioBufferKind::LineBuffered),
577+
Ok(stdout) => {
578+
let buffering = if stdout.should_be_line_buffered() {
579+
StdioBufferKind::LineBuffered
580+
} else {
581+
StdioBufferKind::Buffered
582+
};
583+
StdioWriter::new(stdout, buffering)
584+
},
576585
_ => StdioWriter::new_fake(),
577586
};
578587
Arc::new(ReentrantMutex::new(RefCell::new(stdout)))

src/libstd/sys/cloudabi/stdio.rs

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ impl Stdout {
2121
pub fn new() -> io::Result<Stdout> {
2222
Ok(Stdout(()))
2323
}
24+
pub fn should_be_line_buffered(&self) -> bool {
25+
true
26+
}
2427
}
2528

2629
impl io::Write for Stdout {

src/libstd/sys/sgx/stdio.rs

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ impl io::Read for Stdin {
3030

3131
impl Stdout {
3232
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
33+
pub fn should_be_line_buffered(&self) -> bool {
34+
// FIXME: Implement me.
35+
true
36+
}
3337
}
3438

3539
impl io::Write for Stdout {

src/libstd/sys/unix/stdio.rs

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ impl io::Read for Stdin {
2222

2323
impl Stdout {
2424
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
25+
pub fn should_be_line_buffered(&self) -> bool {
26+
unsafe {
27+
libc::isatty(libc::STDOUT_FILENO) != 0
28+
}
29+
}
2530
}
2631

2732
impl io::Write for Stdout {

src/libstd/sys/vxworks/stdio.rs

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ impl io::Read for Stdin {
2020

2121
impl Stdout {
2222
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
23+
pub fn should_be_line_buffered(&self) -> bool {
24+
// FIXME: Implement me.
25+
true
26+
}
2327
}
2428

2529
impl io::Write for Stdout {

src/libstd/sys/wasi/stdio.rs

+6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ impl Stdout {
4040
pub fn flush(&self) -> io::Result<()> {
4141
Ok(())
4242
}
43+
44+
pub fn should_be_line_buffered(&self) -> bool {
45+
// FIXME: Currently there seems to be no way to query whether stdout is
46+
// a tty, `isatty` is not exposed by WASI.
47+
true
48+
}
4349
}
4450

4551
impl Stderr {

src/libstd/sys/wasm/stdio.rs

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ impl io::Write for Stdout {
3030
fn flush(&mut self) -> io::Result<()> {
3131
Ok(())
3232
}
33+
34+
fn should_be_line_buffered(&self) -> bool {
35+
true
36+
}
3337
}
3438

3539
impl Stderr {

src/libstd/sys/windows/stdio.rs

+5
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@ impl Stdout {
246246
pub fn new() -> io::Result<Stdout> {
247247
Ok(Stdout)
248248
}
249+
pub fn should_be_line_buffered(&self) -> bool {
250+
// FIXME: Fill in. I don't know how to check whether output is
251+
// redirected on Windows.
252+
true
253+
}
249254
}
250255

251256
impl io::Write for Stdout {

src/libstd/sys/windows/stdio_uwp.rs

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ impl Stdout {
4848
pub fn new() -> io::Result<Stdout> {
4949
Ok(Stdout)
5050
}
51+
pub fn should_be_line_buffered(&self) -> bool {
52+
// FIXME: Fill in. I don't know how to check whether output is
53+
// redirected on Windows.
54+
true
55+
}
5156
}
5257

5358
impl io::Write for Stdout {

0 commit comments

Comments
 (0)