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
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). |
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 |
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;
}
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;
}
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;
}
sca_*-Wrapper sind auf beiden Architekturen korrekt.fork auf Android std.thread (pthread-basiert) verwenden. Bionic erlaubt clone-basierte Threads ohne Einschränkungen._unsupported-Stubs liefern explizit −1 (und nicht ENOSYS vom Kernel), damit Fehler in Userland-Logs sichtbar werden, bevor SELinux den Prozess beendet.std.net.socket (TCP/UDP), std.net.dns und std.net.tls verwenden.std.net.internal.syscalls_linux — die Linux-Syscall-Basis, auf die alle sca_*-Wrapper delegierenstd.net.socket — TCP/UDP-Verbindungen (High-Level)std.thread — Threads (Android-Alternative zu fork)Letzte Aktualisierung: 2026-06-05