fuchsia: Don't fail to spawn if no stdin exists
This commit is contained in:
parent
403701f976
commit
7bfa2be4ef
@ -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(),
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user