Skip to content

Commit 21ed20a

Browse files
committed
fix #1093
1 parent 1662466 commit 21ed20a

File tree

2 files changed

+20
-21
lines changed

2 files changed

+20
-21
lines changed

src/unistd.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use fcntl::FcntlArg::F_SETFD;
77
use libc::{self, c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t,
88
uid_t, gid_t, mode_t};
99
use std::{fmt, mem, ptr};
10-
use std::ffi::{CString, CStr, OsString, OsStr};
10+
use std::ffi::{CStr, OsString, OsStr};
1111
use std::os::unix::ffi::{OsStringExt, OsStrExt};
1212
use std::os::unix::io::RawFd;
1313
use std::path::PathBuf;
@@ -663,10 +663,9 @@ pub fn fchownat<P: ?Sized + NixPath>(
663663
Errno::result(res).map(drop)
664664
}
665665

666-
fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
667-
let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
668-
args_p.push(ptr::null());
669-
args_p
666+
fn to_exec_array(args: &[&CStr]) -> Vec<*const c_char> {
667+
use std::iter::once;
668+
args.iter().map(|s| s.as_ptr()).chain(once(ptr::null())).collect()
670669
}
671670

672671
/// Replace the current process image with a new one (see
@@ -676,7 +675,7 @@ fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
676675
/// performs the same action but does not allow for customization of the
677676
/// environment for the new process.
678677
#[inline]
679-
pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
678+
pub fn execv(path: &CStr, argv: &[&CStr]) -> Result<Void> {
680679
let args_p = to_exec_array(argv);
681680

682681
unsafe {
@@ -700,7 +699,7 @@ pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
700699
/// in the `args` list is an argument to the new process. Each element in the
701700
/// `env` list should be a string in the form "key=value".
702701
#[inline]
703-
pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
702+
pub fn execve(path: &CStr, args: &[&CStr], env: &[&CStr]) -> Result<Void> {
704703
let args_p = to_exec_array(args);
705704
let env_p = to_exec_array(env);
706705

@@ -721,7 +720,7 @@ pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void>
721720
/// would not work if "bash" was specified for the path argument, but `execvp`
722721
/// would assuming that a bash executable was on the system `PATH`.
723722
#[inline]
724-
pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
723+
pub fn execvp(filename: &CStr, args: &[&CStr]) -> Result<Void> {
725724
let args_p = to_exec_array(args);
726725

727726
unsafe {
@@ -741,7 +740,7 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
741740
#[cfg(any(target_os = "haiku",
742741
target_os = "linux",
743742
target_os = "openbsd"))]
744-
pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
743+
pub fn execvpe(filename: &CStr, args: &[&CStr], env: &[&CStr]) -> Result<Void> {
745744
let args_p = to_exec_array(args);
746745
let env_p = to_exec_array(env);
747746

@@ -769,7 +768,7 @@ pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<
769768
target_os = "linux",
770769
target_os = "freebsd"))]
771770
#[inline]
772-
pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
771+
pub fn fexecve(fd: RawFd, args: &[&CStr], env: &[&CStr]) -> Result<Void> {
773772
let args_p = to_exec_array(args);
774773
let env_p = to_exec_array(env);
775774

@@ -792,8 +791,8 @@ pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
792791
/// is referenced as a file descriptor to the base directory plus a path.
793792
#[cfg(any(target_os = "android", target_os = "linux"))]
794793
#[inline]
795-
pub fn execveat(dirfd: RawFd, pathname: &CString, args: &[CString],
796-
env: &[CString], flags: super::fcntl::AtFlags) -> Result<Void> {
794+
pub fn execveat(dirfd: RawFd, pathname: &CStr, args: &[&CStr],
795+
env: &[&CStr], flags: super::fcntl::AtFlags) -> Result<Void> {
797796
let args_p = to_exec_array(args);
798797
let env_p = to_exec_array(env);
799798

test/test_unistd.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,13 @@ macro_rules! execve_test_factory(
201201
// exec!
202202
$syscall(
203203
$exe,
204-
$(&CString::new($pathname).unwrap(), )*
205-
&[CString::new(b"".as_ref()).unwrap(),
206-
CString::new(b"-c".as_ref()).unwrap(),
204+
$(CString::new($pathname).unwrap().as_c_str(), )*
205+
&[CString::new(b"".as_ref()).unwrap().as_c_str(),
206+
CString::new(b"-c".as_ref()).unwrap().as_c_str(),
207207
CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
208-
.as_ref()).unwrap()],
209-
&[CString::new(b"foo=bar".as_ref()).unwrap(),
210-
CString::new(b"baz=quux".as_ref()).unwrap()]
208+
.as_ref()).unwrap().as_c_str()],
209+
&[CString::new(b"foo=bar".as_ref()).unwrap().as_c_str(),
210+
CString::new(b"baz=quux".as_ref()).unwrap().as_c_str()]
211211
$(, $flags)*).unwrap();
212212
},
213213
Parent { child } => {
@@ -229,18 +229,18 @@ macro_rules! execve_test_factory(
229229

230230
cfg_if!{
231231
if #[cfg(target_os = "android")] {
232-
execve_test_factory!(test_execve, execve, &CString::new("/system/bin/sh").unwrap());
232+
execve_test_factory!(test_execve, execve, CString::new("/system/bin/sh").unwrap().as_c_str());
233233
execve_test_factory!(test_fexecve, fexecve, File::open("/system/bin/sh").unwrap().into_raw_fd());
234234
} else if #[cfg(any(target_os = "freebsd",
235235
target_os = "linux"))] {
236-
execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
236+
execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str());
237237
execve_test_factory!(test_fexecve, fexecve, File::open("/bin/sh").unwrap().into_raw_fd());
238238
} else if #[cfg(any(target_os = "dragonfly",
239239
target_os = "ios",
240240
target_os = "macos",
241241
target_os = "netbsd",
242242
target_os = "openbsd"))] {
243-
execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
243+
execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str());
244244
// No fexecve() on DragonFly, ios, macos, NetBSD, OpenBSD.
245245
//
246246
// Note for NetBSD and OpenBSD: although rust-lang/libc includes it

0 commit comments

Comments
 (0)