std: Fix some behavior without stdio handles

On all platforms, reading from stdin where the actual stdin isn't present should
return 0 bytes as having been read rather than the entire buffer.

On Windows, handle the case where we're inheriting stdio handles but one of them
isn't present. Currently the behavior is to fail returning an I/O error but
instead this commit corrects it to detecting this situation and propagating the
non-set handle.

Closes #31167
This commit is contained in:
Alex Crichton 2016-01-24 21:14:56 -08:00
parent 6866f1361d
commit fee457d3af
3 changed files with 133 additions and 4 deletions

View file

@ -112,7 +112,7 @@ impl<W: io::Write> io::Write for Maybe<W> {
impl<R: io::Read> io::Read for Maybe<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match *self {
Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), buf.len()),
Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), 0),
Maybe::Fake => Ok(0)
}
}

View file

@ -351,10 +351,15 @@ fn make_dirp(d: Option<&OsString>) -> (*const u16, Vec<u16>) {
impl Stdio {
fn to_handle(&self, stdio_id: c::DWORD) -> io::Result<Handle> {
match *self {
// If no stdio handle is available, then inherit means that it
// should still be unavailable so propagate the
// INVALID_HANDLE_VALUE.
Stdio::Inherit => {
stdio::get(stdio_id).and_then(|io| {
io.handle().duplicate(0, true, c::DUPLICATE_SAME_ACCESS)
})
match stdio::get(stdio_id) {
Ok(io) => io.handle().duplicate(0, true,
c::DUPLICATE_SAME_ACCESS),
Err(..) => Ok(Handle::new(c::INVALID_HANDLE_VALUE)),
}
}
Stdio::Raw(handle) => {
RawHandle::new(handle).duplicate(0, true, c::DUPLICATE_SAME_ACCESS)