Skip to content

Commit d400563

Browse files
committed
std: Chunk writing to stdout on windows
This just takes a similar approach to reading stdin on windows by artificially limiting the size of the buffers going in and out. Closes #14940
1 parent 0996766 commit d400563

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

src/libstd/io/stdio.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use failure::local_stderr;
3131
use fmt;
3232
use io::{Reader, Writer, IoResult, IoError, OtherIoError,
3333
standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
34+
use iter::Iterator;
3435
use kinds::Send;
3536
use libc;
3637
use option::{Option, Some, None};
@@ -40,7 +41,9 @@ use rt;
4041
use rt::local::Local;
4142
use rt::task::Task;
4243
use rt::rtio::{DontClose, IoFactory, LocalIo, RtioFileStream, RtioTTY};
44+
use slice::ImmutableVector;
4345
use str::StrSlice;
46+
use uint;
4447

4548
// And so begins the tale of acquiring a uv handle to a stdio stream on all
4649
// platforms in all situations. Our story begins by splitting the world into two
@@ -355,10 +358,18 @@ impl StdWriter {
355358

356359
impl Writer for StdWriter {
357360
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
358-
match self.inner {
359-
TTY(ref mut tty) => tty.write(buf),
360-
File(ref mut file) => file.write(buf),
361-
}.map_err(IoError::from_rtio_error)
361+
// As with stdin on windows, stdout often can't handle writes of large
362+
// sizes. For an example, see #14940. For this reason, chunk the output
363+
// buffer on windows, but on unix we can just write the whole buffer all
364+
// at once.
365+
let max_size = if cfg!(windows) {64 * 1024} else {uint::MAX};
366+
for chunk in buf.chunks(max_size) {
367+
try!(match self.inner {
368+
TTY(ref mut tty) => tty.write(chunk),
369+
File(ref mut file) => file.write(chunk),
370+
}.map_err(IoError::from_rtio_error))
371+
}
372+
Ok(())
362373
}
363374
}
364375

src/test/run-pass/issue-14940.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::os;
12+
use std::io::{stdio, Command};
13+
14+
fn main() {
15+
let args = os::args();
16+
if args.len() > 1 {
17+
let mut out = stdio::stdout();
18+
out.write(['a' as u8, ..128 * 1024]).unwrap();
19+
} else {
20+
let out = Command::new(args.get(0).as_slice()).arg("child").output();
21+
let out = out.unwrap();
22+
assert!(out.status.success());
23+
}
24+
}

0 commit comments

Comments
 (0)