From 71688a082a042d5c8313491bc5f3f88fcf42f854 Mon Sep 17 00:00:00 2001 From: Jack O'Connor Date: Wed, 14 Sep 2016 15:48:57 -0700 Subject: [PATCH 1/4] call pipe2 directly on Linux --- src/unistd.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/unistd.rs b/src/unistd.rs index 74d74c9c31..2f8aa5230a 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -1,8 +1,8 @@ //! Standard symbolic constants and types //! use {Errno, Error, Result, NixPath}; -use fcntl::{fcntl, OFlag, O_NONBLOCK, O_CLOEXEC, FD_CLOEXEC}; -use fcntl::FcntlArg::{F_SETFD, F_SETFL}; +use fcntl::{fcntl, OFlag, O_CLOEXEC, FD_CLOEXEC}; +use fcntl::FcntlArg::F_SETFD; use libc::{self, c_char, c_void, c_int, c_uint, size_t, pid_t, off_t, uid_t, gid_t, mode_t}; use std::mem; use std::ffi::{CString, CStr, OsString}; @@ -360,6 +360,25 @@ pub fn pipe() -> Result<(RawFd, RawFd)> { } } +// libc only defines `pipe2` in `libc::notbsd`. +#[cfg(any(target_os = "linux", + target_os = "android", + target_os = "emscripten"))] +pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { + unsafe { + let mut fds: [c_int; 2] = mem::uninitialized(); + + let res = libc::pipe2(fds.as_mut_ptr(), flags.bits()); + + try!(Errno::result(res)); + + Ok((fds[0], fds[1])) + } +} + +#[cfg(not(any(target_os = "linux", + target_os = "android", + target_os = "emscripten")))] pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { unsafe { let mut fds: [c_int; 2] = mem::uninitialized(); @@ -374,7 +393,13 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { } } +#[cfg(not(any(target_os = "linux", + target_os = "android", + target_os = "emscripten")))] fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> { + use fcntl::O_NONBLOCK; + use fcntl::FcntlArg::F_SETFL; + let mut res = Ok(0); if flags.contains(O_CLOEXEC) { From b28005f658129f9130d44ad63b38a74ff2b6e69d Mon Sep 17 00:00:00 2001 From: Jack O'Connor Date: Thu, 15 Sep 2016 09:52:38 -0700 Subject: [PATCH 2/4] make unsafe code more fine-grained in pipe2 --- src/unistd.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/unistd.rs b/src/unistd.rs index 2f8aa5230a..1b2175ea3e 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -365,32 +365,28 @@ pub fn pipe() -> Result<(RawFd, RawFd)> { target_os = "android", target_os = "emscripten"))] pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { - unsafe { - let mut fds: [c_int; 2] = mem::uninitialized(); + let mut fds: [c_int; 2] = unsafe { mem::uninitialized() }; - let res = libc::pipe2(fds.as_mut_ptr(), flags.bits()); + let res = unsafe { libc::pipe2(fds.as_mut_ptr(), flags.bits()) }; - try!(Errno::result(res)); + try!(Errno::result(res)); - Ok((fds[0], fds[1])) - } + Ok((fds[0], fds[1])) } #[cfg(not(any(target_os = "linux", target_os = "android", target_os = "emscripten")))] pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { - unsafe { - let mut fds: [c_int; 2] = mem::uninitialized(); + let mut fds: [c_int; 2] = unsafe { mem::uninitialized() }; - let res = libc::pipe(fds.as_mut_ptr()); + let res = unsafe { libc::pipe(fds.as_mut_ptr()) }; - try!(Errno::result(res)); + try!(Errno::result(res)); - try!(pipe2_setflags(fds[0], fds[1], flags)); + try!(pipe2_setflags(fds[0], fds[1], flags)); - Ok((fds[0], fds[1])) - } + Ok((fds[0], fds[1])) } #[cfg(not(any(target_os = "linux", From 40a6cafdffc21debba6a6a459766059bf9e32a06 Mon Sep 17 00:00:00 2001 From: Jack O'Connor Date: Thu, 15 Sep 2016 13:32:19 -0700 Subject: [PATCH 3/4] add a CHANGELOG entry for pipe2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4238ed7402..1d7c461920 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Changed +- `pipe2` now calls `libc::pipe2` where available. Previously it was emulated + using `pipe`, which meant that setting `O_CLOEXEC` was not atomic. + ## [0.7.0] 2016-09-09 ### Added From 1d262d0541c729df94351b73eef0957785d28d85 Mon Sep 17 00:00:00 2001 From: Jack O'Connor Date: Thu, 15 Sep 2016 14:43:42 -0700 Subject: [PATCH 4/4] add a GitHub link to the CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d7c461920..3f8f54de2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - `pipe2` now calls `libc::pipe2` where available. Previously it was emulated using `pipe`, which meant that setting `O_CLOEXEC` was not atomic. + ([#427](https://github.com/nix-rust/nix/pull/427)) ## [0.7.0] 2016-09-09