summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/unix/linux_like/android/b32/x86/mod.rs29
-rw-r--r--src/unix/linux_like/android/b64/mod.rs16
-rw-r--r--src/unix/linux_like/android/mod.rs14
3 files changed, 45 insertions, 14 deletions
diff --git a/src/unix/linux_like/android/b32/x86/mod.rs b/src/unix/linux_like/android/b32/x86/mod.rs
index 879ea1a174..6507cb4e07 100644
--- a/src/unix/linux_like/android/b32/x86/mod.rs
+++ b/src/unix/linux_like/android/b32/x86/mod.rs
@@ -574,6 +574,35 @@ pub const REG_EFL: ::c_int = 16;
pub const REG_UESP: ::c_int = 17;
pub const REG_SS: ::c_int = 18;
+// socketcall values from linux/net.h (only the needed ones, and not public)
+const SYS_ACCEPT4: ::c_int = 18;
+
+f! {
+ // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not
+ // exposed by the libc. As work-around, we implement it as raw syscall.
+ // Note that for x86, the `accept4` syscall is not available either,
+ // and we must use the `socketcall` syscall instead.
+ // This workaround can be removed if the minimum Android version is bumped.
+ // When the workaround is removed, `accept4` can be moved back
+ // to `linux_like/mod.rs`
+ pub fn accept4(
+ fd: ::c_int,
+ addr: *mut ::sockaddr,
+ len: *mut ::socklen_t,
+ flg: ::c_int
+ ) -> ::c_int {
+ // Arguments are passed as array of `long int`
+ // (which is big enough on x86 for a pointer).
+ let mut args = [
+ fd as ::c_long,
+ addr as ::c_long,
+ len as ::c_long,
+ flg as ::c_long,
+ ];
+ ::syscall(SYS_socketcall, SYS_ACCEPT4, args[..].as_mut_ptr())
+ }
+}
+
cfg_if! {
if #[cfg(libc_align)] {
mod align;
diff --git a/src/unix/linux_like/android/b64/mod.rs b/src/unix/linux_like/android/b64/mod.rs
index 96244d10fe..c23e2dbf2d 100644
--- a/src/unix/linux_like/android/b64/mod.rs
+++ b/src/unix/linux_like/android/b64/mod.rs
@@ -305,6 +305,22 @@ pub const UT_LINESIZE: usize = 32;
pub const UT_NAMESIZE: usize = 32;
pub const UT_HOSTSIZE: usize = 256;
+f! {
+ // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not
+ // exposed by the libc. As work-around, we implement it through `syscall`
+ // directly. This workaround can be removed if the minimum version of
+ // Android is bumped. When the workaround is removed, `accept4` can be
+ // moved back to `linux_like/mod.rs`
+ pub fn accept4(
+ fd: ::c_int,
+ addr: *mut ::sockaddr,
+ len: *mut ::socklen_t,
+ flg: ::c_int
+ ) -> ::c_int {
+ ::syscall(SYS_accept4, fd, addr, len, flg) as ::c_int
+ }
+}
+
extern "C" {
pub fn getauxval(type_: ::c_ulong) -> ::c_ulong;
}
diff --git a/src/unix/linux_like/android/mod.rs b/src/unix/linux_like/android/mod.rs
index 09ecdd62f6..dfbef65028 100644
--- a/src/unix/linux_like/android/mod.rs
+++ b/src/unix/linux_like/android/mod.rs
@@ -2350,20 +2350,6 @@ f! {
pub fn SO_EE_OFFENDER(ee: *const ::sock_extended_err) -> *mut ::sockaddr {
ee.offset(1) as *mut ::sockaddr
}
-
- // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not
- // exposed by the libc. As work-around, we implement it through `syscall`
- // directly. This workaround can be removed if the minimum version of
- // Android is bumped. When the workaround is removed, `accept4` can be
- // moved back to `linux_like/mod.rs`
- pub fn accept4(
- fd: ::c_int,
- addr: *mut ::sockaddr,
- len: *mut ::socklen_t,
- flg: ::c_int
- ) -> ::c_int {
- syscall(SYS_accept4, fd, addr, len, flg) as ::c_int
- }
}
extern "C" {