Skip to content

Commit

Permalink
Auto merge of #2079 - de-vri-es:android-x86-accept4, r=joshtriplett
Browse files Browse the repository at this point in the history
Implement accept4 on x86 android with `socketcall` syscall.

Linux x86 kernels before 4.3 only support the `socketcall` syscall rather than individual syscalls for socket operations. Since `libc` does a raw syscall for `accept4` on Android, it doesn't work on x86 systems.

This PR instead implements `accept4` for x86 android using `socketcall`. The value for `SYS_ACCEPT4` (in contrast to `SYS_accept4` 👀) is taken from the `linux/net.h` header.

Also note that the `socketcall` syscall takes all arguments as array of long ints. I've double checked with `glibc` to check how they pass arguments, since the Linux man page only says this: "args points to a block containing the actual arguments" and "only standard library implementors and kernel hackers need to know about socketcall()".

This should fix rust-lang/rust#82400
  • Loading branch information
bors committed Feb 26, 2021
2 parents 8a88b7d + df5f0de commit ffbdaaa
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 14 deletions.
34 changes: 34 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,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 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,
];
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;
}

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 ffbdaaa

Please sign in to comment.