Skip to content

Commit d1d3455

Browse files
nikklassencarllerche
authored andcommitted
Add missing exec functions
1 parent 08a5528 commit d1d3455

File tree

1 file changed

+48
-18
lines changed

1 file changed

+48
-18
lines changed

src/unistd.rs

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use errno::Errno;
55
use fcntl::{fcntl, OFlag, O_NONBLOCK, O_CLOEXEC, FD_CLOEXEC};
66
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
77
use libc::{c_char, c_void, c_int, size_t, pid_t, off_t};
8-
use std::{mem, ptr};
8+
use std::mem;
99
use std::ffi::CString;
1010
use std::os::unix::io::RawFd;
1111

@@ -27,9 +27,19 @@ mod ffi {
2727
// doc: http://man7.org/linux/man-pages/man2/chdir.2.html
2828
pub fn chdir(path: *const c_char) -> c_int;
2929

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+
3034
// execute program
3135
// 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+
3343
// doc: http://man7.org/linux/man-pages/man3/exec.3.html
3444
#[cfg(any(target_os = "linux", target_os = "android"))]
3545
#[cfg(feature = "execvpe")]
@@ -157,23 +167,47 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
157167
return Ok(())
158168
}
159169

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+
162174
let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
163175
args_p.push(ptr::null());
176+
args_p.as_ptr()
177+
}
164178

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);
167182

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)
170185
};
171186

172-
if res != 0 {
173-
return Err(Error::Sys(Errno::last()));
174-
}
187+
Err(Error::Sys(Errno::last()))
188+
}
175189

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()))
177211
}
178212

179213
pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
@@ -360,14 +394,10 @@ mod linux {
360394
let mut env_p: Vec<*const c_char> = env.iter().map(|s| s.as_ptr()).collect();
361395
env_p.push(ptr::null());
362396

363-
let res = unsafe {
397+
unsafe {
364398
super::ffi::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
365399
};
366400

367-
if res != 0 {
368-
return Err(Error::Sys(Errno::last()));
369-
}
370-
371-
unreachable!()
401+
Err(Error::Sys(Errno::last()))
372402
}
373403
}

0 commit comments

Comments
 (0)