]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/no-stdio.rs
Remove Ty prefix from Ty{Adt|Array|Slice|RawPtr|Ref|FnDef|FnPtr|Dynamic|Closure|Gener...
[rust.git] / src / test / run-pass / no-stdio.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // ignore-android
12 // ignore-cloudabi no processes
13 // ignore-emscripten no processes
14
15 #![feature(libc)]
16
17 extern crate libc;
18
19 use std::process::{Command, Stdio};
20 use std::env;
21 use std::io::{self, Read, Write};
22
23 #[cfg(unix)]
24 unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R {
25     let doit = |a| {
26         let r = libc::dup(a);
27         assert!(r >= 0);
28         return r
29     };
30     let a = doit(0);
31     let b = doit(1);
32     let c = doit(2);
33
34     assert!(libc::close(0) >= 0);
35     assert!(libc::close(1) >= 0);
36     assert!(libc::close(2) >= 0);
37
38     let r = f();
39
40     assert!(libc::dup2(a, 0) >= 0);
41     assert!(libc::dup2(b, 1) >= 0);
42     assert!(libc::dup2(c, 2) >= 0);
43
44     return r
45 }
46
47 #[cfg(windows)]
48 unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R {
49     type DWORD = u32;
50     type HANDLE = *mut u8;
51     type BOOL = i32;
52
53     const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD;
54     const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
55     const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
56     const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
57
58     extern "system" {
59         fn GetStdHandle(which: DWORD) -> HANDLE;
60         fn SetStdHandle(which: DWORD, handle: HANDLE) -> BOOL;
61     }
62
63     let doit = |id| {
64         let handle = GetStdHandle(id);
65         assert!(handle != INVALID_HANDLE_VALUE);
66         assert!(SetStdHandle(id, INVALID_HANDLE_VALUE) != 0);
67         return handle
68     };
69
70     let a = doit(STD_INPUT_HANDLE);
71     let b = doit(STD_OUTPUT_HANDLE);
72     let c = doit(STD_ERROR_HANDLE);
73
74     let r = f();
75
76     let doit = |id, handle| {
77         assert!(SetStdHandle(id, handle) != 0);
78     };
79     doit(STD_INPUT_HANDLE, a);
80     doit(STD_OUTPUT_HANDLE, b);
81     doit(STD_ERROR_HANDLE, c);
82
83     return r
84 }
85
86 fn main() {
87     if env::args().len() > 1 {
88         println!("test");
89         assert!(io::stdout().write(b"test\n").is_ok());
90         assert!(io::stderr().write(b"test\n").is_ok());
91         assert_eq!(io::stdin().read(&mut [0; 10]).unwrap(), 0);
92         return
93     }
94
95     // First, make sure reads/writes without stdio work if stdio itself is
96     // missing.
97     let (a, b, c) = unsafe {
98         without_stdio(|| {
99             let a = io::stdout().write(b"test\n");
100             let b = io::stderr().write(b"test\n");
101             let c = io::stdin().read(&mut [0; 10]);
102
103             (a, b, c)
104         })
105     };
106
107     assert_eq!(a.unwrap(), 5);
108     assert_eq!(b.unwrap(), 5);
109     assert_eq!(c.unwrap(), 0);
110
111     // Second, spawn a child and do some work with "null" descriptors to make
112     // sure it's ok
113     let me = env::current_exe().unwrap();
114     let status = Command::new(&me)
115                         .arg("next")
116                         .stdin(Stdio::null())
117                         .stdout(Stdio::null())
118                         .stderr(Stdio::null())
119                         .status().unwrap();
120     assert!(status.success(), "{:?} isn't a success", status);
121
122     // Finally, close everything then spawn a child to make sure everything is
123     // *still* ok.
124     let status = unsafe {
125         without_stdio(|| Command::new(&me).arg("next").status())
126     }.unwrap();
127     assert!(status.success(), "{:?} isn't a success", status);
128 }