std.net.internal.syscalls_android
Android-Syscall-Wrapper (WP-AND-04): Stellt Netzwerk-Syscalls unter expliziten Android-Namen bereit. Auf ARM64 und x86_64 verwendet Android dieselben Syscall-Nummern wie upstream Linux — die Wrapper delegieren direkt an die entsprechenden Funktionen aus std.net.internal.syscalls_linux. Für Syscalls, die Bionic oder SELinux in App-Prozessen blockiert, sind explizite _unsupported-Stubs enthalten, die sofort −1 zurückgeben.
→ std.net.internal.types · std.net.internal.syscalls_linux · Standard Library
Netzwerk-Syscalls
Alle Wrapper delegieren 1:1 an die entsprechenden sys_*-Funktionen. Rückgabewerte und Fehler-Semantik sind identisch mit Linux.
| Signatur | Beschreibung |
|---|---|
sca_socket(domain: int64, socktype: int64, protocol: int64): int64 | Erstellt einen Socket. Gibt fd zurück, < 0 bei Fehler. |
sca_bind(sockfd: int64, addr: int64, addrlen: int64): int64 | Bindet Socket an eine lokale Adresse. Gibt 0 bei Erfolg. |
sca_listen(sockfd: int64, backlog: int64): int64 | Markiert Socket als passiven Listener. Gibt 0 bei Erfolg. |
sca_accept(sockfd: int64, addr: int64, addrlen: int64): int64 | Akzeptiert eine eingehende Verbindung. Gibt neuen fd zurück. |
sca_connect(sockfd: int64, addr: int64, addrlen: int64): int64 | Verbindet Socket mit einer Remote-Adresse. Gibt 0 bei Erfolg. |
sca_recvfrom(sockfd: int64, buf: int64, len: int64, flags: int64, src_addr: int64, addrlen: int64): int64 | Empfängt Daten; füllt optional src_addr mit der Absenderadresse. |
sca_sendto(sockfd: int64, buf: int64, len: int64, flags: int64, dest_addr: int64, addrlen: int64): int64 | Sendet Daten; bei verbundenen Sockets dest_addr = 0. |
sca_close(sockfd: int64): int64 | Schließt den Socket-fd. Gibt 0 bei Erfolg. |
sca_setsockopt(sockfd: int64, level: int64, optname: int64, optval: int64, optlen: int64): int64 | Setzt eine Socket-Option. Gibt 0 bei Erfolg. |
sca_getsockopt(sockfd: int64, level: int64, optname: int64, optval: int64, optlen: int64): int64 | Liest eine Socket-Option. Gibt 0 bei Erfolg. |
sca_set_nonblock(sockfd: int64): int64 | Setzt O_NONBLOCK via fcntl(F_GETFL/F_SETFL). Gibt 0 bei Erfolg. |
sca_shutdown(sockfd: int64, how: int64): int64 | Beendet einen Teil oder beide Seiten der Verbindung (SHUT_RD=0, SHUT_WR=1, SHUT_RDWR=2). |
Eingeschränkte Syscalls (Stubs)
Folgende Syscalls werden von SELinux in normalen Android-App-Prozessen blockiert. Die Stubs geben sofort −1 zurück, statt den Kernel aufzurufen:
| Funktion | Grund |
|---|---|
sca_fork_unsupported(): int64 | fork ist in Bionic-basierten App-Prozessen nicht empfohlen; stattdessen std.thread (pthread/clone) verwenden |
sca_vfork_unsupported(): int64 | Wie fork — nicht unterstützt |
sca_ptrace_unsupported(): int64 | ptrace ist auf nicht-debuggbaren App-Prozessen durch SELinux blockiert; Android Trace API oder systrace verwenden |
sca_personality_unsupported(): int64 | personality() wird durch SELinux in der App-Domain abgelehnt |
sca_reboot_unsupported(): int64 | reboot() ist dem Power-Management-Daemon vorbehalten |
Verwendung
TCP-Client auf Android
import std.net.internal.syscalls_android;
import std.net.internal.types;
fn ConnectTCP(ip: int64, port: int64): int64 {
var fd := sca_socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) { return -1; }
// sockaddr_in aufbauen
var addr: int64 := alloc(SOCKADDR_IN_SIZE);
pokeSockaddrIn(addr, AF_INET, port, ip);
var r := sca_connect(fd, addr, SOCKADDR_IN_SIZE);
free(addr, SOCKADDR_IN_SIZE);
if (r < 0) { sca_close(fd); return -1; }
return fd;
}
Non-blocking UDP-Socket
import std.net.internal.syscalls_android;
fn OpenUDPNonblock(): int64 {
var fd := sca_socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) { return -1; }
sca_set_nonblock(fd);
return fd;
}
Senden und Empfangen
import std.net.internal.syscalls_android;
import std.alloc;
fn SendRecv(fd: int64, msg: int64, msglen: int64): int64 {
var sent := sca_sendto(fd, msg, msglen, 0, 0, 0);
if (sent < 0) { return -1; }
var buf: int64 := alloc(4096);
var n := sca_recvfrom(fd, buf, 4096, 0, 0, 0);
free(buf, 4096);
return n;
}
Hinweise
- Syscall-Nummern: ARM64 und x86_64 Android verwenden dieselben Nummern wie Linux; die
sca_*-Wrapper sind auf beiden Architekturen korrekt. - SELinux-Policies variieren je nach Android-Version, ROM und App-Zertifizierung. Selbst unterstützte Syscalls können auf bestimmten Geräten durch herstellerspezifische SELinux-Regeln blockiert werden.
- fork / Thread: Statt
forkauf Androidstd.thread(pthread-basiert) verwenden. Bionic erlaubt clone-basierte Threads ohne Einschränkungen. - Die
_unsupported-Stubs liefern explizit−1(und nichtENOSYSvom Kernel), damit Fehler in Userland-Logs sichtbar werden, bevor SELinux den Prozess beendet. - Für höhere Abstraktionen (TCP/UDP, DNS, TLS) die übergeordneten Units
std.net.socket(TCP/UDP),std.net.dnsundstd.net.tlsverwenden.
Verwandte Units
std.net.internal.syscalls_linux— die Linux-Syscall-Basis, auf die allesca_*-Wrapper delegierenstd.net.socket— TCP/UDP-Verbindungen (High-Level)std.thread— Threads (Android-Alternative zu fork)
Letzte Aktualisierung: 2026-06-05
