Auto merge of #51359 - cramertj:fdio_spawn, r=sfackler
[fuchsia] Migrate from launchpad to fdio_spawn_etc fdio_spawn_etc is the preferred way of creating processes on Fuchsia now. cc @abarth
This commit is contained in:
@@ -74,7 +74,6 @@ fn main() {
|
||||
}
|
||||
println!("cargo:rustc-link-lib=zircon");
|
||||
println!("cargo:rustc-link-lib=fdio");
|
||||
println!("cargo:rustc-link-lib=launchpad"); // for std::process
|
||||
} else if target.contains("cloudabi") {
|
||||
if cfg!(feature = "backtrace") {
|
||||
println!("cargo:rustc-link-lib=unwind");
|
||||
|
||||
@@ -56,68 +56,49 @@ impl Command {
|
||||
-> io::Result<zx_handle_t> {
|
||||
use sys::process::zircon::*;
|
||||
|
||||
let job_handle = zx_job_default();
|
||||
let envp = match maybe_envp {
|
||||
Some(envp) => envp.as_ptr(),
|
||||
None => ptr::null(),
|
||||
};
|
||||
|
||||
// To make sure launchpad_destroy gets called on the launchpad if this function fails
|
||||
struct LaunchpadDestructor(*mut launchpad_t);
|
||||
impl Drop for LaunchpadDestructor {
|
||||
fn drop(&mut self) { unsafe { launchpad_destroy(self.0); } }
|
||||
}
|
||||
|
||||
// Duplicate the job handle
|
||||
let mut job_copy: zx_handle_t = ZX_HANDLE_INVALID;
|
||||
zx_cvt(zx_handle_duplicate(job_handle, ZX_RIGHT_SAME_RIGHTS, &mut job_copy))?;
|
||||
// Create a launchpad
|
||||
let mut launchpad: *mut launchpad_t = ptr::null_mut();
|
||||
zx_cvt(launchpad_create(job_copy, self.get_argv()[0], &mut launchpad))?;
|
||||
let launchpad_destructor = LaunchpadDestructor(launchpad);
|
||||
|
||||
// Set the process argv
|
||||
zx_cvt(launchpad_set_args(launchpad, self.get_argv().len() as i32 - 1,
|
||||
self.get_argv().as_ptr()))?;
|
||||
// Setup the environment vars
|
||||
zx_cvt(launchpad_set_environ(launchpad, envp))?;
|
||||
zx_cvt(launchpad_add_vdso_vmo(launchpad))?;
|
||||
// Load the executable
|
||||
zx_cvt(launchpad_elf_load(launchpad, launchpad_vmo_from_file(self.get_argv()[0])))?;
|
||||
zx_cvt(launchpad_load_vdso(launchpad, ZX_HANDLE_INVALID))?;
|
||||
zx_cvt(launchpad_clone(launchpad, LP_CLONE_FDIO_NAMESPACE | LP_CLONE_FDIO_CWD))?;
|
||||
let transfer_or_clone = |opt_fd, target_fd| if let Some(local_fd) = opt_fd {
|
||||
fdio_spawn_action_t {
|
||||
action: FDIO_SPAWN_ACTION_TRANSFER_FD,
|
||||
local_fd,
|
||||
target_fd,
|
||||
..Default::default()
|
||||
}
|
||||
} else {
|
||||
fdio_spawn_action_t {
|
||||
action: FDIO_SPAWN_ACTION_CLONE_FD,
|
||||
local_fd: target_fd,
|
||||
target_fd,
|
||||
..Default::default()
|
||||
}
|
||||
};
|
||||
|
||||
// Clone stdin, stdout, and stderr
|
||||
if let Some(fd) = stdio.stdin.fd() {
|
||||
zx_cvt(launchpad_transfer_fd(launchpad, fd, 0))?;
|
||||
} else {
|
||||
zx_cvt(launchpad_clone_fd(launchpad, 0, 0))?;
|
||||
}
|
||||
if let Some(fd) = stdio.stdout.fd() {
|
||||
zx_cvt(launchpad_transfer_fd(launchpad, fd, 1))?;
|
||||
} else {
|
||||
zx_cvt(launchpad_clone_fd(launchpad, 1, 1))?;
|
||||
}
|
||||
if let Some(fd) = stdio.stderr.fd() {
|
||||
zx_cvt(launchpad_transfer_fd(launchpad, fd, 2))?;
|
||||
} else {
|
||||
zx_cvt(launchpad_clone_fd(launchpad, 2, 2))?;
|
||||
}
|
||||
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 actions = [action1, action2, action3];
|
||||
|
||||
// We don't want FileDesc::drop to be called on any stdio. It would close their fds. The
|
||||
// fds will be closed once the child process finishes.
|
||||
// We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc
|
||||
// always consumes transferred file descriptors.
|
||||
mem::forget(stdio);
|
||||
|
||||
for callback in self.get_closures().iter_mut() {
|
||||
callback()?;
|
||||
}
|
||||
|
||||
// `launchpad_go` destroys the launchpad, so we must not
|
||||
mem::forget(launchpad_destructor);
|
||||
|
||||
let mut process_handle: zx_handle_t = 0;
|
||||
let mut err_msg: *const libc::c_char = ptr::null();
|
||||
zx_cvt(launchpad_go(launchpad, &mut process_handle, &mut err_msg))?;
|
||||
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(),
|
||||
&mut process_handle,
|
||||
ptr::null_mut(),
|
||||
))?;
|
||||
// FIXME: See if we want to do something with that err_msg
|
||||
|
||||
Ok(process_handle)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_camel_case_types, unused)]
|
||||
|
||||
use convert::TryInto;
|
||||
use io;
|
||||
@@ -117,75 +117,36 @@ extern {
|
||||
avail: *mut size_t) -> zx_status_t;
|
||||
}
|
||||
|
||||
// From `enum special_handles` in system/ulib/launchpad/launchpad.c
|
||||
// HND_LOADER_SVC = 0
|
||||
// HND_EXEC_VMO = 1
|
||||
// HND_SEGMENTS_VMAR = 2
|
||||
const HND_SPECIAL_COUNT: c_int = 3;
|
||||
|
||||
#[derive(Default)]
|
||||
#[repr(C)]
|
||||
pub struct launchpad_t {
|
||||
argc: u32,
|
||||
envc: u32,
|
||||
args: *const c_char,
|
||||
args_len: size_t,
|
||||
env: *const c_char,
|
||||
env_len: size_t,
|
||||
|
||||
handles: *mut zx_handle_t,
|
||||
handles_info: *mut u32,
|
||||
handle_count: size_t,
|
||||
handle_alloc: size_t,
|
||||
|
||||
entry: zx_vaddr_t,
|
||||
base: zx_vaddr_t,
|
||||
vdso_base: zx_vaddr_t,
|
||||
|
||||
stack_size: size_t,
|
||||
|
||||
special_handles: [zx_handle_t; HND_SPECIAL_COUNT as usize],
|
||||
loader_message: bool,
|
||||
pub struct fdio_spawn_action_t {
|
||||
pub action: u32,
|
||||
pub reserved0: u32,
|
||||
pub local_fd: i32,
|
||||
pub target_fd: i32,
|
||||
pub reserved1: u64,
|
||||
}
|
||||
|
||||
extern {
|
||||
pub fn launchpad_create(job: zx_handle_t, name: *const c_char,
|
||||
lp: *mut *mut launchpad_t) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_go(lp: *mut launchpad_t,
|
||||
proc_handle: *mut zx_handle_t,
|
||||
err_msg: *mut *const c_char) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_destroy(lp: *mut launchpad_t);
|
||||
|
||||
pub fn launchpad_set_args(lp: *mut launchpad_t, argc: c_int,
|
||||
argv: *const *const c_char) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_set_environ(lp: *mut launchpad_t, envp: *const *const c_char) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_clone(lp: *mut launchpad_t, what: u32) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_clone_fd(lp: *mut launchpad_t, fd: c_int, target_fd: c_int) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_transfer_fd(lp: *mut launchpad_t, fd: c_int, target_fd: c_int) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_elf_load(lp: *mut launchpad_t, vmo: zx_handle_t) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_add_vdso_vmo(lp: *mut launchpad_t) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_load_vdso(lp: *mut launchpad_t, vmo: zx_handle_t) -> zx_status_t;
|
||||
|
||||
pub fn launchpad_vmo_from_file(filename: *const c_char) -> zx_handle_t;
|
||||
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,
|
||||
process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t;
|
||||
}
|
||||
|
||||
// Launchpad clone constants
|
||||
// fdio_spawn_etc flags
|
||||
|
||||
pub const LP_CLONE_FDIO_NAMESPACE: u32 = 0x0001;
|
||||
pub const LP_CLONE_FDIO_CWD: u32 = 0x0002;
|
||||
// LP_CLONE_FDIO_STDIO = 0x0004
|
||||
// LP_CLONE_FDIO_ALL = 0x00FF
|
||||
// LP_CLONE_ENVIRON = 0x0100
|
||||
// LP_CLONE_DEFAULT_JOB = 0x0200
|
||||
// LP_CLONE_ALL = 0xFFFF
|
||||
pub const FDIO_SPAWN_CLONE_JOB: u32 = 0x0001;
|
||||
pub const FDIO_SPAWN_CLONE_LDSVC: u32 = 0x0002;
|
||||
pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004;
|
||||
pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008;
|
||||
pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010;
|
||||
pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF;
|
||||
|
||||
// fdio_spawn_etc actions
|
||||
|
||||
pub const FDIO_SPAWN_ACTION_CLONE_FD: u32 = 0x0001;
|
||||
pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;
|
||||
|
||||
// Errors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user