Skip to content

Commit 46455dc

Browse files
committed
Auto merge of rust-lang#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.
2 parents 42e1e12 + 4971e99 commit 46455dc

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

library/std/tests/switch-stdout.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,48 @@ use std::io::{Read, Write};
55

66
mod common;
77

8+
#[cfg(windows)]
9+
use std::os::windows::io::OwnedHandle;
10+
811
#[cfg(unix)]
9-
fn switch_stdout_to(file: File) {
12+
use std::os::fd::OwnedFd;
13+
14+
#[cfg(unix)]
15+
fn switch_stdout_to(file: OwnedFd) -> OwnedFd {
1016
use std::os::unix::prelude::*;
1117

1218
extern "C" {
19+
fn dup(old: i32) -> i32;
1320
fn dup2(old: i32, new: i32) -> i32;
1421
}
1522

1623
unsafe {
24+
let orig_fd = dup(1);
25+
assert_ne!(orig_fd, -1);
26+
let res = OwnedFd::from_raw_fd(orig_fd);
1727
assert_eq!(dup2(file.as_raw_fd(), 1), 1);
28+
res
1829
}
1930
}
2031

2132
#[cfg(windows)]
22-
fn switch_stdout_to(file: File) {
33+
fn switch_stdout_to(file: OwnedHandle) -> OwnedHandle {
2334
use std::os::windows::prelude::*;
2435

2536
extern "system" {
37+
fn GetStdHandle(nStdHandle: u32) -> *mut u8;
2638
fn SetStdHandle(nStdHandle: u32, handle: *mut u8) -> i32;
2739
}
2840

2941
const STD_OUTPUT_HANDLE: u32 = (-11i32) as u32;
42+
const INVALID_HANDLE_VALUE: *mut u8 = !0 as *mut u8;
3043

3144
unsafe {
45+
let orig_hdl = GetStdHandle(STD_OUTPUT_HANDLE);
46+
assert!(!orig_hdl.is_null() && orig_hdl != INVALID_HANDLE_VALUE);
3247
let rc = SetStdHandle(STD_OUTPUT_HANDLE, file.into_raw_handle() as *mut _);
3348
assert!(rc != 0);
49+
OwnedHandle::from_raw_handle(orig_hdl as _)
3450
}
3551
}
3652

@@ -43,10 +59,12 @@ fn switch_stdout() {
4359
let mut stdout = std::io::stdout();
4460
stdout.write(b"foo\n").unwrap();
4561
stdout.flush().unwrap();
46-
switch_stdout_to(f);
62+
let orig_hdl = switch_stdout_to(f.into());
4763
stdout.write(b"bar\n").unwrap();
4864
stdout.flush().unwrap();
4965

66+
switch_stdout_to(orig_hdl);
67+
5068
let mut contents = String::new();
5169
File::open(&path).unwrap().read_to_string(&mut contents).unwrap();
5270
assert_eq!(contents, "bar\n");

0 commit comments

Comments
 (0)