Skip to content

[fuchsia] Migrate from launchpad to fdio_spawn_etc #51359

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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_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)
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