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 fork auf Android std.thread (pthread-basiert) verwenden. Bionic erlaubt clone-basierte Threads ohne Einschränkungen.
  • Die _unsupported-Stubs liefern explizit −1 (und nicht ENOSYS vom 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.dns und std.net.tls verwenden.

Verwandte Units

Letzte Aktualisierung: 2026-06-05