Skip to content

Commit

Permalink
Auto merge of #27980 - tbu-:pr_cloexec_dup, r=alexcrichton
Browse files Browse the repository at this point in the history
Still needs values of F_DUPFD_CLOEXEC on other OSs.

For Bitrig, NetBSD and OpenBSD the constant was incorrectly in posix01, when
it's actually posix08. In order to maintain backwards-compatiblity, the
constant was only copied, not moved.

cc #24237
  • Loading branch information
bors committed Aug 31, 2015
2 parents 811868e + 1f81ef4 commit 05cc464
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
7 changes: 6 additions & 1 deletion src/liblibc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3614,6 +3614,7 @@ pub mod consts {
pub mod posix08 {
use types::os::arch::c95::c_int;
pub const O_CLOEXEC: c_int = 0x80000;
pub const F_DUPFD_CLOEXEC: c_int = 1030;
}
#[cfg(any(target_arch = "arm",
target_arch = "aarch64",
Expand Down Expand Up @@ -4285,11 +4286,13 @@ pub mod consts {
pub mod posix08 {
use types::os::arch::c95::c_int;
pub const O_CLOEXEC: c_int = 0x100000;
pub const F_DUPFD_CLOEXEC: c_int = 17;
}
#[cfg(target_os = "dragonfly")]
pub mod posix08 {
use types::os::arch::c95::c_int;
pub const O_CLOEXEC: c_int = 0x20000;
pub const F_DUPFD_CLOEXEC: c_int = 17;
}
pub mod bsd44 {
use types::os::arch::c95::c_int;
Expand Down Expand Up @@ -4657,7 +4660,6 @@ pub mod consts {
pub const F_GETLK : c_int = 7;
pub const F_SETLK : c_int = 8;
pub const F_SETLKW : c_int = 9;
pub const F_DUPFD_CLOEXEC : c_int = 10;

pub const SIGTRAP : c_int = 5;
pub const SIG_IGN: size_t = 1;
Expand Down Expand Up @@ -4739,11 +4741,13 @@ pub mod consts {
pub mod posix08 {
use types::os::arch::c95::c_int;
pub const O_CLOEXEC: c_int = 0x10000;
pub const F_DUPFD_CLOEXEC: c_int = 10;
}
#[cfg(target_os = "netbsd")]
pub mod posix08 {
use types::os::arch::c95::c_int;
pub const O_CLOEXEC: c_int = 0x400000;
pub const F_DUPFD_CLOEXEC: c_int = 12;
}
pub mod bsd44 {
use types::os::arch::c95::c_int;
Expand Down Expand Up @@ -5186,6 +5190,7 @@ pub mod consts {
pub mod posix08 {
use types::os::arch::c95::c_int;
pub const O_CLOEXEC: c_int = 0x1000000;
pub const F_DUPFD_CLOEXEC: c_int = 67;
}
pub mod bsd44 {
use types::os::arch::c95::c_int;
Expand Down
30 changes: 25 additions & 5 deletions src/libstd/sys/unix/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ use prelude::v1::*;
use ffi::CStr;
use io;
use libc::{self, c_int, size_t};
use net::SocketAddr;
use str;
use sync::atomic::{self, AtomicBool};
use sys::c;
use net::SocketAddr;
use sys::fd::FileDesc;
use sys_common::{AsInner, FromInner, IntoInner};
use sys_common::net::{getsockopt, setsockopt};
Expand Down Expand Up @@ -66,10 +67,29 @@ impl Socket {
}

pub fn duplicate(&self) -> io::Result<Socket> {
let fd = try!(cvt(unsafe { libc::dup(self.0.raw()) }));
let fd = FileDesc::new(fd);
fd.set_cloexec();
Ok(Socket(fd))
use libc::funcs::posix88::fcntl::fcntl;
let make_socket = |fd| {
let fd = FileDesc::new(fd);
fd.set_cloexec();
Socket(fd)
};
static EMULATE_F_DUPFD_CLOEXEC: AtomicBool = AtomicBool::new(false);
if !EMULATE_F_DUPFD_CLOEXEC.load(atomic::Ordering::Relaxed) {
match cvt(unsafe { fcntl(self.0.raw(), libc::F_DUPFD_CLOEXEC, 0) }) {
// `EINVAL` can only be returned on two occasions: Invalid
// command (second parameter) or invalid third parameter. 0 is
// always a valid third parameter, so it must be the second
// parameter.
//
// Store the result in a global variable so we don't try each
// syscall twice.
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {
EMULATE_F_DUPFD_CLOEXEC.store(true, atomic::Ordering::Relaxed);
}
res => return res.map(make_socket),
}
}
cvt(unsafe { fcntl(self.0.raw(), libc::F_DUPFD, 0) }).map(make_socket)
}

pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
Expand Down

0 comments on commit 05cc464

Please sign in to comment.