From 403701f97628b85bfa3e5ec0e5ca82b81d53ba1e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 30 Aug 2019 11:51:04 -0700 Subject: [PATCH] Don't try to use /dev/null on Fuchsia --- src/libstd/sys/unix/process/process_common.rs | 28 +++++++++++++++++-- .../sys/unix/process/process_fuchsia.rs | 15 ++++++---- src/libstd/sys/unix/process/zircon.rs | 2 +- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 6bb20bbe087..511e6784080 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -1,19 +1,27 @@ use crate::os::unix::prelude::*; -use crate::ffi::{OsString, OsStr, CString, CStr}; +use crate::ffi::{OsString, OsStr, CString}; use crate::fmt; use crate::io; use crate::ptr; use crate::sys::fd::FileDesc; -use crate::sys::fs::{File, OpenOptions}; +use crate::sys::fs::File; use crate::sys::pipe::{self, AnonPipe}; use crate::sys_common::process::{CommandEnv, DefaultEnvKey}; use crate::collections::BTreeMap; +#[cfg(not(target_os = "fuchsia"))] +use { + crate::ffi::CStr, + crate::sys::fs::OpenOptions, +}; + use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE}; cfg_if::cfg_if! { - if #[cfg(target_os = "redox")] { + if #[cfg(target_os = "fuchsia")] { + // fuchsia doesn't have /dev/null + } else if #[cfg(target_os = "redox")] { const DEV_NULL: &'static str = "null:\0"; } else { const DEV_NULL: &'static str = "/dev/null\0"; @@ -83,6 +91,11 @@ pub enum ChildStdio { Inherit, Explicit(c_int), Owned(FileDesc), + + // On Fuchsia, null stdio is the default, so we simply don't specify + // any actions at the time of spawning. + #[cfg(target_os = "fuchsia")] + Null, } pub enum Stdio { @@ -301,6 +314,7 @@ pub fn to_child_stdio(&self, readable: bool) Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours))) } + #[cfg(not(target_os = "fuchsia"))] Stdio::Null => { let mut opts = OpenOptions::new(); opts.read(readable); @@ -311,6 +325,11 @@ pub fn to_child_stdio(&self, readable: bool) let fd = File::open_c(&path, &opts)?; Ok((ChildStdio::Owned(fd.into_fd()), None)) } + + #[cfg(target_os = "fuchsia")] + Stdio::Null => { + Ok((ChildStdio::Null, None)) + } } } } @@ -333,6 +352,9 @@ pub fn fd(&self) -> Option { ChildStdio::Inherit => None, ChildStdio::Explicit(fd) => Some(fd), ChildStdio::Owned(ref fd) => Some(fd.raw()), + + #[cfg(target_os = "fuchsia")] + ChildStdio::Null => None, } } } diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs index 7c6be9b0a60..295ec59eb32 100644 --- a/src/libstd/sys/unix/process/process_fuchsia.rs +++ b/src/libstd/sys/unix/process/process_fuchsia.rs @@ -52,7 +52,7 @@ unsafe fn do_exec(&mut self, stdio: ChildPipes, maybe_envp: Option<&CStringArray None => ptr::null(), }; - let transfer_or_clone = |opt_fd, target_fd| if let Some(local_fd) = opt_fd { + let make_action = |local_io: &ChildStdio, target_fd| if let Some(local_fd) = local_io.fd() { fdio_spawn_action_t { action: FDIO_SPAWN_ACTION_TRANSFER_FD, local_fd, @@ -60,6 +60,10 @@ unsafe fn do_exec(&mut self, stdio: ChildPipes, maybe_envp: Option<&CStringArray ..Default::default() } } else { + if let ChildStdio::Null = local_io { + // acts as no-op + return Default::default(); + } fdio_spawn_action_t { action: FDIO_SPAWN_ACTION_CLONE_FD, local_fd: target_fd, @@ -69,9 +73,9 @@ unsafe fn do_exec(&mut self, stdio: ChildPipes, maybe_envp: Option<&CStringArray }; // Clone stdin, stdout, and stderr - let action1 = transfer_or_clone(stdio.stdin.fd(), 0); - let action2 = transfer_or_clone(stdio.stdout.fd(), 1); - let action3 = transfer_or_clone(stdio.stderr.fd(), 2); + let action1 = make_action(&stdio.stdin, 0); + let action2 = make_action(&stdio.stdout, 1); + let action3 = make_action(&stdio.stderr, 2); let actions = [action1, action2, action3]; // We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc @@ -86,7 +90,8 @@ unsafe fn do_exec(&mut self, stdio: ChildPipes, maybe_envp: Option<&CStringArray zx_cvt(fdio_spawn_etc( 0, FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE, - self.get_argv()[0], self.get_argv().as_ptr(), envp, 3, actions.as_ptr(), + self.get_argv()[0], self.get_argv().as_ptr(), envp, + actions.len() as size_t, actions.as_ptr(), &mut process_handle, ptr::null_mut(), ))?; diff --git a/src/libstd/sys/unix/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs index 9224bef7c4a..29032f5e0d2 100644 --- a/src/libstd/sys/unix/process/zircon.rs +++ b/src/libstd/sys/unix/process/zircon.rs @@ -120,7 +120,7 @@ pub struct fdio_spawn_action_t { extern { pub fn fdio_spawn_etc(job: zx_handle_t, flags: u32, path: *const c_char, argv: *const *const c_char, envp: *const *const c_char, - action_count: u64, actions: *const fdio_spawn_action_t, + action_count: size_t, actions: *const fdio_spawn_action_t, process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t; }