fuchsia: Don't fail to spawn if no stdin exists

This commit is contained in:
Tyler Mandry 2019-08-30 18:21:57 -07:00
parent 403701f976
commit 7bfa2be4ef
2 changed files with 41 additions and 22 deletions

View File

@ -52,30 +52,45 @@ impl Command {
None => ptr::null(),
};
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,
target_fd,
..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,
target_fd,
..Default::default()
let make_action = |local_io: &ChildStdio, target_fd| -> io::Result<fdio_spawn_action_t> {
if let Some(local_fd) = local_io.fd() {
Ok(fdio_spawn_action_t {
action: FDIO_SPAWN_ACTION_TRANSFER_FD,
local_fd,
target_fd,
..Default::default()
})
} else {
if let ChildStdio::Null = local_io {
// acts as no-op
return Ok(Default::default());
}
let mut handle = ZX_HANDLE_INVALID;
let status = fdio_fd_clone(target_fd, &mut handle);
if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED {
// This descriptor is closed; skip it rather than generating an
// error.
return Ok(Default::default());
}
zx_cvt(status)?;
let mut cloned_fd = 0;
zx_cvt(fdio_fd_create(handle, &mut cloned_fd))?;
Ok(fdio_spawn_action_t {
action: FDIO_SPAWN_ACTION_TRANSFER_FD,
local_fd: cloned_fd as i32,
target_fd,
..Default::default()
})
}
};
// Clone stdin, stdout, and stderr
let action1 = make_action(&stdio.stdin, 0);
let action2 = make_action(&stdio.stdout, 1);
let action3 = make_action(&stdio.stderr, 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
@ -88,7 +103,7 @@ impl Command {
let mut process_handle: zx_handle_t = 0;
zx_cvt(fdio_spawn_etc(
0,
ZX_HANDLE_INVALID,
FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE,
self.get_argv()[0], self.get_argv().as_ptr(), envp,
actions.len() as size_t, actions.as_ptr(),

View File

@ -2,8 +2,9 @@
use crate::convert::TryInto;
use crate::io;
use crate::os::raw::c_char;
use crate::i64;
use crate::mem::MaybeUninit;
use crate::os::raw::c_char;
use libc::{c_int, c_void, size_t};
@ -122,6 +123,9 @@ extern {
argv: *const *const c_char, envp: *const *const c_char,
action_count: size_t, actions: *const fdio_spawn_action_t,
process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t;
pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t;
pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t;
}
// fdio_spawn_etc flags