From a4c05bf11dedcb850ee2cf929060ff0db8be71b4 Mon Sep 17 00:00:00 2001 From: Maarten de Vries Date: Wed, 24 Feb 2021 11:45:23 +0100 Subject: [PATCH 1/3] Implement accept4 on x86 android with `socketcall` syscall. --- src/unix/linux_like/android/b32/x86/mod.rs | 34 ++++++++++++++++++++++ src/unix/linux_like/android/b64/mod.rs | 16 ++++++++++ src/unix/linux_like/android/mod.rs | 14 --------- 3 files changed, 50 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 879ea1a174d38..f5f0d60b4cbf7 100644 --- a/src/unix/linux_like/android/b32/x86/mod.rs +++ b/src/unix/linux_like/android/b32/x86/mod.rs @@ -574,6 +574,40 @@ 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 Andoird 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, + ]; + socketcall(SYS_ACCEPT4, &args) + } +} + +extern "C" { + // used to implement `accept4`, but not made public + fn socketcall(call: c_int, args: *mut c_long) -> c_int; +} + 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 96244d10fe1e6..d761c20ee7b9d 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 09ecdd62f6bad..dfbef65028af6 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" { From 64614cf8e4aac26870684e9a39a02bfc6dfdebb6 Mon Sep 17 00:00:00 2001 From: Maarten de Vries Date: Wed, 24 Feb 2021 12:07:50 +0100 Subject: [PATCH 2/3] Fix typo in src/unix/linux_like/android/b32/x86/mod.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sebastian Dröge --- src/unix/linux_like/android/b32/x86/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/linux_like/android/b32/x86/mod.rs b/src/unix/linux_like/android/b32/x86/mod.rs index f5f0d60b4cbf7..f048e8447c213 100644 --- a/src/unix/linux_like/android/b32/x86/mod.rs +++ b/src/unix/linux_like/android/b32/x86/mod.rs @@ -582,7 +582,7 @@ f! { // 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 Andoird version is bumped. + // 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( From df5f0de11ed21719306f8f793e8188b67a04a1ea Mon Sep 17 00:00:00 2001 From: Maarten de Vries Date: Fri, 26 Feb 2021 11:09:53 +0100 Subject: [PATCH 3/3] Fix socketcall declaration and invocation. --- src/unix/linux_like/android/b32/x86/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/unix/linux_like/android/b32/x86/mod.rs b/src/unix/linux_like/android/b32/x86/mod.rs index f048e8447c213..8fbc015dcf2e7 100644 --- a/src/unix/linux_like/android/b32/x86/mod.rs +++ b/src/unix/linux_like/android/b32/x86/mod.rs @@ -599,13 +599,13 @@ f! { len as ::c_long, flg as ::c_long, ]; - socketcall(SYS_ACCEPT4, &args) + socketcall(SYS_ACCEPT4, args[..].as_mut_ptr()) } } extern "C" { // used to implement `accept4`, but not made public - fn socketcall(call: c_int, args: *mut c_long) -> c_int; + fn socketcall(call: ::c_int, args: *mut ::c_long) -> ::c_int; } cfg_if! {