@@ -56,68 +56,49 @@ impl Command {
56
56
-> io::Result<zx_handle_t> {
57
57
use sys::process::zircon::*;
58
58
59
- let job_handle = zx_job_default();
60
59
let envp = match maybe_envp {
61
60
Some(envp) => envp.as_ptr(),
62
61
None => ptr::null(),
63
62
};
64
63
65
- // To make sure launchpad_destroy gets called on the launchpad if this function fails
66
- struct LaunchpadDestructor(*mut launchpad_t);
67
- impl Drop for LaunchpadDestructor {
68
- fn drop(&mut self) { unsafe { launchpad_destroy(self.0); } }
69
- }
70
-
71
- // Duplicate the job handle
72
- let mut job_copy: zx_handle_t = ZX_HANDLE_INVALID;
73
- zx_cvt(zx_handle_duplicate(job_handle, ZX_RIGHT_SAME_RIGHTS, &mut job_copy))?;
74
- // Create a launchpad
75
- let mut launchpad: *mut launchpad_t = ptr::null_mut();
76
- zx_cvt(launchpad_create(job_copy, self.get_argv()[0], &mut launchpad))?;
77
- let launchpad_destructor = LaunchpadDestructor(launchpad);
78
-
79
- // Set the process argv
80
- zx_cvt(launchpad_set_args(launchpad, self.get_argv().len() as i32 - 1,
81
- self.get_argv().as_ptr()))?;
82
- // Setup the environment vars
83
- zx_cvt(launchpad_set_environ(launchpad, envp))?;
84
- zx_cvt(launchpad_add_vdso_vmo(launchpad))?;
85
- // Load the executable
86
- zx_cvt(launchpad_elf_load(launchpad, launchpad_vmo_from_file(self.get_argv()[0])))?;
87
- zx_cvt(launchpad_load_vdso(launchpad, ZX_HANDLE_INVALID))?;
88
- zx_cvt(launchpad_clone(launchpad, LP_CLONE_FDIO_NAMESPACE | LP_CLONE_FDIO_CWD))?;
64
+ let transfer_or_clone = |opt_fd, target_fd| if let Some(local_fd) = opt_fd {
65
+ fdio_spawn_action_t {
66
+ action: FDIO_SPAWN_ACTION_TRANSFER_FD,
67
+ local_fd,
68
+ target_fd,
69
+ ..Default::default()
70
+ }
71
+ } else {
72
+ fdio_spawn_action_t {
73
+ action: FDIO_SPAWN_ACTION_CLONE_FD,
74
+ local_fd: target_fd,
75
+ target_fd,
76
+ ..Default::default()
77
+ }
78
+ };
89
79
90
80
// Clone stdin, stdout, and stderr
91
- if let Some(fd) = stdio.stdin.fd() {
92
- zx_cvt(launchpad_transfer_fd(launchpad, fd, 0))?;
93
- } else {
94
- zx_cvt(launchpad_clone_fd(launchpad, 0, 0))?;
95
- }
96
- if let Some(fd) = stdio.stdout.fd() {
97
- zx_cvt(launchpad_transfer_fd(launchpad, fd, 1))?;
98
- } else {
99
- zx_cvt(launchpad_clone_fd(launchpad, 1, 1))?;
100
- }
101
- if let Some(fd) = stdio.stderr.fd() {
102
- zx_cvt(launchpad_transfer_fd(launchpad, fd, 2))?;
103
- } else {
104
- zx_cvt(launchpad_clone_fd(launchpad, 2, 2))?;
105
- }
81
+ let action1 = transfer_or_clone(stdio.stdin.fd(), 0);
82
+ let action2 = transfer_or_clone(stdio.stdout.fd(), 1);
83
+ let action3 = transfer_or_clone(stdio.stderr.fd(), 2);
84
+ let actions = [action1, action2, action3];
106
85
107
- // We don't want FileDesc::drop to be called on any stdio. It would close their fds. The
108
- // fds will be closed once the child process finishes .
86
+ // We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc
87
+ // always consumes transferred file descriptors .
109
88
mem::forget(stdio);
110
89
111
90
for callback in self.get_closures().iter_mut() {
112
91
callback()?;
113
92
}
114
93
115
- // `launchpad_go` destroys the launchpad, so we must not
116
- mem::forget(launchpad_destructor);
117
-
118
94
let mut process_handle: zx_handle_t = 0;
119
- let mut err_msg: *const libc::c_char = ptr::null();
120
- zx_cvt(launchpad_go(launchpad, &mut process_handle, &mut err_msg))?;
95
+ zx_cvt(fdio_spawn_etc(
96
+ 0,
97
+ FDIO_SPAWN_SHARE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE,
98
+ self.get_argv()[0], self.get_argv().as_ptr(), envp, 3, actions.as_ptr(),
99
+ &mut process_handle,
100
+ ptr::null_mut(),
101
+ ))?;
121
102
// FIXME: See if we want to do something with that err_msg
122
103
123
104
Ok(process_handle)
0 commit comments