diff options
author | Tilde Engineering <engineering@tilde.io> | 2014-10-07 15:25:03 -0700 |
---|---|---|
committer | Tilde Engineering <engineering@tilde.io> | 2014-10-07 15:25:03 -0700 |
commit | 4d680086e17d255e6d5c4a2fab0beb06919c8b52 (patch) | |
tree | 3eb0f060ee5c2e490eccbf75ee865bb546718f03 | |
parent | 92b70a8f3009cec523256724ba11ae2d5f6611e2 (diff) | |
download | nix-4d680086e17d255e6d5c4a2fab0beb06919c8b52.zip |
Fix dup3 and accept4 on Darwin
-rw-r--r-- | src/sys/socket.rs | 40 | ||||
-rw-r--r-- | src/unistd.rs | 37 |
2 files changed, 50 insertions, 27 deletions
diff --git a/src/sys/socket.rs b/src/sys/socket.rs index bef64d7c..5703cbb5 100644 --- a/src/sys/socket.rs +++ b/src/sys/socket.rs @@ -215,6 +215,7 @@ pub fn accept(sockfd: Fd) -> SysResult<Fd> { Ok(res) } +#[cfg(not(any(target_os = "macos", target_os = "ios")))] pub fn accept4(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> { use libc::sockaddr; @@ -225,35 +226,46 @@ pub fn accept4(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> { static accept4: *const (); } - let feat_atomic = !accept4.is_null(); - - let res = if feat_atomic { - unsafe { + if !accept4.is_null() { + let res = unsafe { mem::transmute::<*const (), F>(accept4)( sockfd, ptr::null_mut(), ptr::null_mut(), flags.bits) + }; + + if res < 0 { + return Err(SysError::last()); } + + Ok(res) } else { - unsafe { ffi::accept(sockfd, ptr::null_mut(), ptr::null_mut()) } - }; + accept4_polyfill(sockfd, flags) + } +} + +#[cfg(any(target_os = "macos", target_os = "ios"))] +fn accept4(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> { + accept4_polyfill(sockfd, flags) +} + +#[inline] +fn accept4_polyfill(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> { + let res = unsafe { ffi::accept(sockfd, ptr::null_mut(), ptr::null_mut()) }; if res < 0 { return Err(SysError::last()); } - if !feat_atomic { - if flags.contains(SOCK_CLOEXEC) { - try!(fcntl(res, F_SETFD(FD_CLOEXEC))); - } + if flags.contains(SOCK_CLOEXEC) { + try!(fcntl(res, F_SETFD(FD_CLOEXEC))); + } - if flags.contains(SOCK_NONBLOCK) { - try!(fcntl(res, F_SETFL(O_NONBLOCK))); - } + if flags.contains(SOCK_NONBLOCK) { + try!(fcntl(res, F_SETFL(O_NONBLOCK))); } Ok(res) } - pub fn connect(sockfd: Fd, addr: &SockAddr) -> SysResult<()> { let res = unsafe { match *addr { diff --git a/src/unistd.rs b/src/unistd.rs index cef12f0e..0774d260 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -95,9 +95,8 @@ pub fn dup2(oldfd: Fd, newfd: Fd) -> SysResult<Fd> { Ok(res) } +#[cfg(not(any(target_os = "macos", target_os = "ios")))] pub fn dup3(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> { - use errno::EINVAL; - type F = unsafe extern "C" fn(c_int, c_int, c_int) -> c_int; extern { @@ -117,21 +116,33 @@ pub fn dup3(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> { Ok(res) } else { - if oldfd == newfd { - return Err(SysError { kind: EINVAL }); - } + dup3_polyfill(oldfd, newfd, flags) + } +} - let fd = try!(dup2(oldfd, newfd)); +#[cfg(any(target_os = "macos", target_os = "ios"))] +pub fn dup3(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> { + dup3_polyfill(oldfd, newfd, flags) +} - if flags.contains(O_CLOEXEC) { - if let Err(e) = fcntl(fd, F_SETFD(FD_CLOEXEC)) { - let _ = close(fd); - return Err(e); - } - } +#[inline] +fn dup3_polyfill(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> { + use errno::EINVAL; - Ok(fd) + if oldfd == newfd { + return Err(SysError { kind: EINVAL }); } + + let fd = try!(dup2(oldfd, newfd)); + + if flags.contains(O_CLOEXEC) { + if let Err(e) = fcntl(fd, F_SETFD(FD_CLOEXEC)) { + let _ = close(fd); + return Err(e); + } + } + + Ok(fd) } #[inline] |