@@ -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