@@ -5,7 +5,7 @@ use errno::Errno;
5
5
use fcntl:: { fcntl, OFlag , O_NONBLOCK , O_CLOEXEC , FD_CLOEXEC } ;
6
6
use fcntl:: FcntlArg :: { F_SETFD , F_SETFL } ;
7
7
use libc:: { c_char, c_void, c_int, size_t, pid_t, off_t} ;
8
- use std:: { mem, ptr } ;
8
+ use std:: mem;
9
9
use std:: ffi:: CString ;
10
10
use std:: os:: unix:: io:: RawFd ;
11
11
@@ -27,9 +27,19 @@ mod ffi {
27
27
// doc: http://man7.org/linux/man-pages/man2/chdir.2.html
28
28
pub fn chdir ( path : * const c_char ) -> c_int ;
29
29
30
+ // Execute PATH with arguments ARGV and environment from `environ'.
31
+ // doc: http://man7.org/linux/man-pages/man3/execv.3.html
32
+ pub fn execv ( path : * const c_char , argv : * const * const c_char ) -> c_int ;
33
+
30
34
// execute program
31
35
// doc: http://man7.org/linux/man-pages/man2/execve.2.html
32
- pub fn execve ( filename : * const c_char , argv : * const * const c_char , envp : * const * const c_char ) -> c_int ;
36
+ pub fn execve ( path : * const c_char , argv : * const * const c_char , envp : * const * const c_char ) -> c_int ;
37
+
38
+ // Execute FILE, searching in the `PATH' environment variable if it contains
39
+ // no slashes, with arguments ARGV and environment from `environ'.
40
+ // doc: http://man7.org/linux/man-pages/man3/execvp.3.html
41
+ pub fn execvp ( filename : * const c_char , argv : * const * const c_char ) -> c_int ;
42
+
33
43
// doc: http://man7.org/linux/man-pages/man3/exec.3.html
34
44
#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
35
45
#[ cfg( feature = "execvpe" ) ]
@@ -157,23 +167,47 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
157
167
return Ok ( ( ) )
158
168
}
159
169
160
- #[ inline]
161
- pub fn execve ( filename : & CString , args : & [ CString ] , env : & [ CString ] ) -> Result < ( ) > {
170
+ fn to_exec_array ( args : & [ CString ] ) -> * const * const c_char {
171
+ use std:: ptr;
172
+ use libc:: c_char;
173
+
162
174
let mut args_p: Vec < * const c_char > = args. iter ( ) . map ( |s| s. as_ptr ( ) ) . collect ( ) ;
163
175
args_p. push ( ptr:: null ( ) ) ;
176
+ args_p. as_ptr ( )
177
+ }
164
178
165
- let mut env_p: Vec < * const c_char > = env. iter ( ) . map ( |s| s. as_ptr ( ) ) . collect ( ) ;
166
- env_p. push ( ptr:: null ( ) ) ;
179
+ #[ inline]
180
+ pub fn execv ( path : & CString , argv : & [ CString ] ) -> Result < ( ) > {
181
+ let args_p = to_exec_array ( argv) ;
167
182
168
- let res = unsafe {
169
- ffi:: execve ( filename . as_ptr ( ) , args_p. as_ptr ( ) , env_p . as_ptr ( ) )
183
+ unsafe {
184
+ ffi:: execv ( path . as_ptr ( ) , args_p)
170
185
} ;
171
186
172
- if res != 0 {
173
- return Err ( Error :: Sys ( Errno :: last ( ) ) ) ;
174
- }
187
+ Err ( Error :: Sys ( Errno :: last ( ) ) )
188
+ }
175
189
176
- unreachable ! ( )
190
+ #[ inline]
191
+ pub fn execve ( path : & CString , args : & [ CString ] , env : & [ CString ] ) -> Result < ( ) > {
192
+ let args_p = to_exec_array ( args) ;
193
+ let env_p = to_exec_array ( env) ;
194
+
195
+ unsafe {
196
+ ffi:: execve ( path. as_ptr ( ) , args_p, env_p)
197
+ } ;
198
+
199
+ Err ( Error :: Sys ( Errno :: last ( ) ) )
200
+ }
201
+
202
+ #[ inline]
203
+ pub fn execvp ( filename : & CString , args : & [ CString ] ) -> Result < ( ) > {
204
+ let args_p = to_exec_array ( args) ;
205
+
206
+ unsafe {
207
+ ffi:: execvp ( filename. as_ptr ( ) , args_p)
208
+ } ;
209
+
210
+ Err ( Error :: Sys ( Errno :: last ( ) ) )
177
211
}
178
212
179
213
pub fn daemon ( nochdir : bool , noclose : bool ) -> Result < ( ) > {
@@ -360,14 +394,10 @@ mod linux {
360
394
let mut env_p: Vec < * const c_char > = env. iter ( ) . map ( |s| s. as_ptr ( ) ) . collect ( ) ;
361
395
env_p. push ( ptr:: null ( ) ) ;
362
396
363
- let res = unsafe {
397
+ unsafe {
364
398
super :: ffi:: execvpe ( filename. as_ptr ( ) , args_p. as_ptr ( ) , env_p. as_ptr ( ) )
365
399
} ;
366
400
367
- if res != 0 {
368
- return Err ( Error :: Sys ( Errno :: last ( ) ) ) ;
369
- }
370
-
371
- unreachable ! ( )
401
+ Err ( Error :: Sys ( Errno :: last ( ) ) )
372
402
}
373
403
}
0 commit comments