(
args: &ForkExecArgs<'_>,
procargs: ProcArgs<'_>,
ctx: &mut ExecErrorContext,
vm: &VirtualMachine,
)
| 272 | } |
| 273 | |
| 274 | fn exec_inner( |
| 275 | args: &ForkExecArgs<'_>, |
| 276 | procargs: ProcArgs<'_>, |
| 277 | ctx: &mut ExecErrorContext, |
| 278 | vm: &VirtualMachine, |
| 279 | ) -> nix::Result<Never> { |
| 280 | for &fd in args.fds_to_keep.as_slice() { |
| 281 | if fd.as_raw_fd() != args.errpipe_write.as_raw_fd() { |
| 282 | posix::set_inheritable(fd, true)? |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | for &fd in &[args.p2cwrite, args.c2pread, args.errread] { |
| 287 | if let MaybeFd::Valid(fd) = fd { |
| 288 | unistd::close(fd)?; |
| 289 | } |
| 290 | } |
| 291 | unistd::close(args.errpipe_read)?; |
| 292 | |
| 293 | let c2pwrite = match args.c2pwrite { |
| 294 | MaybeFd::Valid(c2pwrite) if c2pwrite.as_raw_fd() == 0 => { |
| 295 | let fd = unistd::dup(c2pwrite)?; |
| 296 | posix::set_inheritable(fd.as_fd(), true)?; |
| 297 | MaybeFd::Valid(fd.into()) |
| 298 | } |
| 299 | fd => fd, |
| 300 | }; |
| 301 | |
| 302 | let mut errwrite = args.errwrite; |
| 303 | loop { |
| 304 | match errwrite { |
| 305 | MaybeFd::Valid(fd) if fd.as_raw_fd() == 0 || fd.as_raw_fd() == 1 => { |
| 306 | let fd = unistd::dup(fd)?; |
| 307 | posix::set_inheritable(fd.as_fd(), true)?; |
| 308 | errwrite = MaybeFd::Valid(fd.into()); |
| 309 | } |
| 310 | _ => break, |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | fn dup_into_stdio<F>(fd: MaybeFd, io_fd: i32, dup2_stdio: F) -> nix::Result<()> |
| 315 | where |
| 316 | F: Fn(Fd) -> nix::Result<()>, |
| 317 | { |
| 318 | match fd { |
| 319 | MaybeFd::Valid(fd) if fd.as_raw_fd() == io_fd => { |
| 320 | posix::set_inheritable(fd.as_fd(), true) |
| 321 | } |
| 322 | MaybeFd::Valid(fd) => dup2_stdio(fd), |
| 323 | MaybeFd::Invalid => Ok(()), |
| 324 | } |
| 325 | } |
| 326 | dup_into_stdio(args.p2cread, 0, unistd::dup2_stdin)?; |
| 327 | dup_into_stdio(c2pwrite, 1, unistd::dup2_stdout)?; |
| 328 | dup_into_stdio(errwrite, 2, unistd::dup2_stderr)?; |
| 329 | |
| 330 | if let Some(ref cwd) = args.cwd { |
| 331 | unistd::chdir(cwd.s.as_c_str()).inspect_err(|_| *ctx = ExecErrorContext::ChDir)? |
no test coverage detected