]> git.proxmox.com Git - rustc.git/blob - src/test/run-pass/no-stdio.rs
New upstream version 1.33.0+dfsg1
[rustc.git] / src / test / run-pass / no-stdio.rs
1 // ignore-android
2 // ignore-cloudabi no processes
3 // ignore-emscripten no processes
4
5 #![feature(rustc_private)]
6
7 extern crate libc;
8
9 use std::process::{Command, Stdio};
10 use std::env;
11 use std::io::{self, Read, Write};
12
13 #[cfg(unix)]
14 unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R {
15 let doit = |a| {
16 let r = libc::dup(a);
17 assert!(r >= 0);
18 return r
19 };
20 let a = doit(0);
21 let b = doit(1);
22 let c = doit(2);
23
24 assert!(libc::close(0) >= 0);
25 assert!(libc::close(1) >= 0);
26 assert!(libc::close(2) >= 0);
27
28 let r = f();
29
30 assert!(libc::dup2(a, 0) >= 0);
31 assert!(libc::dup2(b, 1) >= 0);
32 assert!(libc::dup2(c, 2) >= 0);
33
34 return r
35 }
36
37 #[cfg(windows)]
38 unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R {
39 type DWORD = u32;
40 type HANDLE = *mut u8;
41 type BOOL = i32;
42
43 const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD;
44 const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
45 const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
46 const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
47
48 extern "system" {
49 fn GetStdHandle(which: DWORD) -> HANDLE;
50 fn SetStdHandle(which: DWORD, handle: HANDLE) -> BOOL;
51 }
52
53 let doit = |id| {
54 let handle = GetStdHandle(id);
55 assert!(handle != INVALID_HANDLE_VALUE);
56 assert!(SetStdHandle(id, INVALID_HANDLE_VALUE) != 0);
57 return handle
58 };
59
60 let a = doit(STD_INPUT_HANDLE);
61 let b = doit(STD_OUTPUT_HANDLE);
62 let c = doit(STD_ERROR_HANDLE);
63
64 let r = f();
65
66 let doit = |id, handle| {
67 assert!(SetStdHandle(id, handle) != 0);
68 };
69 doit(STD_INPUT_HANDLE, a);
70 doit(STD_OUTPUT_HANDLE, b);
71 doit(STD_ERROR_HANDLE, c);
72
73 return r
74 }
75
76 fn main() {
77 if env::args().len() > 1 {
78 println!("test");
79 assert!(io::stdout().write(b"test\n").is_ok());
80 assert!(io::stderr().write(b"test\n").is_ok());
81 assert_eq!(io::stdin().read(&mut [0; 10]).unwrap(), 0);
82 return
83 }
84
85 // First, make sure reads/writes without stdio work if stdio itself is
86 // missing.
87 let (a, b, c) = unsafe {
88 without_stdio(|| {
89 let a = io::stdout().write(b"test\n");
90 let b = io::stderr().write(b"test\n");
91 let c = io::stdin().read(&mut [0; 10]);
92
93 (a, b, c)
94 })
95 };
96
97 assert_eq!(a.unwrap(), 5);
98 assert_eq!(b.unwrap(), 5);
99 assert_eq!(c.unwrap(), 0);
100
101 // Second, spawn a child and do some work with "null" descriptors to make
102 // sure it's ok
103 let me = env::current_exe().unwrap();
104 let status = Command::new(&me)
105 .arg("next")
106 .stdin(Stdio::null())
107 .stdout(Stdio::null())
108 .stderr(Stdio::null())
109 .status().unwrap();
110 assert!(status.success(), "{:?} isn't a success", status);
111
112 // Finally, close everything then spawn a child to make sure everything is
113 // *still* ok.
114 let status = unsafe {
115 without_stdio(|| Command::new(&me).arg("next").status())
116 }.unwrap();
117 assert!(status.success(), "{:?} isn't a success", status);
118 }