Skip to content

Commit

Permalink
Use SOCK_CLOEXEC and accept4() on more platforms.
Browse files Browse the repository at this point in the history
  • Loading branch information
de-vri-es committed Oct 30, 2020
1 parent 8df58ae commit 59c6ae6
Showing 1 changed file with 32 additions and 6 deletions.
38 changes: 32 additions & 6 deletions library/std/src/sys/unix/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,18 @@ impl Socket {
pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
unsafe {
cfg_if::cfg_if! {
if #[cfg(target_os = "linux")] {
// On Linux we pass the SOCK_CLOEXEC flag to atomically create
// the socket and set it as CLOEXEC, added in 2.6.27.
if #[cfg(any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "opensbd",
))] {
// On platforms that support it we pass the SOCK_CLOEXEC
// flag to atomically create the socket and set it as
// CLOEXEC. On Linux this was added in 2.6.27.
let fd = cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0))?;
Ok(Socket(FileDesc::new(fd)))
} else {
Expand All @@ -83,7 +92,15 @@ impl Socket {
let mut fds = [0, 0];

cfg_if::cfg_if! {
if #[cfg(target_os = "linux")] {
if #[cfg(any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "opensbd",
))] {
// Like above, set cloexec atomically
cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?;
Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1]))))
Expand Down Expand Up @@ -174,9 +191,18 @@ impl Socket {
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> {
// Unfortunately the only known way right now to accept a socket and
// atomically set the CLOEXEC flag is to use the `accept4` syscall on
// Linux. This was added in 2.6.28, glibc 2.10 and musl 0.9.5.
// platforms that support it. On Linux, this was added in 2.6.28,
// glibc 2.10 and musl 0.9.5.
cfg_if::cfg_if! {
if #[cfg(target_os = "linux")] {
if #[cfg(any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "opensbd",
))] {
let fd = cvt_r(|| unsafe {
libc::accept4(self.0.raw(), storage, len, libc::SOCK_CLOEXEC)
})?;
Expand Down

0 comments on commit 59c6ae6

Please sign in to comment.