Skip to content

Commit f60fcfd

Browse files
committed
Use the real pipe2(2) on all BSD targets.
All supported non-Apple platforms now use the native syscall. Only ios and macos lack it. It was added in: * DragonflyBSD 4.2 * FreeBSD 10.0 * NetBSD 6.0 * OpenBSD 5.7
1 parent 1b9d205 commit f60fcfd

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
3838
([#602](https://github.com/nix-rust/nix/pull/774))
3939

4040
### Changed
41+
- Use native `pipe` on all BSD targets. Users should notice no difference.
42+
([#777](https://github.com/nix-rust/nix/pull/777))
4143
- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
4244
- Marked `sys::ptrace::ptrace` as `unsafe`.
4345
- Changed function signature of `socket()` and `socketpair()`. The `protocol` argument

src/unistd.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -856,9 +856,13 @@ pub fn pipe() -> Result<(RawFd, RawFd)> {
856856
}
857857

858858
// libc only defines `pipe2` in `libc::notbsd`.
859-
#[cfg(any(target_os = "linux",
860-
target_os = "android",
861-
target_os = "emscripten"))]
859+
#[cfg(any(target_os = "android",
860+
target_os = "dragonfly",
861+
target_os = "emscripten",
862+
target_os = "freebsd",
863+
target_os = "linux",
864+
target_os = "netbsd",
865+
target_os = "openbsd"))]
862866
pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
863867
let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
864868

@@ -869,9 +873,8 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
869873
Ok((fds[0], fds[1]))
870874
}
871875

872-
#[cfg(not(any(target_os = "linux",
873-
target_os = "android",
874-
target_os = "emscripten")))]
876+
#[cfg(any(target_os = "ios",
877+
target_os = "macos"))]
875878
pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
876879
let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
877880

@@ -884,9 +887,8 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
884887
Ok((fds[0], fds[1]))
885888
}
886889

887-
#[cfg(not(any(target_os = "linux",
888-
target_os = "android",
889-
target_os = "emscripten")))]
890+
#[cfg(any(target_os = "ios",
891+
target_os = "macos"))]
890892
fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
891893
use fcntl::O_NONBLOCK;
892894
use fcntl::FcntlArg::F_SETFL;

test/test_unistd.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ extern crate tempdir;
22

33
use nix::unistd::*;
44
use nix::unistd::ForkResult::*;
5+
use nix::fcntl;
56
use nix::sys::wait::*;
67
use nix::sys::stat;
78
use std::{env, iter};
@@ -291,3 +292,26 @@ fn test_sysconf_unsupported() {
291292
let open_max = sysconf(SysconfVar::_XOPEN_CRYPT);
292293
assert!(open_max.expect("sysconf failed").is_none())
293294
}
295+
296+
// Test that we can create a pair of pipes. No need to verify that they pass
297+
// data; that's the domain of the OS, not nix.
298+
#[test]
299+
fn test_pipe() {
300+
let (fd0, fd1) = pipe().unwrap();
301+
let m0 = stat::SFlag::from_bits_truncate(stat::fstat(fd0).unwrap().st_mode);
302+
// S_IFIFO means it's a pipe
303+
assert_eq!(m0, stat::S_IFIFO);
304+
let m1 = stat::SFlag::from_bits_truncate(stat::fstat(fd1).unwrap().st_mode);
305+
assert_eq!(m1, stat::S_IFIFO);
306+
}
307+
308+
// pipe2(2) is the same as pipe(2), except it allows setting some flags. Check
309+
// that we can set a flag.
310+
#[test]
311+
fn test_pipe2() {
312+
let (fd0, fd1) = pipe2(fcntl::O_CLOEXEC).unwrap();
313+
let f0 = fcntl::FdFlag::from_bits_truncate(fcntl::fcntl(fd0, fcntl::F_GETFD).unwrap());
314+
assert!(f0.contains(fcntl::FD_CLOEXEC));
315+
let f1 = fcntl::FdFlag::from_bits_truncate(fcntl::fcntl(fd1, fcntl::F_GETFD).unwrap());
316+
assert!(f1.contains(fcntl::FD_CLOEXEC));
317+
}

0 commit comments

Comments
 (0)