]> git.proxmox.com Git - rustc.git/blob - src/test/ui/command/command-pre-exec.rs
New upstream version 1.56.0~beta.4+dfsg1
[rustc.git] / src / test / ui / command / command-pre-exec.rs
1 // run-pass
2 // revisions: mir thir
3 // [thir]compile-flags: -Zthir-unsafeck
4
5 #![allow(stable_features)]
6 // ignore-windows - this is a unix-specific test
7 // ignore-emscripten no processes
8 // ignore-sgx no processes
9 #![feature(process_exec, rustc_private)]
10
11 use std::env;
12 use std::io::Error;
13 use std::os::unix::process::CommandExt;
14 use std::process::Command;
15 use std::sync::atomic::{AtomicUsize, Ordering};
16 use std::sync::Arc;
17
18 #[cfg(not(target_os = "linux"))]
19 fn getpid() -> u32 {
20 use std::process;
21 process::id()
22 }
23
24 /// We need to directly use the getpid syscall instead of using `process::id()`
25 /// because the libc wrapper might return incorrect values after a process was
26 /// forked.
27 #[cfg(target_os = "linux")]
28 fn getpid() -> u32 {
29 extern crate libc;
30 unsafe {
31 libc::syscall(libc::SYS_getpid) as _
32 }
33 }
34
35 fn main() {
36 if let Some(arg) = env::args().nth(1) {
37 match &arg[..] {
38 "test1" => println!("hello2"),
39 "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"),
40 "test3" => assert_eq!(env::current_dir().unwrap().to_str().unwrap(), "/"),
41 "empty" => {}
42 _ => panic!("unknown argument: {}", arg),
43 }
44 return;
45 }
46
47 let me = env::current_exe().unwrap();
48
49 let output = unsafe {
50 Command::new(&me)
51 .arg("test1")
52 .pre_exec(|| {
53 println!("hello");
54 Ok(())
55 })
56 .output()
57 .unwrap()
58 };
59 assert!(output.status.success());
60 assert!(output.stderr.is_empty());
61 assert_eq!(output.stdout, b"hello\nhello2\n");
62
63 let output = unsafe {
64 Command::new(&me)
65 .arg("test3")
66 .pre_exec(|| {
67 env::set_current_dir("/").unwrap();
68 Ok(())
69 })
70 .output()
71 .unwrap()
72 };
73 assert!(output.status.success());
74 assert!(output.stderr.is_empty());
75 assert!(output.stdout.is_empty());
76
77 let output = unsafe {
78 Command::new(&me)
79 .arg("bad")
80 .pre_exec(|| Err(Error::from_raw_os_error(102)))
81 .output()
82 .unwrap_err()
83 };
84 assert_eq!(output.raw_os_error(), Some(102));
85
86 let pid = getpid();
87 let output = unsafe {
88 Command::new(&me)
89 .arg("empty")
90 .pre_exec(move || {
91 let child = getpid();
92 assert!(pid != child);
93 Ok(())
94 })
95 .output()
96 .unwrap()
97 };
98 assert!(output.status.success());
99 assert!(output.stderr.is_empty());
100 assert!(output.stdout.is_empty());
101
102 let mem = Arc::new(AtomicUsize::new(0));
103 let mem2 = mem.clone();
104 let output = unsafe {
105 Command::new(&me)
106 .arg("empty")
107 .pre_exec(move || {
108 assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0);
109 Ok(())
110 })
111 .output()
112 .unwrap()
113 };
114 assert!(output.status.success());
115 assert!(output.stderr.is_empty());
116 assert!(output.stdout.is_empty());
117 assert_eq!(mem.load(Ordering::SeqCst), 0);
118 }