Skip to content

Commit 7171945

Browse files
author
Bryant Mairs
committed
Remove emulation of FD_CLOEXEC/O_NONBLOCK
Rather than using the native implementation of these constants on supported platforms, the native implementation was instead emulated. This was also hidden from the user even though this could result in data races and the functionality being broken. Native functionality is, however, not support on macos/ios. Rather than enable this emulation solely for this platform, it should be removed as this is a dangerous abstraction.
1 parent badb451 commit 7171945

File tree

2 files changed

+20
-97
lines changed

2 files changed

+20
-97
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
5151
([#892](https://github.com/nix-rust/nix/pull/892))
5252
- Remove `IFF_NOTRAILERS` on OpenBSD, as it has been removed in OpenBSD 6.3
5353
([#893](https://github.com/nix-rust/nix/pull/893))
54+
- Emulation of `FD_CLOEXEC` and `O_NONBLOCK` was removed from `socket()`, `accept4()`, and
55+
`socketpair()`.
56+
([#907](https://github.com/nix-rust/nix/pull/907))
5457

5558
### Fixed
5659
- Fixed possible panics when using `SigAction::flags` on Linux

src/sys/socket/mod.rs

Lines changed: 17 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//! [Further reading](http://man7.org/linux/man-pages/man7/socket.7.html)
44
use {Error, Result};
55
use errno::Errno;
6-
use features;
76
use libc::{self, c_void, c_int, socklen_t, size_t};
87
use std::{fmt, mem, ptr, slice};
98
use std::os::unix::io::RawFd;
@@ -692,87 +691,44 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
692691
///
693692
/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html)
694693
pub fn socket<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result<RawFd> {
695-
let mut ty = ty as c_int;
696694
let protocol = match protocol.into() {
697695
None => 0,
698696
Some(p) => p as c_int,
699697
};
700-
let feat_atomic = features::socket_atomic_cloexec();
701698

702-
if feat_atomic {
703-
ty |= flags.bits();
704-
}
699+
// SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a
700+
// little easier to understand by separating it out. So we have to merge these bitfields
701+
// here.
702+
let mut ty = ty as c_int;
703+
ty |= flags.bits();
705704

706705
// TODO: Check the kernel version
707-
let res = try!(Errno::result(unsafe { libc::socket(domain as c_int, ty, protocol) }));
708-
709-
#[cfg(any(target_os = "android",
710-
target_os = "dragonfly",
711-
target_os = "freebsd",
712-
target_os = "linux",
713-
target_os = "netbsd",
714-
target_os = "openbsd"))]
715-
{
716-
use fcntl::{fcntl, FdFlag, OFlag};
717-
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
718-
719-
if !feat_atomic {
720-
if flags.contains(SockFlag::SOCK_CLOEXEC) {
721-
try!(fcntl(res, F_SETFD(FdFlag::FD_CLOEXEC)));
722-
}
723-
724-
if flags.contains(SockFlag::SOCK_NONBLOCK) {
725-
try!(fcntl(res, F_SETFL(OFlag::O_NONBLOCK)));
726-
}
727-
}
728-
}
706+
let res = unsafe { libc::socket(domain as c_int, ty, protocol) };
729707

730-
Ok(res)
708+
Errno::result(res)
731709
}
732710

733711
/// Create a pair of connected sockets
734712
///
735713
/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html)
736714
pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, protocol: T,
737715
flags: SockFlag) -> Result<(RawFd, RawFd)> {
738-
let mut ty = ty as c_int;
739716
let protocol = match protocol.into() {
740717
None => 0,
741718
Some(p) => p as c_int,
742719
};
743-
let feat_atomic = features::socket_atomic_cloexec();
744720

745-
if feat_atomic {
746-
ty |= flags.bits();
747-
}
721+
// SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a
722+
// little easier to understand by separating it out. So we have to merge these bitfields
723+
// here.
724+
let mut ty = ty as c_int;
725+
ty |= flags.bits();
726+
748727
let mut fds = [-1, -1];
749-
let res = unsafe {
750-
libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr())
751-
};
752-
try!(Errno::result(res));
753-
754-
#[cfg(any(target_os = "android",
755-
target_os = "dragonfly",
756-
target_os = "freebsd",
757-
target_os = "linux",
758-
target_os = "netbsd",
759-
target_os = "openbsd"))]
760-
{
761-
use fcntl::{fcntl, FdFlag, OFlag};
762-
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
763728

764-
if !feat_atomic {
765-
if flags.contains(SockFlag::SOCK_CLOEXEC) {
766-
try!(fcntl(fds[0], F_SETFD(FdFlag::FD_CLOEXEC)));
767-
try!(fcntl(fds[1], F_SETFD(FdFlag::FD_CLOEXEC)));
768-
}
729+
let res = unsafe { libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr()) };
730+
Errno::result(res)?;
769731

770-
if flags.contains(SockFlag::SOCK_NONBLOCK) {
771-
try!(fcntl(fds[0], F_SETFL(OFlag::O_NONBLOCK)));
772-
try!(fcntl(fds[1], F_SETFL(OFlag::O_NONBLOCK)));
773-
}
774-
}
775-
}
776732
Ok((fds[0], fds[1]))
777733
}
778734

@@ -810,45 +766,9 @@ pub fn accept(sockfd: RawFd) -> Result<RawFd> {
810766
///
811767
/// [Further reading](http://man7.org/linux/man-pages/man2/accept.2.html)
812768
pub fn accept4(sockfd: RawFd, flags: SockFlag) -> Result<RawFd> {
813-
accept4_polyfill(sockfd, flags)
814-
}
815-
816-
#[inline]
817-
fn accept4_polyfill(sockfd: RawFd, flags: SockFlag) -> Result<RawFd> {
818-
let res = try!(Errno::result(unsafe { libc::accept(sockfd, ptr::null_mut(), ptr::null_mut()) }));
819-
820-
#[cfg(any(target_os = "android",
821-
target_os = "dragonfly",
822-
target_os = "freebsd",
823-
target_os = "linux",
824-
target_os = "netbsd",
825-
target_os = "openbsd"))]
826-
{
827-
use fcntl::{fcntl, FdFlag, OFlag};
828-
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
829-
830-
if flags.contains(SockFlag::SOCK_CLOEXEC) {
831-
try!(fcntl(res, F_SETFD(FdFlag::FD_CLOEXEC)));
832-
}
833-
834-
if flags.contains(SockFlag::SOCK_NONBLOCK) {
835-
try!(fcntl(res, F_SETFL(OFlag::O_NONBLOCK)));
836-
}
837-
}
838-
839-
// Disable unused variable warning on some platforms
840-
#[cfg(not(any(target_os = "android",
841-
target_os = "dragonfly",
842-
target_os = "freebsd",
843-
target_os = "linux",
844-
target_os = "netbsd",
845-
target_os = "openbsd")))]
846-
{
847-
let _ = flags;
848-
}
769+
let res = unsafe { libc::accept4(sockfd, ptr::null_mut(), ptr::null_mut(), flags.bits()) };
849770

850-
851-
Ok(res)
771+
Errno::result(res)
852772
}
853773

854774
/// Initiate a connection on a socket

0 commit comments

Comments
 (0)