1 use std::os::unix::prelude::RawFd; 2 3 use tokio::process::Command; 4 use tokio_crate as tokio; 5 6 use crate::{map_fds, preserve_fds, validate_child_fds, FdMapping, FdMappingCollision}; 7 8 /// Extension to add file descriptor mappings to a [`Command`]. 9 pub trait CommandFdAsyncExt { 10 /// Adds the given set of file descriptors to the command. 11 /// 12 /// Warning: Calling this more than once on the same command, or attempting to run the same 13 /// command more than once after calling this, may result in unexpected behaviour. fd_mappings(&mut self, mappings: Vec<FdMapping>) -> Result<&mut Self, FdMappingCollision>14 fn fd_mappings(&mut self, mappings: Vec<FdMapping>) -> Result<&mut Self, FdMappingCollision>; 15 16 /// Adds the given set of file descriptors to be passed on to the child process when the command 17 /// is run. preserved_fds(&mut self, fds: Vec<RawFd>) -> &mut Self18 fn preserved_fds(&mut self, fds: Vec<RawFd>) -> &mut Self; 19 } 20 21 impl CommandFdAsyncExt for Command { fd_mappings( &mut self, mut mappings: Vec<FdMapping>, ) -> Result<&mut Self, FdMappingCollision>22 fn fd_mappings( 23 &mut self, 24 mut mappings: Vec<FdMapping>, 25 ) -> Result<&mut Self, FdMappingCollision> { 26 let child_fds = validate_child_fds(&mappings)?; 27 28 unsafe { 29 self.pre_exec(move || map_fds(&mut mappings, &child_fds)); 30 } 31 32 Ok(self) 33 } 34 preserved_fds(&mut self, fds: Vec<RawFd>) -> &mut Self35 fn preserved_fds(&mut self, fds: Vec<RawFd>) -> &mut Self { 36 unsafe { 37 self.pre_exec(move || preserve_fds(&fds)); 38 } 39 40 self 41 } 42 } 43