1 // Copyright 2021, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 use command_fds::{CommandFdExt, FdMapping};
16 use std::fs::{read_dir, read_link, File};
17 use std::os::unix::io::AsRawFd;
18 use std::os::unix::process::CommandExt;
19 use std::process::Command;
20 use std::thread::sleep;
21 use std::time::Duration;
22
23 /// Print out a list of all open file descriptors.
list_fds()24 fn list_fds() {
25 let dir = read_dir("/proc/self/fd").unwrap();
26 for entry in dir {
27 let entry = entry.unwrap();
28 let target = read_link(entry.path()).unwrap();
29 println!("{:?} {:?}", entry, target);
30 }
31 }
32
main()33 fn main() {
34 list_fds();
35
36 // Open a file.
37 let file = File::open("Cargo.toml").unwrap();
38 println!("File: {:?}", file);
39 list_fds();
40
41 // Prepare to run `ls -l /proc/self/fd` with some FDs mapped.
42 let mut command = Command::new("ls");
43 command.arg("-l").arg("/proc/self/fd");
44 command
45 .fd_mappings(vec![
46 // Map `file` as FD 3 in the child process.
47 FdMapping {
48 parent_fd: file.as_raw_fd(),
49 child_fd: 3,
50 },
51 // Map this process's stdin as FD 5 in the child process.
52 FdMapping {
53 parent_fd: 0,
54 child_fd: 5,
55 },
56 ])
57 .unwrap();
58 unsafe {
59 command.pre_exec(move || {
60 println!("pre_exec");
61 list_fds();
62 Ok(())
63 });
64 }
65
66 // Spawn the child process.
67 println!("Spawning command");
68 let mut child = command.spawn().unwrap();
69 sleep(Duration::from_millis(100));
70 println!("Spawned");
71 list_fds();
72
73 println!("Waiting for command");
74 println!("{:?}", child.wait().unwrap());
75 }
76