Auto merge of #117386 - roblabla:fix-switch-stdio-win7, r=ChrisDenton
Fix switch_stdout_to on Windows7 The `switch_stdout_to` test was broken on Windows7, as deleting the temporary test folder would fail since the `switch-stdout-output` file we redirected the stdout to is never closed, and it's impossible on Win7 to delete an opened file. To fix this issue, we make `switch_stdout_to` return the previous handle. Using this, we add a new `switch_stdout_to` call at the end of the test to return the stdio handles to their original state, and recover the handle to the file we opened. This handle is automatically closed at the end of the function, which should allow the temporary test folder to be deleted properly.
This commit is contained in:
commit
46455dc650
@ -5,32 +5,48 @@ use std::io::{Read, Write};
|
||||
|
||||
mod common;
|
||||
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::io::OwnedHandle;
|
||||
|
||||
#[cfg(unix)]
|
||||
fn switch_stdout_to(file: File) {
|
||||
use std::os::fd::OwnedFd;
|
||||
|
||||
#[cfg(unix)]
|
||||
fn switch_stdout_to(file: OwnedFd) -> OwnedFd {
|
||||
use std::os::unix::prelude::*;
|
||||
|
||||
extern "C" {
|
||||
fn dup(old: i32) -> i32;
|
||||
fn dup2(old: i32, new: i32) -> i32;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let orig_fd = dup(1);
|
||||
assert_ne!(orig_fd, -1);
|
||||
let res = OwnedFd::from_raw_fd(orig_fd);
|
||||
assert_eq!(dup2(file.as_raw_fd(), 1), 1);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn switch_stdout_to(file: File) {
|
||||
fn switch_stdout_to(file: OwnedHandle) -> OwnedHandle {
|
||||
use std::os::windows::prelude::*;
|
||||
|
||||
extern "system" {
|
||||
fn GetStdHandle(nStdHandle: u32) -> *mut u8;
|
||||
fn SetStdHandle(nStdHandle: u32, handle: *mut u8) -> i32;
|
||||
}
|
||||
|
||||
const STD_OUTPUT_HANDLE: u32 = (-11i32) as u32;
|
||||
const INVALID_HANDLE_VALUE: *mut u8 = !0 as *mut u8;
|
||||
|
||||
unsafe {
|
||||
let orig_hdl = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
assert!(!orig_hdl.is_null() && orig_hdl != INVALID_HANDLE_VALUE);
|
||||
let rc = SetStdHandle(STD_OUTPUT_HANDLE, file.into_raw_handle() as *mut _);
|
||||
assert!(rc != 0);
|
||||
OwnedHandle::from_raw_handle(orig_hdl as _)
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,10 +59,12 @@ fn switch_stdout() {
|
||||
let mut stdout = std::io::stdout();
|
||||
stdout.write(b"foo\n").unwrap();
|
||||
stdout.flush().unwrap();
|
||||
switch_stdout_to(f);
|
||||
let orig_hdl = switch_stdout_to(f.into());
|
||||
stdout.write(b"bar\n").unwrap();
|
||||
stdout.flush().unwrap();
|
||||
|
||||
switch_stdout_to(orig_hdl);
|
||||
|
||||
let mut contents = String::new();
|
||||
File::open(&path).unwrap().read_to_string(&mut contents).unwrap();
|
||||
assert_eq!(contents, "bar\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user