Skip to content

Commit 31a2777

Browse files
committed
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
1 parent ec101fa commit 31a2777

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

src/unix/linux_like/android/b32/x86/mod.rs

+29
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,35 @@ pub const REG_EFL: ::c_int = 16;
574574
pub const REG_UESP: ::c_int = 17;
575575
pub const REG_SS: ::c_int = 18;
576576

577+
// socketcall values from linux/net.h (only the needed ones, and not public)
578+
const SYS_ACCEPT4: ::c_int = 18;
579+
580+
f! {
581+
// Sadly, Android before 5.0 (API level 21), the accept4 syscall is not
582+
// exposed by the libc. As work-around, we implement it as raw syscall.
583+
// Note that for x86, the `accept4` syscall is not available either,
584+
// and we must use the `socketcall` syscall instead.
585+
// This workaround can be removed if the minimum Android version is bumped.
586+
// When the workaround is removed, `accept4` can be moved back
587+
// to `linux_like/mod.rs`
588+
pub fn accept4(
589+
fd: ::c_int,
590+
addr: *mut ::sockaddr,
591+
len: *mut ::socklen_t,
592+
flg: ::c_int
593+
) -> ::c_int {
594+
// Arguments are passed as array of `long int`
595+
// (which is big enough on x86 for a pointer).
596+
let mut args = [
597+
fd as ::c_long,
598+
addr as ::c_long,
599+
len as ::c_long,
600+
flg as ::c_long,
601+
];
602+
::syscall(SYS_socketcall, SYS_ACCEPT4, args[..].as_mut_ptr())
603+
}
604+
}
605+
577606
cfg_if! {
578607
if #[cfg(libc_align)] {
579608
mod align;

src/unix/linux_like/android/b64/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,22 @@ pub const UT_LINESIZE: usize = 32;
305305
pub const UT_NAMESIZE: usize = 32;
306306
pub const UT_HOSTSIZE: usize = 256;
307307

308+
f! {
309+
// Sadly, Android before 5.0 (API level 21), the accept4 syscall is not
310+
// exposed by the libc. As work-around, we implement it through `syscall`
311+
// directly. This workaround can be removed if the minimum version of
312+
// Android is bumped. When the workaround is removed, `accept4` can be
313+
// moved back to `linux_like/mod.rs`
314+
pub fn accept4(
315+
fd: ::c_int,
316+
addr: *mut ::sockaddr,
317+
len: *mut ::socklen_t,
318+
flg: ::c_int
319+
) -> ::c_int {
320+
::syscall(SYS_accept4, fd, addr, len, flg) as ::c_int
321+
}
322+
}
323+
308324
extern "C" {
309325
pub fn getauxval(type_: ::c_ulong) -> ::c_ulong;
310326
}

src/unix/linux_like/android/mod.rs

-14
Original file line numberDiff line numberDiff line change
@@ -2350,20 +2350,6 @@ f! {
23502350
pub fn SO_EE_OFFENDER(ee: *const ::sock_extended_err) -> *mut ::sockaddr {
23512351
ee.offset(1) as *mut ::sockaddr
23522352
}
2353-
2354-
// Sadly, Android before 5.0 (API level 21), the accept4 syscall is not
2355-
// exposed by the libc. As work-around, we implement it through `syscall`
2356-
// directly. This workaround can be removed if the minimum version of
2357-
// Android is bumped. When the workaround is removed, `accept4` can be
2358-
// moved back to `linux_like/mod.rs`
2359-
pub fn accept4(
2360-
fd: ::c_int,
2361-
addr: *mut ::sockaddr,
2362-
len: *mut ::socklen_t,
2363-
flg: ::c_int
2364-
) -> ::c_int {
2365-
syscall(SYS_accept4, fd, addr, len, flg) as ::c_int
2366-
}
23672353
}
23682354

23692355
extern "C" {

0 commit comments

Comments
 (0)