Skip to content

Commit 1bd2d20

Browse files
committed
std: Atomically set CLOEXEC for sockets if possible
This commit adds support for creating sockets with the `SOCK_CLOEXEC` flag. Support for this flag was added in Linux 2.6.27, however, and support does not exist on platforms other than Linux. For this reason we still have the same fallback as before but just special case Linux if we can.
1 parent 0fff73b commit 1bd2d20

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

src/libstd/sys/unix/net.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ pub use libc as netc;
2525

2626
pub type wrlen_t = size_t;
2727

28+
// See below for the usage of SOCK_CLOEXEC, but this constant is only defined on
29+
// Linux currently (e.g. support doesn't exist on other platforms). In order to
30+
// get name resolution to work and things to compile we just define a dummy
31+
// SOCK_CLOEXEC here for other platforms. Note that the dummy constant isn't
32+
// actually ever used (the blocks below are wrapped in `if cfg!` as well.
33+
#[cfg(target_os = "linux")]
34+
use libc::SOCK_CLOEXEC;
35+
#[cfg(not(target_os = "linux"))]
36+
const SOCK_CLOEXEC: c_int = 0;
37+
2838
pub struct Socket(FileDesc);
2939

3040
pub fn init() {}
@@ -48,6 +58,19 @@ impl Socket {
4858
SocketAddr::V6(..) => libc::AF_INET6,
4959
};
5060
unsafe {
61+
// On linux we first attempt to pass the SOCK_CLOEXEC flag to
62+
// atomically create the socket and set it as CLOEXEC. Support for
63+
// this option, however, was added in 2.6.27, and we still support
64+
// 2.6.18 as a kernel, so if the returned error is EINVAL we
65+
// fallthrough to the fallback.
66+
if cfg!(target_os = "linux") {
67+
match cvt(libc::socket(fam, ty | SOCK_CLOEXEC, 0)) {
68+
Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
69+
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
70+
Err(e) => return Err(e),
71+
}
72+
}
73+
5174
let fd = try!(cvt(libc::socket(fam, ty, 0)));
5275
let fd = FileDesc::new(fd);
5376
fd.set_cloexec();

0 commit comments

Comments
 (0)