blob: b399dc7fb5eb523041b7b091de812e748dd3e7a2 [file] [log] [blame]
// Copyright 2021, The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use command_fds::{CommandFdExt, FdMapping};
use std::fs::{read_dir, read_link, File};
use std::os::unix::io::AsRawFd;
use std::os::unix::process::CommandExt;
use std::process::Command;
use std::thread::sleep;
use std::time::Duration;
/// Print out a list of all open file descriptors.
fn list_fds() {
let dir = read_dir("/proc/self/fd").unwrap();
for entry in dir {
let entry = entry.unwrap();
let target = read_link(entry.path()).unwrap();
println!("{:?} {:?}", entry, target);
}
}
fn main() {
list_fds();
// Open a file.
let file = File::open("Cargo.toml").unwrap();
println!("File: {:?}", file);
list_fds();
// Prepare to run `ls -l /proc/self/fd` with some FDs mapped.
let mut command = Command::new("ls");
command.arg("-l").arg("/proc/self/fd");
command
.fd_mappings(vec![
// Map `file` as FD 3 in the child process.
FdMapping {
parent_fd: file.as_raw_fd(),
child_fd: 3,
},
// Map this process's stdin as FD 5 in the child process.
FdMapping {
parent_fd: 0,
child_fd: 5,
},
])
.unwrap();
unsafe {
command.pre_exec(move || {
println!("pre_exec");
list_fds();
Ok(())
});
}
// Spawn the child process.
println!("Spawning command");
let mut child = command.spawn().unwrap();
sleep(Duration::from_millis(100));
println!("Spawned");
list_fds();
println!("Waiting for command");
println!("{:?}", child.wait().unwrap());
}