Skip to content

Commit

Permalink
Implement accept4 on x86 android with socketcall syscall.
Browse files Browse the repository at this point in the history
  • Loading branch information
de-vri-es committed Feb 27, 2021
1 parent ec101fa commit 446f7a7
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
29 changes: 29 additions & 0 deletions src/unix/linux_like/android/b32/x86/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
16 changes: 16 additions & 0 deletions src/unix/linux_like/android/b64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
14 changes: 0 additions & 14 deletions src/unix/linux_like/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Expand Down

0 comments on commit 446f7a7

Please sign in to comment.