• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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