Skip to content

Commit baab9c4

Browse files
authored
Merge branch 'master' into musl_seek
2 parents 0139b7d + 8ab88ee commit baab9c4

File tree

3 files changed

+58
-23
lines changed

3 files changed

+58
-23
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1010
### Changed
1111
- Expose `SeekData` and `SeekHole` on all Linux targets
1212
(#[1284](https://github.com/nix-rust/nix/pull/1284))
13+
- Changed unistd::{execv,execve,execvp,execvpe,fexecve,execveat} to take both `&[&CStr]` and `&[CString]` as its list argument(s).
14+
(#[1278](https://github.com/nix-rust/nix/pull/1278))
1315
### Fixed
1416
### Removed
1517

src/unistd.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use libc::{self, c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t,
1212
uid_t, gid_t, mode_t, PATH_MAX};
1313
use std::{fmt, mem, ptr};
1414
use std::convert::Infallible;
15-
use std::ffi::{CStr, OsString};
15+
use std::ffi::{CStr, CString, OsString};
1616
#[cfg(not(target_os = "redox"))]
17-
use std::ffi::{CString, OsStr};
17+
use std::ffi::{OsStr};
1818
use std::os::unix::ffi::OsStringExt;
1919
#[cfg(not(target_os = "redox"))]
2020
use std::os::unix::ffi::OsStrExt;
@@ -715,9 +715,9 @@ pub fn fchownat<P: ?Sized + NixPath>(
715715
Errno::result(res).map(drop)
716716
}
717717

718-
fn to_exec_array(args: &[&CStr]) -> Vec<*const c_char> {
718+
fn to_exec_array<S: AsRef<CStr>>(args: &[S]) -> Vec<*const c_char> {
719719
use std::iter::once;
720-
args.iter().map(|s| s.as_ptr()).chain(once(ptr::null())).collect()
720+
args.iter().map(|s| s.as_ref().as_ptr()).chain(once(ptr::null())).collect()
721721
}
722722

723723
/// Replace the current process image with a new one (see
@@ -727,7 +727,7 @@ fn to_exec_array(args: &[&CStr]) -> Vec<*const c_char> {
727727
/// performs the same action but does not allow for customization of the
728728
/// environment for the new process.
729729
#[inline]
730-
pub fn execv(path: &CStr, argv: &[&CStr]) -> Result<Infallible> {
730+
pub fn execv<S: AsRef<CStr>>(path: &CStr, argv: &[S]) -> Result<Infallible> {
731731
let args_p = to_exec_array(argv);
732732

733733
unsafe {
@@ -751,7 +751,7 @@ pub fn execv(path: &CStr, argv: &[&CStr]) -> Result<Infallible> {
751751
/// in the `args` list is an argument to the new process. Each element in the
752752
/// `env` list should be a string in the form "key=value".
753753
#[inline]
754-
pub fn execve(path: &CStr, args: &[&CStr], env: &[&CStr]) -> Result<Infallible> {
754+
pub fn execve<SA: AsRef<CStr>, SE: AsRef<CStr>>(path: &CStr, args: &[SA], env: &[SE]) -> Result<Infallible> {
755755
let args_p = to_exec_array(args);
756756
let env_p = to_exec_array(env);
757757

@@ -772,7 +772,7 @@ pub fn execve(path: &CStr, args: &[&CStr], env: &[&CStr]) -> Result<Infallible>
772772
/// would not work if "bash" was specified for the path argument, but `execvp`
773773
/// would assuming that a bash executable was on the system `PATH`.
774774
#[inline]
775-
pub fn execvp(filename: &CStr, args: &[&CStr]) -> Result<Infallible> {
775+
pub fn execvp<S: AsRef<CStr>>(filename: &CStr, args: &[S]) -> Result<Infallible> {
776776
let args_p = to_exec_array(args);
777777

778778
unsafe {
@@ -792,7 +792,7 @@ pub fn execvp(filename: &CStr, args: &[&CStr]) -> Result<Infallible> {
792792
#[cfg(any(target_os = "haiku",
793793
target_os = "linux",
794794
target_os = "openbsd"))]
795-
pub fn execvpe(filename: &CStr, args: &[&CStr], env: &[&CStr]) -> Result<Infallible> {
795+
pub fn execvpe<SA: AsRef<CStr>, SE: AsRef<CStr>>(filename: &CStr, args: &[SA], env: &[SE]) -> Result<Infallible> {
796796
let args_p = to_exec_array(args);
797797
let env_p = to_exec_array(env);
798798

@@ -820,7 +820,7 @@ pub fn execvpe(filename: &CStr, args: &[&CStr], env: &[&CStr]) -> Result<Infalli
820820
target_os = "linux",
821821
target_os = "freebsd"))]
822822
#[inline]
823-
pub fn fexecve(fd: RawFd, args: &[&CStr], env: &[&CStr]) -> Result<Infallible> {
823+
pub fn fexecve<SA: AsRef<CStr> ,SE: AsRef<CStr>>(fd: RawFd, args: &[SA], env: &[SE]) -> Result<Infallible> {
824824
let args_p = to_exec_array(args);
825825
let env_p = to_exec_array(env);
826826

@@ -843,8 +843,8 @@ pub fn fexecve(fd: RawFd, args: &[&CStr], env: &[&CStr]) -> Result<Infallible> {
843843
/// is referenced as a file descriptor to the base directory plus a path.
844844
#[cfg(any(target_os = "android", target_os = "linux"))]
845845
#[inline]
846-
pub fn execveat(dirfd: RawFd, pathname: &CStr, args: &[&CStr],
847-
env: &[&CStr], flags: super::fcntl::AtFlags) -> Result<Infallible> {
846+
pub fn execveat<SA: AsRef<CStr>,SE: AsRef<CStr>>(dirfd: RawFd, pathname: &CStr, args: &[SA],
847+
env: &[SE], flags: super::fcntl::AtFlags) -> Result<Infallible> {
848848
let args_p = to_exec_array(args);
849849
let env_p = to_exec_array(env);
850850

test/test_unistd.rs

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,38 @@ fn test_initgroups() {
256256
#[cfg(not(target_os = "redox"))]
257257
macro_rules! execve_test_factory(
258258
($test_name:ident, $syscall:ident, $exe: expr $(, $pathname:expr, $flags:expr)*) => (
259-
#[test]
260-
fn $test_name() {
259+
260+
#[cfg(test)]
261+
mod $test_name {
262+
use super::*;
263+
264+
fn syscall_cstr_ref() -> Result<std::convert::Infallible, nix::Error> {
265+
$syscall(
266+
$exe,
267+
$(CString::new($pathname).unwrap().as_c_str(), )*
268+
&[CString::new(b"".as_ref()).unwrap().as_c_str(),
269+
CString::new(b"-c".as_ref()).unwrap().as_c_str(),
270+
CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
271+
.as_ref()).unwrap().as_c_str()],
272+
&[CString::new(b"foo=bar".as_ref()).unwrap().as_c_str(),
273+
CString::new(b"baz=quux".as_ref()).unwrap().as_c_str()]
274+
$(, $flags)*)
275+
}
276+
277+
fn syscall_cstring() -> Result<std::convert::Infallible, nix::Error> {
278+
$syscall(
279+
$exe,
280+
$(CString::new($pathname).unwrap().as_c_str(), )*
281+
&[CString::new(b"".as_ref()).unwrap(),
282+
CString::new(b"-c".as_ref()).unwrap(),
283+
CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
284+
.as_ref()).unwrap()],
285+
&[CString::new(b"foo=bar".as_ref()).unwrap(),
286+
CString::new(b"baz=quux".as_ref()).unwrap()]
287+
$(, $flags)*)
288+
}
289+
290+
fn common_test(syscall: fn() -> Result<std::convert::Infallible, nix::Error>) {
261291
if "execveat" == stringify!($syscall) {
262292
// Though undocumented, Docker's default seccomp profile seems to
263293
// block this syscall. https://github.com/nix-rust/nix/issues/1122
@@ -276,16 +306,7 @@ macro_rules! execve_test_factory(
276306
Child => {
277307
// Make `writer` be the stdout of the new process.
278308
dup2(writer, 1).unwrap();
279-
let r = $syscall(
280-
$exe,
281-
$(CString::new($pathname).unwrap().as_c_str(), )*
282-
&[CString::new(b"".as_ref()).unwrap().as_c_str(),
283-
CString::new(b"-c".as_ref()).unwrap().as_c_str(),
284-
CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
285-
.as_ref()).unwrap().as_c_str()],
286-
&[CString::new(b"foo=bar".as_ref()).unwrap().as_c_str(),
287-
CString::new(b"baz=quux".as_ref()).unwrap().as_c_str()]
288-
$(, $flags)*);
309+
let r = syscall();
289310
let _ = std::io::stderr()
290311
.write_all(format!("{:?}", r).as_bytes());
291312
// Should only get here in event of error
@@ -307,6 +328,18 @@ macro_rules! execve_test_factory(
307328
}
308329
}
309330
}
331+
332+
#[test]
333+
fn test_cstr_ref() {
334+
common_test(syscall_cstr_ref);
335+
}
336+
337+
#[test]
338+
fn test_cstring() {
339+
common_test(syscall_cstring);
340+
}
341+
}
342+
310343
)
311344
);
312345

0 commit comments

Comments
 (0)