diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2016-02-04 13:22:51 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2016-02-05 16:58:10 -0800 |
| commit | 0fff73b64a9658c9a3aa228488964d09e63115b4 (patch) | |
| tree | b56882a79aac5bc50479fb330ae228dcd7f5e77f /src/libstd/sys | |
| parent | 64d7eca0e5a80a961c022eed3581f0ab3f00adfc (diff) | |
| download | rust-0fff73b64a9658c9a3aa228488964d09e63115b4.tar.gz rust-0fff73b64a9658c9a3aa228488964d09e63115b4.zip | |
std: When duplicating fds, skip extra set_cloexec
Similar to the previous commit, if `F_DUPFD_CLOEXEC` succeeds then there's no need for us to then call `set_cloexec` on platforms other than Linux. The bug mentioned of kernels not actually setting the `CLOEXEC` flag has only been repored on Linux, not elsewhere.
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/fd.rs | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index d5f03764be2..0eadee54e26 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -77,9 +77,7 @@ impl FileDesc { // follow a strategy similar to musl [1] where if passing // F_DUPFD_CLOEXEC causes `fcntl` to return EINVAL it means it's not // supported (the third parameter, 0, is always valid), so we stop - // trying that. We also *still* call the `set_cloexec` method as - // apparently some kernel at some point stopped setting CLOEXEC even - // though it reported doing so on F_DUPFD_CLOEXEC. + // trying that. // // Also note that Android doesn't have F_DUPFD_CLOEXEC, but get it to // resolve so we at least compile this. @@ -95,14 +93,25 @@ impl FileDesc { fd.set_cloexec(); fd }; - static TRY_CLOEXEC: AtomicBool = AtomicBool::new(true); + static TRY_CLOEXEC: AtomicBool = + AtomicBool::new(!cfg!(target_os = "android")); let fd = self.raw(); - if !cfg!(target_os = "android") && TRY_CLOEXEC.load(Ordering::Relaxed) { + if TRY_CLOEXEC.load(Ordering::Relaxed) { match cvt(unsafe { libc::fcntl(fd, F_DUPFD_CLOEXEC, 0) }) { + // We *still* call the `set_cloexec` method as apparently some + // linux kernel at some point stopped setting CLOEXEC even + // though it reported doing so on F_DUPFD_CLOEXEC. + Ok(fd) => { + return Ok(if cfg!(target_os = "linux") { + make_filedesc(fd) + } else { + FileDesc::new(fd) + }) + } Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => { TRY_CLOEXEC.store(false, Ordering::Relaxed); } - res => return res.map(make_filedesc), + Err(e) => return Err(e), } } cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD, 0) }).map(make_filedesc) |
