1 // run-pass
2 // ignore-windows
3 // ignore-android
4 // ignore-emscripten no processes
5 // ignore-haiku
6 // ignore-sgx no processes
7 
8 #![feature(rustc_private)]
9 
10 extern crate libc;
11 
12 use std::env;
13 use std::fs::File;
14 use std::io;
15 use std::net::{TcpListener, TcpStream, UdpSocket};
16 use std::os::unix::prelude::*;
17 use std::process::{Command, Stdio};
18 use std::thread;
19 
main()20 fn main() {
21     let args = env::args().collect::<Vec<_>>();
22     if args.len() == 1 {
23         parent()
24     } else {
25         child(&args)
26     }
27 }
28 
parent()29 fn parent() {
30     let file = File::open(env::current_exe().unwrap()).unwrap();
31     let tcp1 = TcpListener::bind("127.0.0.1:0").unwrap();
32     let tcp2 = tcp1.try_clone().unwrap();
33     let addr = tcp1.local_addr().unwrap();
34     let t = thread::spawn(move || TcpStream::connect(addr).unwrap());
35     let tcp3 = tcp1.accept().unwrap().0;
36     let tcp4 = t.join().unwrap();
37     let tcp5 = tcp3.try_clone().unwrap();
38     let tcp6 = tcp4.try_clone().unwrap();
39     let udp1 = UdpSocket::bind("127.0.0.1:0").unwrap();
40     let udp2 = udp1.try_clone().unwrap();
41 
42     let mut child = Command::new(env::args().next().unwrap())
43                             .arg("100")
44                             .stdout(Stdio::piped())
45                             .stdin(Stdio::piped())
46                             .stderr(Stdio::piped())
47                             .spawn().unwrap();
48     let pipe1 = child.stdin.take().unwrap();
49     let pipe2 = child.stdout.take().unwrap();
50     let pipe3 = child.stderr.take().unwrap();
51 
52 
53     let status = Command::new(env::args().next().unwrap())
54                         .arg(file.as_raw_fd().to_string())
55                         .arg(tcp1.as_raw_fd().to_string())
56                         .arg(tcp2.as_raw_fd().to_string())
57                         .arg(tcp3.as_raw_fd().to_string())
58                         .arg(tcp4.as_raw_fd().to_string())
59                         .arg(tcp5.as_raw_fd().to_string())
60                         .arg(tcp6.as_raw_fd().to_string())
61                         .arg(udp1.as_raw_fd().to_string())
62                         .arg(udp2.as_raw_fd().to_string())
63                         .arg(pipe1.as_raw_fd().to_string())
64                         .arg(pipe2.as_raw_fd().to_string())
65                         .arg(pipe3.as_raw_fd().to_string())
66                         .status()
67                         .unwrap();
68     assert!(status.success());
69     child.wait().unwrap();
70 }
71 
child(args: &[String])72 fn child(args: &[String]) {
73     let mut b = [0u8; 2];
74     for arg in &args[1..] {
75         let fd: libc::c_int = arg.parse().unwrap();
76         unsafe {
77             assert_eq!(libc::read(fd, b.as_mut_ptr() as *mut _, 2), -1);
78             assert_eq!(io::Error::last_os_error().raw_os_error(),
79                        Some(libc::EBADF));
80         }
81     }
82 }
83