Skip to content

Commit

Permalink
Rollup merge of #51359 - cramertj:fdio_spawn, r=sfackler
Browse files Browse the repository at this point in the history
[fuchsia] Migrate from launchpad to fdio_spawn_etc

fdio_spawn_etc is the preferred way of creating processes on Fuchsia
now.

cc @abarth
  • Loading branch information
Mark-Simulacrum authored Jun 5, 2018
2 parents 7d0d7ea + aa23aba commit 5f2de72
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 110 deletions.
1 change: 0 additions & 1 deletion src/libstd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
75 changes: 28 additions & 47 deletions src/libstd/sys/unix/process/process_fuchsia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_SHARE_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)
Expand Down
85 changes: 23 additions & 62 deletions src/libstd/sys/unix/process/zircon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 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;
}

pub fn launchpad_load_vdso(lp: *mut launchpad_t, vmo: zx_handle_t) -> zx_status_t;
// fdio_spawn_etc flags

pub fn launchpad_vmo_from_file(filename: *const c_char) -> zx_handle_t;
}
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;

// Launchpad clone constants
// fdio_spawn_etc actions

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_ACTION_CLONE_FD: u32 = 0x0001;
pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;

// Errors

Expand Down

0 comments on commit 5f2de72

Please sign in to comment.