@@ -56,68 +56,49 @@ impl Command {
5656 -> io:: Result < zx_handle_t > {
5757 use sys:: process:: zircon:: * ;
5858
59- let job_handle = zx_job_default ( ) ;
6059 let envp = match maybe_envp {
6160 Some ( envp) => envp. as_ptr ( ) ,
6261 None => ptr:: null ( ) ,
6362 } ;
6463
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+ } ;
8979
9080 // 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] ;
10685
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 .
10988 mem:: forget ( stdio) ;
11089
11190 for callback in self . get_closures ( ) . iter_mut ( ) {
11291 callback ( ) ?;
11392 }
11493
115- // `launchpad_go` destroys the launchpad, so we must not
116- mem:: forget ( launchpad_destructor) ;
117-
11894 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_CLONE_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+ ) ) ?;
121102 // FIXME: See if we want to do something with that err_msg
122103
123104 Ok ( process_handle)
0 commit comments