Skip to content

Commit

Permalink
Merge branch 'master' into more_tcp_keepalive_options
Browse files Browse the repository at this point in the history
  • Loading branch information
yoav-steinberg committed Aug 22, 2020
2 parents 237e982 + 645309d commit 97d2b7d
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 33 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Added `TCP_KEEPCNT` and `TCP_KEEPINTVL` TCP keepalive options.
(#[1283](https://github.com/nix-rust/nix/pull/1283))
- Added Netlink protocol families to the `SockProtocol` enum
(#[1289](https://github.com/nix-rust/nix/pull/1289))
### Changed
- Expose `SeekData` and `SeekHole` on all Linux targets
(#[1284](https://github.com/nix-rust/nix/pull/1284))
- Changed unistd::{execv,execve,execvp,execvpe,fexecve,execveat} to take both `&[&CStr]` and `&[CString]` as its list argument(s).
(#[1278](https://github.com/nix-rust/nix/pull/1278))
### Fixed
### Removed

Expand Down
2 changes: 1 addition & 1 deletion src/sys/ioctl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some
//! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into
//! subcomponents (For linux this is documented in
//! [`Documentation/ioctl/ioctl-number.rst`](http://elixir.free-electrons.com/linux/latest/source/Documentation/ioctl/ioctl-number.rst)):
//! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)):
//!
//! * Number: The actual ioctl ID
//! * Type: A grouping of ioctls for a common purpose or driver
Expand Down
58 changes: 58 additions & 0 deletions src/sys/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,64 @@ pub enum SockProtocol {
/// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
#[cfg(any(target_os = "ios", target_os = "macos"))]
KextControl = libc::SYSPROTO_CONTROL,
/// Receives routing and link updates and may be used to modify the routing tables (both IPv4 and IPv6), IP addresses, link
// parameters, neighbor setups, queueing disciplines, traffic classes and packet classifiers
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkRoute = libc::NETLINK_ROUTE,
/// Reserved for user-mode socket protocols
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkUserSock = libc::NETLINK_USERSOCK,
/// Query information about sockets of various protocol families from the kernel
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkSockDiag = libc::NETLINK_SOCK_DIAG,
/// SELinux event notifications.
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkSELinux = libc::NETLINK_SELINUX,
/// Open-iSCSI
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkISCSI = libc::NETLINK_ISCSI,
/// Auditing
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkAudit = libc::NETLINK_AUDIT,
/// Access to FIB lookup from user space
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkFIBLookup = libc::NETLINK_FIB_LOOKUP,
/// Netfilter subsystem
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkNetFilter = libc::NETLINK_NETFILTER,
/// SCSI Transports
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkSCSITransport = libc::NETLINK_SCSITRANSPORT,
/// Infiniband RDMA
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkRDMA = libc::NETLINK_RDMA,
/// Transport IPv6 packets from netfilter to user space. Used by ip6_queue kernel module.
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkIPv6Firewall = libc::NETLINK_IP6_FW,
/// DECnet routing messages
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkDECNetRoutingMessage = libc::NETLINK_DNRTMSG,
/// Kernel messages to user space
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkKObjectUEvent = libc::NETLINK_KOBJECT_UEVENT,
/// Netlink interface to request information about ciphers registered with the kernel crypto API as well as allow
/// configuration of the kernel crypto API.
/// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
#[cfg(any(target_os = "android", target_os = "linux"))]
NetlinkCrypto = libc::NETLINK_CRYPTO,
}

libc_bitflags!{
Expand Down
2 changes: 1 addition & 1 deletion src/sys/stat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ pub enum FchmodatFlags {
/// If `flag` is `FchmodatFlags::NoFollowSymlink` and `path` names a symbolic link,
/// then the mode of the symbolic link is changed.
///
/// `fchmod(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to
/// `fchmodat(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to
/// a call `libc::chmod(path, mode)`. That's why `chmod` is unimplemented
/// in the `nix` crate.
///
Expand Down
32 changes: 13 additions & 19 deletions src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use libc::{self, c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t,
uid_t, gid_t, mode_t, PATH_MAX};
use std::{fmt, mem, ptr};
use std::convert::Infallible;
use std::ffi::{CStr, OsString};
use std::ffi::{CStr, CString, OsString};
#[cfg(not(target_os = "redox"))]
use std::ffi::{CString, OsStr};
use std::ffi::{OsStr};
use std::os::unix::ffi::OsStringExt;
#[cfg(not(target_os = "redox"))]
use std::os::unix::ffi::OsStrExt;
Expand Down Expand Up @@ -715,9 +715,9 @@ pub fn fchownat<P: ?Sized + NixPath>(
Errno::result(res).map(drop)
}

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

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

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

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

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

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

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

Expand Down Expand Up @@ -1018,20 +1018,14 @@ pub enum Whence {
/// Specify an offset relative to the next location in the file greater than or
/// equal to offset that contains some data. If offset points to
/// some data, then the file offset is set to offset.
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
all(target_os = "linux", not(any(target_env = "musl",
target_arch = "mips",
target_arch = "mips64")))))]
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
SeekData = libc::SEEK_DATA,
/// Specify an offset relative to the next hole in the file greater than
/// or equal to offset. If offset points into the middle of a hole, then
/// the file offset should be set to offset. If there is no hole past offset,
/// then the file offset should be adjusted to the end of the file (i.e., there
/// is an implicit hole at the end of any file).
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
all(target_os = "linux", not(any(target_env = "musl",
target_arch = "mips",
target_arch = "mips64")))))]
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
SeekHole = libc::SEEK_HOLE
}

Expand Down
57 changes: 45 additions & 12 deletions test/test_unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,38 @@ fn test_initgroups() {
#[cfg(not(target_os = "redox"))]
macro_rules! execve_test_factory(
($test_name:ident, $syscall:ident, $exe: expr $(, $pathname:expr, $flags:expr)*) => (
#[test]
fn $test_name() {

#[cfg(test)]
mod $test_name {
use super::*;

fn syscall_cstr_ref() -> Result<std::convert::Infallible, nix::Error> {
$syscall(
$exe,
$(CString::new($pathname).unwrap().as_c_str(), )*
&[CString::new(b"".as_ref()).unwrap().as_c_str(),
CString::new(b"-c".as_ref()).unwrap().as_c_str(),
CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
.as_ref()).unwrap().as_c_str()],
&[CString::new(b"foo=bar".as_ref()).unwrap().as_c_str(),
CString::new(b"baz=quux".as_ref()).unwrap().as_c_str()]
$(, $flags)*)
}

fn syscall_cstring() -> Result<std::convert::Infallible, nix::Error> {
$syscall(
$exe,
$(CString::new($pathname).unwrap().as_c_str(), )*
&[CString::new(b"".as_ref()).unwrap(),
CString::new(b"-c".as_ref()).unwrap(),
CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
.as_ref()).unwrap()],
&[CString::new(b"foo=bar".as_ref()).unwrap(),
CString::new(b"baz=quux".as_ref()).unwrap()]
$(, $flags)*)
}

fn common_test(syscall: fn() -> Result<std::convert::Infallible, nix::Error>) {
if "execveat" == stringify!($syscall) {
// Though undocumented, Docker's default seccomp profile seems to
// block this syscall. https://github.com/nix-rust/nix/issues/1122
Expand All @@ -276,16 +306,7 @@ macro_rules! execve_test_factory(
Child => {
// Make `writer` be the stdout of the new process.
dup2(writer, 1).unwrap();
let r = $syscall(
$exe,
$(CString::new($pathname).unwrap().as_c_str(), )*
&[CString::new(b"".as_ref()).unwrap().as_c_str(),
CString::new(b"-c".as_ref()).unwrap().as_c_str(),
CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
.as_ref()).unwrap().as_c_str()],
&[CString::new(b"foo=bar".as_ref()).unwrap().as_c_str(),
CString::new(b"baz=quux".as_ref()).unwrap().as_c_str()]
$(, $flags)*);
let r = syscall();
let _ = std::io::stderr()
.write_all(format!("{:?}", r).as_bytes());
// Should only get here in event of error
Expand All @@ -307,6 +328,18 @@ macro_rules! execve_test_factory(
}
}
}

#[test]
fn test_cstr_ref() {
common_test(syscall_cstr_ref);
}

#[test]
fn test_cstring() {
common_test(syscall_cstring);
}
}

)
);

Expand Down

0 comments on commit 97d2b7d

Please sign in to comment.