summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sys/socket.rs40
-rw-r--r--src/unistd.rs37
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]