From ff7204f9772767ab6234ff976c79def2d3f66518 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Fri, 19 Oct 2018 22:52:25 +0200 Subject: [PATCH 1/8] Implemented dup3() by a direct call to system call dup3() instead of emulating it via dup2() and fcntl() which can cause a race condition. --- src/unistd.rs | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/unistd.rs b/src/unistd.rs index ad06a3c0eb..8e410c5dd9 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2,8 +2,7 @@ use errno::{self, Errno}; use {Error, Result, NixPath}; -use fcntl::{fcntl, FdFlag, OFlag}; -use fcntl::FcntlArg::F_SETFD; +use fcntl::OFlag; 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}; use std::{fmt, mem, ptr}; @@ -374,26 +373,11 @@ pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result { /// /// This function behaves similar to `dup2()` but allows for flags to be /// specified. -pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { - dup3_polyfill(oldfd, newfd, flags) -} - #[inline] -fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { - if oldfd == newfd { - return Err(Error::Sys(Errno::EINVAL)); - } - - let fd = try!(dup2(oldfd, newfd)); - - if flags.contains(OFlag::O_CLOEXEC) { - if let Err(e) = fcntl(fd, F_SETFD(FdFlag::FD_CLOEXEC)) { - let _ = close(fd); - return Err(e); - } - } +pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { + let res = unsafe { libc::dup3(oldfd, newfd, flags.bits()) }; - Ok(fd) + Errno::result(res) } /// Change the current working directory of the calling process (see From 1be9004af95e40f520e5b2d44955802944ccb5ac Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Fri, 19 Oct 2018 23:25:34 +0200 Subject: [PATCH 2/8] Added support for `fchown`, `lchown` and `chmod`. --- src/unistd.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/unistd.rs b/src/unistd.rs index 8e410c5dd9..ee55a84d04 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -562,6 +562,55 @@ pub fn chown(path: &P, owner: Option, group: Option(path: &P, owner: Option, group: Option) -> Result<()> { + let res = try!(path.with_nix_path(|cstr| { + // According to the POSIX specification, -1 is used to indicate that + // owner and group, respectively, are not to be changed. Since uid_t and + // gid_t are unsigned types, we use wrapping_sub to get '-1'. + unsafe { libc::lchown(cstr.as_ptr(), + owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1)), + group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1))) } + })); + + Errno::result(res).map(drop) +} + +/// Change the ownership of the file specified by the file descriptor `fd` to be owned by the +/// specified `owner` (user) and `group` (see +/// [fchown(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html)). +/// +/// The owner/group for the provided path name will not be modified if `None` is +/// provided for that argument. Ownership change will be attempted for the path +/// only if `Some` owner/group is provided. +#[inline] +pub fn fchown(fd: RawFd, owner: Option, group: Option) -> Result<()> { + let res = unsafe { libc::fchown(fd, + owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1)), + group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1))) }; + + Errno::result(res).map(drop) +} + +/// Change the mode of the file at `path` (see +/// [chmod(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html)). +#[inline] +pub fn chmod(path: &P, mode: Mode) -> Result<()> { + let res = try!(path.with_nix_path(|cstr| { + unsafe { libc::chmod(cstr.as_ptr(), mode.bits() as mode_t) } + })); + + Errno::result(res).map(drop) +} + fn to_exec_array(args: &[CString]) -> Vec<*const c_char> { let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect(); args_p.push(ptr::null()); From 395e653a194a3f32d76d774353239675f4bbf79b Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 20 Oct 2018 02:07:24 +0200 Subject: [PATCH 3/8] Removed lchown() and chmod() support. Configured conditional support for dup3(). --- src/unistd.rs | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/src/unistd.rs b/src/unistd.rs index ee55a84d04..fe03706cf8 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -373,7 +373,13 @@ pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result { /// /// This function behaves similar to `dup2()` but allows for flags to be /// specified. -#[inline] +#[cfg(any(target_os = "fuchsia", + target_os = "emscripten", + target_os = "freebsd", + target_os = "linux", + target_os = "solaris", + target_os = "netbsd", + target_os = "openbsd"))] pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { let res = unsafe { libc::dup3(oldfd, newfd, flags.bits()) }; @@ -562,28 +568,6 @@ pub fn chown(path: &P, owner: Option, group: Option(path: &P, owner: Option, group: Option) -> Result<()> { - let res = try!(path.with_nix_path(|cstr| { - // According to the POSIX specification, -1 is used to indicate that - // owner and group, respectively, are not to be changed. Since uid_t and - // gid_t are unsigned types, we use wrapping_sub to get '-1'. - unsafe { libc::lchown(cstr.as_ptr(), - owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1)), - group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1))) } - })); - - Errno::result(res).map(drop) -} - /// Change the ownership of the file specified by the file descriptor `fd` to be owned by the /// specified `owner` (user) and `group` (see /// [fchown(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html)). @@ -591,7 +575,6 @@ pub fn lchown(path: &P, owner: Option, group: Option, group: Option) -> Result<()> { let res = unsafe { libc::fchown(fd, owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1)), @@ -600,17 +583,6 @@ pub fn fchown(fd: RawFd, owner: Option, group: Option) -> Result<()> { Errno::result(res).map(drop) } -/// Change the mode of the file at `path` (see -/// [chmod(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html)). -#[inline] -pub fn chmod(path: &P, mode: Mode) -> Result<()> { - let res = try!(path.with_nix_path(|cstr| { - unsafe { libc::chmod(cstr.as_ptr(), mode.bits() as mode_t) } - })); - - Errno::result(res).map(drop) -} - fn to_exec_array(args: &[CString]) -> Vec<*const c_char> { let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect(); args_p.push(ptr::null()); From 32c3821c809d82cdc9547529310691480bfc53a1 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 20 Oct 2018 14:46:59 +0200 Subject: [PATCH 4/8] Added changelog entries. --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1e0c01d3e..5f062af931 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added +- Added a `dup3` wrapper by a direct call to the system call `dup3` instead of emulating it via + `dup2` and `fcntl` which could cause a race condition. The `dup3` system call is supported + on the following platforms: Fuchsia, Emscripten, FreeBSD, Linux, Solaris, NetBSD, OpenBSD. + ([#957](https://github.com/nix-rust/nix/pull/957)) +- Added a `fchown` wrapper. + ([#957](https://github.com/nix-rust/nix/pull/957)) - Added a `sysinfo` wrapper. ([#922](https://github.com/nix-rust/nix/pull/922)) - Support the `SO_PEERCRED` socket option and the `UnixCredentials` type on all Linux and Android targets. From b7486e12e8cd2a98147ce7bd5a6453b6881e1f69 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 20 Oct 2018 15:09:04 +0200 Subject: [PATCH 5/8] Merged with nix-rust/nix/master. --- CHANGELOG.md | 16 +++++---- src/fcntl.rs | 9 +++++ src/sys/stat.rs | 16 ++------- src/unistd.rs | 88 +++++++++++++++++++++++++++++++++++++++------ test/test_unistd.rs | 83 ++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 181 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f062af931..5b653b0fe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added -- Added a `dup3` wrapper by a direct call to the system call `dup3` instead of emulating it via - `dup2` and `fcntl` which could cause a race condition. The `dup3` system call is supported - on the following platforms: Fuchsia, Emscripten, FreeBSD, Linux, Solaris, NetBSD, OpenBSD. - ([#957](https://github.com/nix-rust/nix/pull/957)) -- Added a `fchown` wrapper. - ([#957](https://github.com/nix-rust/nix/pull/957)) - Added a `sysinfo` wrapper. ([#922](https://github.com/nix-rust/nix/pull/922)) - Support the `SO_PEERCRED` socket option and the `UnixCredentials` type on all Linux and Android targets. @@ -27,6 +21,16 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Added `AF_UNSPEC` wrapper to `AddressFamily` ([#948](https://github.com/nix-rust/nix/pull/948)) - Added the `mode_t` public alias within `sys::stat`. ([#954](https://github.com/nix-rust/nix/pull/954)) +- Added a `truncate` wrapper. + ([#956](https://github.com/nix-rust/nix/pull/956)) +- Added a `fchownat` wrapper. + ([#955](https://github.com/nix-rust/nix/pull/955)) +- Added a `fchown` wrapper. + ([#957](https://github.com/nix-rust/nix/pull/957)) +- Added a `dup3` wrapper by a direct call to the system call `dup3` instead of emulating it via + `dup2` and `fcntl` which could cause a race condition. The `dup3` system call is supported + on the following platforms: Fuchsia, Emscripten, FreeBSD, Linux, Solaris, NetBSD, OpenBSD. + ([#957](https://github.com/nix-rust/nix/pull/957)) ### Changed - Increased required Rust version to 1.22.1/ diff --git a/src/fcntl.rs b/src/fcntl.rs index 58de3b3119..5942506be4 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -2,6 +2,7 @@ use {Error, Result, NixPath}; use errno::Errno; use libc::{self, c_int, c_uint, c_char, size_t, ssize_t}; use sys::stat::Mode; +use std::os::raw; use std::os::unix::io::RawFd; use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -182,6 +183,14 @@ pub fn readlinkat<'a, P: ?Sized + NixPath>(dirfd: RawFd, path: &P, buffer: &'a m wrap_readlink_result(buffer, res) } +/// Computes the raw fd consumed by a function of the form `*at`. +pub(crate) fn at_rawfd(fd: Option) -> raw::c_int { + match fd { + None => libc::AT_FDCWD, + Some(fd) => fd, + } +} + #[cfg(any(target_os = "android", target_os = "linux"))] libc_bitflags!( /// Additional flags for file sealing, which allows for limiting operations on a file. diff --git a/src/sys/stat.rs b/src/sys/stat.rs index d0f0f8d9d8..a0b3aafcb9 100644 --- a/src/sys/stat.rs +++ b/src/sys/stat.rs @@ -3,10 +3,9 @@ pub use libc::stat as FileStat; use {Result, NixPath}; use errno::Errno; -use fcntl::AtFlags; +use fcntl::{AtFlags, at_rawfd}; use libc; use std::mem; -use std::os::raw; use std::os::unix::io::RawFd; use sys::time::{TimeSpec, TimeVal}; @@ -135,15 +134,6 @@ pub fn fchmod(fd: RawFd, mode: Mode) -> Result<()> { Errno::result(res).map(|_| ()) } -/// Computes the raw fd consumed by a function of the form `*at`. -#[inline] -fn actual_atfd(fd: Option) -> raw::c_int { - match fd { - None => libc::AT_FDCWD, - Some(fd) => fd, - } -} - /// Flags for `fchmodat` function. #[derive(Clone, Copy, Debug)] pub enum FchmodatFlags { @@ -180,7 +170,7 @@ pub fn fchmodat( }; let res = path.with_nix_path(|cstr| unsafe { libc::fchmodat( - actual_atfd(dirfd), + at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t, atflag.bits() as libc::c_int, @@ -260,7 +250,7 @@ pub fn utimensat( let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()]; let res = path.with_nix_path(|cstr| unsafe { libc::utimensat( - actual_atfd(dirfd), + at_rawfd(dirfd), cstr.as_ptr(), ×[0], atflag.bits() as libc::c_int, diff --git a/src/unistd.rs b/src/unistd.rs index fe03706cf8..8dd54b3da0 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2,7 +2,7 @@ use errno::{self, Errno}; use {Error, Result, NixPath}; -use fcntl::OFlag; +use fcntl::{at_rawfd, FdFlag, OFlag}; 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}; use std::{fmt, mem, ptr}; @@ -547,6 +547,16 @@ pub fn getcwd() -> Result { } } +/// Computes the raw UID and GID values to pass to a `*chown` call. +fn chown_raw_ids(owner: Option, group: Option) -> (libc::uid_t, libc::gid_t) { + // According to the POSIX specification, -1 is used to indicate that owner and group + // are not to be changed. Since uid_t and gid_t are unsigned types, we have to wrap + // around to get -1. + let uid = owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1)); + let gid = group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1)); + (uid, gid) +} + /// Change the ownership of the file at `path` to be owned by the specified /// `owner` (user) and `group` (see /// [chown(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html)). @@ -557,17 +567,62 @@ pub fn getcwd() -> Result { #[inline] pub fn chown(path: &P, owner: Option, group: Option) -> Result<()> { let res = try!(path.with_nix_path(|cstr| { - // According to the POSIX specification, -1 is used to indicate that - // owner and group, respectively, are not to be changed. Since uid_t and - // gid_t are unsigned types, we use wrapping_sub to get '-1'. - unsafe { libc::chown(cstr.as_ptr(), - owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1)), - group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1))) } + let (uid, gid) = chown_raw_ids(owner, group); + unsafe { libc::chown(cstr.as_ptr(), uid, gid) } })); Errno::result(res).map(drop) } +/// Flags for `fchownat` function. +#[derive(Clone, Copy, Debug)] +pub enum FchownatFlags { + FollowSymlink, + NoFollowSymlink, +} + +/// Change the ownership of the file at `path` to be owned by the specified +/// `owner` (user) and `group`. +/// +/// The owner/group for the provided path name will not be modified if `None` is +/// provided for that argument. Ownership change will be attempted for the path +/// only if `Some` owner/group is provided. +/// +/// The file to be changed is determined relative to the directory associated +/// with the file descriptor `dirfd` or the current working directory +/// if `dirfd` is `None`. +/// +/// If `flag` is `FchownatFlags::NoFollowSymlink` and `path` names a symbolic link, +/// then the mode of the symbolic link is changed. +/// +/// `fchownat(None, path, mode, FchownatFlags::NoFollowSymlink)` is identical to +/// a call `libc::lchown(path, mode)`. That's why `lchmod` is unimplemented in +/// the `nix` crate. +/// +/// # References +/// +/// [fchownat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchownat.html). +pub fn fchownat( + dirfd: Option, + path: &P, + owner: Option, + group: Option, + flag: FchownatFlags, +) -> Result<()> { + let atflag = + match flag { + FchownatFlags::FollowSymlink => AtFlags::empty(), + FchownatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW, + }; + let res = path.with_nix_path(|cstr| unsafe { + let (uid, gid) = chown_raw_ids(owner, group); + libc::fchownat(at_rawfd(dirfd), cstr.as_ptr(), uid, gid, + atflag.bits() as libc::c_int) + })?; + + Errno::result(res).map(|_| ()) +} + /// Change the ownership of the file specified by the file descriptor `fd` to be owned by the /// specified `owner` (user) and `group` (see /// [fchown(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html)). @@ -576,9 +631,8 @@ pub fn chown(path: &P, owner: Option, group: Option, group: Option) -> Result<()> { - let res = unsafe { libc::fchown(fd, - owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1)), - group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1))) }; + let (uid, gid) = chown_raw_ids(owner, group); + let res = unsafe { libc::fchown(fd, uid, gid) }; Errno::result(res).map(drop) } @@ -991,6 +1045,20 @@ fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> { } } +/// Truncate a file to a specified length +/// +/// See also +/// [truncate(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html) +pub fn truncate(path: &P, len: off_t) -> Result<()> { + let res = try!(path.with_nix_path(|cstr| { + unsafe { + libc::truncate(cstr.as_ptr(), len) + } + })); + + Errno::result(res).map(drop) +} + /// Truncate a file to a specified length /// /// See also diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 54cbff8dcf..e5f9d448dd 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -1,4 +1,4 @@ -use nix::fcntl::{fcntl, FcntlArg, FdFlag, OFlag}; +use nix::fcntl::{fcntl, FcntlArg, FdFlag, open, OFlag}; use nix::unistd::*; use nix::unistd::ForkResult::*; use nix::sys::signal::{SaFlags, SigAction, SigHandler, SigSet, Signal, sigaction}; @@ -6,7 +6,7 @@ use nix::sys::wait::*; use nix::sys::stat::{self, Mode, SFlag}; use std::{env, iter}; use std::ffi::CString; -use std::fs::File; +use std::fs::{self, File}; use std::io::Write; use std::os::unix::prelude::*; use tempfile::{self, tempfile}; @@ -301,6 +301,49 @@ fn test_getcwd() { assert_eq!(getcwd().unwrap(), inner_tmp_dir.as_path()); } +#[test] +fn test_chown() { + // Testing for anything other than our own UID/GID is hard. + let uid = Some(getuid()); + let gid = Some(getgid()); + + let tempdir = tempfile::tempdir().unwrap(); + let path = tempdir.path().join("file"); + { + File::create(&path).unwrap(); + } + + chown(&path, uid, gid).unwrap(); + chown(&path, uid, None).unwrap(); + chown(&path, None, gid).unwrap(); + + fs::remove_file(&path).unwrap(); + chown(&path, uid, gid).unwrap_err(); +} + +#[test] +fn test_fchownat() { + // Testing for anything other than our own UID/GID is hard. + let uid = Some(getuid()); + let gid = Some(getgid()); + + let tempdir = tempfile::tempdir().unwrap(); + let path = tempdir.path().join("file"); + { + File::create(&path).unwrap(); + } + + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + + fchownat(Some(dirfd), "file", uid, gid, FchownatFlags::FollowSymlink).unwrap(); + + chdir(tempdir.path()).unwrap(); + fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap(); + + fs::remove_file(&path).unwrap(); + fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap_err(); +} + #[test] fn test_lseek() { const CONTENTS: &[u8] = b"abcdef123456"; @@ -390,6 +433,42 @@ fn test_pipe2() { assert!(f1.contains(FdFlag::FD_CLOEXEC)); } +#[test] +fn test_truncate() { + let tempdir = tempfile::tempdir().unwrap(); + let path = tempdir.path().join("file"); + + { + let mut tmp = File::create(&path).unwrap(); + const CONTENTS: &[u8] = b"12345678"; + tmp.write_all(CONTENTS).unwrap(); + } + + truncate(&path, 4).unwrap(); + + let metadata = fs::metadata(&path).unwrap(); + assert_eq!(4, metadata.len()); +} + +#[test] +fn test_ftruncate() { + let tempdir = tempfile::tempdir().unwrap(); + let path = tempdir.path().join("file"); + + let tmpfd = { + let mut tmp = File::create(&path).unwrap(); + const CONTENTS: &[u8] = b"12345678"; + tmp.write_all(CONTENTS).unwrap(); + tmp.into_raw_fd() + }; + + ftruncate(tmpfd, 2).unwrap(); + close(tmpfd).unwrap(); + + let metadata = fs::metadata(&path).unwrap(); + assert_eq!(2, metadata.len()); +} + // Used in `test_alarm`. static mut ALARM_CALLED: bool = false; From c0500ef737c1628a007e3a5d966ff8a2a5edd05c Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 20 Oct 2018 15:16:41 +0200 Subject: [PATCH 6/8] Fixed an issue with missing use directives. --- src/unistd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unistd.rs b/src/unistd.rs index 8dd54b3da0..9e33b31b21 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2,7 +2,7 @@ use errno::{self, Errno}; use {Error, Result, NixPath}; -use fcntl::{at_rawfd, FdFlag, OFlag}; +use fcntl::{AtFlags, at_rawfd, OFlag}; 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}; use std::{fmt, mem, ptr}; From 9f1329f93860bb3a3c1918f1ac95b8c4511d6cf1 Mon Sep 17 00:00:00 2001 From: "Dr. Koutheir Attouchi" Date: Sun, 21 Oct 2018 11:30:28 +0200 Subject: [PATCH 7/8] More precise change log entries for dup3() --- CHANGELOG.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b653b0fe7..02dc117fd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,14 +27,14 @@ This project adheres to [Semantic Versioning](http://semver.org/). ([#955](https://github.com/nix-rust/nix/pull/955)) - Added a `fchown` wrapper. ([#957](https://github.com/nix-rust/nix/pull/957)) -- Added a `dup3` wrapper by a direct call to the system call `dup3` instead of emulating it via - `dup2` and `fcntl` which could cause a race condition. The `dup3` system call is supported - on the following platforms: Fuchsia, Emscripten, FreeBSD, Linux, Solaris, NetBSD, OpenBSD. - ([#957](https://github.com/nix-rust/nix/pull/957)) ### Changed - Increased required Rust version to 1.22.1/ ([#900](https://github.com/nix-rust/nix/pull/900)) +- Changed the `dup3` wrapper to perform a direct call to the system call `dup3` instead of emulating + it via `dup2` and `fcntl` which could cause a race condition. The `dup3` system call is supported + on the following platforms: Fuchsia, Emscripten, FreeBSD, Linux, Solaris, NetBSD, OpenBSD. + ([#957](https://github.com/nix-rust/nix/pull/957)) ### Fixed - Made `preadv` take immutable slice of IoVec. @@ -43,6 +43,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ([#918](https://github.com/nix-rust/nix/pull/918)) ### Removed +- Removed the `dup3` wrapper on OSX, which was emulated via `dup2` and `fcntl`, which could cause + a race condition. The `dup3` system call is not supported on OSX. + ([#957](https://github.com/nix-rust/nix/pull/957)) ## [0.11.0] 2018-06-01 From eccf010ec52b785f4d76c55b5c4f07b68039c665 Mon Sep 17 00:00:00 2001 From: "Dr. Koutheir Attouchi" Date: Sun, 21 Oct 2018 18:25:00 +0200 Subject: [PATCH 8/8] Sorted OS names in alphabetical order --- src/unistd.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/unistd.rs b/src/unistd.rs index 9e33b31b21..ffd423fd33 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -373,13 +373,13 @@ pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result { /// /// This function behaves similar to `dup2()` but allows for flags to be /// specified. -#[cfg(any(target_os = "fuchsia", - target_os = "emscripten", +#[cfg(any(target_os = "emscripten", target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", - target_os = "solaris", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { let res = unsafe { libc::dup3(oldfd, newfd, flags.bits()) };