Skip to content

Commit 9ebc633

Browse files
committed
fix #1093
1 parent 2fc246c commit 9ebc633

File tree

3 files changed

+23
-21
lines changed

3 files changed

+23
-21
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4242
`self` by value.
4343
([#1107](https://github.com/nix-rust/nix/pull/1107))
4444

45+
- Type `&CString` for parameters of `exec(v|ve|vp|vpe|veat)` are changed to `&CStr`.
46+
([#1121](https://github.com/nix-rust/nix/pull/1121))
47+
4548
### Fixed
4649
- Fix length of abstract socket addresses
4750
([#1120](https://github.com/nix-rust/nix/pull/1120))

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, PATH_MAX};
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;
@@ -675,10 +675,9 @@ pub fn fchownat<P: ?Sized + NixPath>(
675675
Errno::result(res).map(drop)
676676
}
677677

678-
fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
679-
let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
680-
args_p.push(ptr::null());
681-
args_p
678+
fn to_exec_array(args: &[&CStr]) -> Vec<*const c_char> {
679+
use std::iter::once;
680+
args.iter().map(|s| s.as_ptr()).chain(once(ptr::null())).collect()
682681
}
683682

684683
/// Replace the current process image with a new one (see
@@ -688,7 +687,7 @@ fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
688687
/// performs the same action but does not allow for customization of the
689688
/// environment for the new process.
690689
#[inline]
691-
pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
690+
pub fn execv(path: &CStr, argv: &[&CStr]) -> Result<Void> {
692691
let args_p = to_exec_array(argv);
693692

694693
unsafe {
@@ -712,7 +711,7 @@ pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
712711
/// in the `args` list is an argument to the new process. Each element in the
713712
/// `env` list should be a string in the form "key=value".
714713
#[inline]
715-
pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
714+
pub fn execve(path: &CStr, args: &[&CStr], env: &[&CStr]) -> Result<Void> {
716715
let args_p = to_exec_array(args);
717716
let env_p = to_exec_array(env);
718717

@@ -733,7 +732,7 @@ pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void>
733732
/// would not work if "bash" was specified for the path argument, but `execvp`
734733
/// would assuming that a bash executable was on the system `PATH`.
735734
#[inline]
736-
pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
735+
pub fn execvp(filename: &CStr, args: &[&CStr]) -> Result<Void> {
737736
let args_p = to_exec_array(args);
738737

739738
unsafe {
@@ -753,7 +752,7 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
753752
#[cfg(any(target_os = "haiku",
754753
target_os = "linux",
755754
target_os = "openbsd"))]
756-
pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
755+
pub fn execvpe(filename: &CStr, args: &[&CStr], env: &[&CStr]) -> Result<Void> {
757756
let args_p = to_exec_array(args);
758757
let env_p = to_exec_array(env);
759758

@@ -781,7 +780,7 @@ pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<
781780
target_os = "linux",
782781
target_os = "freebsd"))]
783782
#[inline]
784-
pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
783+
pub fn fexecve(fd: RawFd, args: &[&CStr], env: &[&CStr]) -> Result<Void> {
785784
let args_p = to_exec_array(args);
786785
let env_p = to_exec_array(env);
787786

@@ -804,8 +803,8 @@ pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
804803
/// is referenced as a file descriptor to the base directory plus a path.
805804
#[cfg(any(target_os = "android", target_os = "linux"))]
806805
#[inline]
807-
pub fn execveat(dirfd: RawFd, pathname: &CString, args: &[CString],
808-
env: &[CString], flags: super::fcntl::AtFlags) -> Result<Void> {
806+
pub fn execveat(dirfd: RawFd, pathname: &CStr, args: &[&CStr],
807+
env: &[&CStr], flags: super::fcntl::AtFlags) -> Result<Void> {
809808
let args_p = to_exec_array(args);
810809
let env_p = to_exec_array(env);
811810

test/test_unistd.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,13 @@ macro_rules! execve_test_factory(
204204
dup2(writer, 1).unwrap();
205205
let r = $syscall(
206206
$exe,
207-
$(&CString::new($pathname).unwrap(), )*
208-
&[CString::new(b"".as_ref()).unwrap(),
209-
CString::new(b"-c".as_ref()).unwrap(),
207+
$(CString::new($pathname).unwrap().as_c_str(), )*
208+
&[CString::new(b"".as_ref()).unwrap().as_c_str(),
209+
CString::new(b"-c".as_ref()).unwrap().as_c_str(),
210210
CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
211-
.as_ref()).unwrap()],
212-
&[CString::new(b"foo=bar".as_ref()).unwrap(),
213-
CString::new(b"baz=quux".as_ref()).unwrap()]
211+
.as_ref()).unwrap().as_c_str()],
212+
&[CString::new(b"foo=bar".as_ref()).unwrap().as_c_str(),
213+
CString::new(b"baz=quux".as_ref()).unwrap().as_c_str()]
214214
$(, $flags)*);
215215
let _ = std::io::stderr()
216216
.write_all(format!("{:?}", r).as_bytes());
@@ -238,18 +238,18 @@ macro_rules! execve_test_factory(
238238

239239
cfg_if!{
240240
if #[cfg(target_os = "android")] {
241-
execve_test_factory!(test_execve, execve, &CString::new("/system/bin/sh").unwrap());
241+
execve_test_factory!(test_execve, execve, CString::new("/system/bin/sh").unwrap().as_c_str());
242242
execve_test_factory!(test_fexecve, fexecve, File::open("/system/bin/sh").unwrap().into_raw_fd());
243243
} else if #[cfg(any(target_os = "freebsd",
244244
target_os = "linux"))] {
245-
execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
245+
execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str());
246246
execve_test_factory!(test_fexecve, fexecve, File::open("/bin/sh").unwrap().into_raw_fd());
247247
} else if #[cfg(any(target_os = "dragonfly",
248248
target_os = "ios",
249249
target_os = "macos",
250250
target_os = "netbsd",
251251
target_os = "openbsd"))] {
252-
execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
252+
execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str());
253253
// No fexecve() on DragonFly, ios, macos, NetBSD, OpenBSD.
254254
//
255255
// Note for NetBSD and OpenBSD: although rust-lang/libc includes it

0 commit comments

Comments
 (0)