Skip to content

Commit d177791

Browse files
authored
Rollup merge of #89433 - arlosi:stdin-fix, r=joshtriplett
Fix ctrl-c causing reads of stdin to return empty on Windows. Pressing ctrl+c (or ctrl+break) on Windows caused a blocking read of stdin to unblock and return empty, unlike other platforms which continue to block. On ctrl-c, `ReadConsoleW` will return success, but also set `LastError` to `ERROR_OPERATION_ABORTED`. This change detects this case, and re-tries the call to `ReadConsoleW`. Fixes #89177. See issue for further details. Tested on Windows 7 and Windows 10 with both MSVC and GNU toolchains
2 parents f9c9774 + 273e522 commit d177791

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

library/std/src/sys/windows/stdio.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -291,15 +291,25 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [u16]) -> io::Result<usize> {
291291
};
292292

293293
let mut amount = 0;
294-
cvt(unsafe {
295-
c::ReadConsoleW(
296-
handle,
297-
buf.as_mut_ptr() as c::LPVOID,
298-
buf.len() as u32,
299-
&mut amount,
300-
&mut input_control as c::PCONSOLE_READCONSOLE_CONTROL,
301-
)
302-
})?;
294+
loop {
295+
cvt(unsafe {
296+
c::SetLastError(0);
297+
c::ReadConsoleW(
298+
handle,
299+
buf.as_mut_ptr() as c::LPVOID,
300+
buf.len() as u32,
301+
&mut amount,
302+
&mut input_control as c::PCONSOLE_READCONSOLE_CONTROL,
303+
)
304+
})?;
305+
306+
// ReadConsoleW returns success with ERROR_OPERATION_ABORTED for Ctrl-C or Ctrl-Break.
307+
// Explicitly check for that case here and try again.
308+
if amount == 0 && unsafe { c::GetLastError() } == c::ERROR_OPERATION_ABORTED {
309+
continue;
310+
}
311+
break;
312+
}
303313

304314
if amount > 0 && buf[amount as usize - 1] == CTRL_Z {
305315
amount -= 1;

0 commit comments

Comments
 (0)