diff options
Diffstat (limited to 'src')
-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] |