command_close/
command-close.rs1use std::fs;
2use std::os::unix::prelude::*;
3use std::process::Command;
4
5fn unset_cloexec(fd: RawFd) {
6 let flags = unsafe { libc::fcntl(fd, libc::F_GETFD) };
7 assert!(flags >= 0);
8
9 if flags & libc::FD_CLOEXEC != 0 {
10 assert_eq!(
11 unsafe { libc::fcntl(fd, libc::F_SETFD, flags & !libc::FD_CLOEXEC) },
12 0
13 );
14 }
15}
16
17fn main() {
18 let f1 = fs::File::open("/").unwrap();
20 let f2 = fs::File::open("/").unwrap();
21 let f3 = fs::File::open("/").unwrap();
22 unset_cloexec(f1.as_raw_fd());
23 unset_cloexec(f2.as_raw_fd());
24 unset_cloexec(f3.as_raw_fd());
25
26 let mut keep_fds = [f1.as_raw_fd(), f3.as_raw_fd()];
27 keep_fds.sort_unstable();
29
30 let mut cmd = Command::new("true");
31
32 unsafe {
33 cmd.pre_exec(move || {
34 #[cfg(any(target_os = "macos", target_os = "ios"))]
39 close_fds::set_fds_cloexec(3, &keep_fds);
40 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
41 close_fds::close_open_fds(3, &keep_fds);
42
43 Ok(())
44 });
45 }
46
47 cmd.status().unwrap();
48}