std.process

Prozesserzeugung und -verwaltung über POSIX-Systemaufrufe (fork, execve, execvp, waitpid, kill). spawn(prog) startet einen Kindprozess und gibt seine PID zurück; run(prog) wartet zusätzlich auf das Ende. wait_for/try_wait warten blockierend bzw. non-blocking auf den Exit-Code; terminate(SIGTERM) und terminate_force(SIGKILL) beenden Prozesse; shell(cmd) führt einen Shell-Befehl aus.

Einsatzbereiche: Daemon-Launcher, Build-Systeme, Prozess-Pooling, Test-Runner, Skript-Ausführung aus Lyx-Programmen.

Wie der Exit-Code eines Kindes ankommt

run, wait_for, try_wait und shell liefern den Exit-Code bereits ausgepackt: Die Unit wendet intern (status » 8) & 255 an — das entspricht WEXITSTATUS. Man bekommt also direkt die 0–255 und nicht den rohen wait-Status.

import std.io;
import std.process;

fn main(): int64 {
    PrintLn(IntToStr(shell("exit 42"c)));   // 42
    return 0;
}

 
Ein per Signal beendetes Kind liefert 0 — nicht 137 oder 143. Bei einem Signaltod steht im ausgepackten Feld nichts; das Ergebnis ist von einem Erfolg nicht zu unterscheiden. Nachgemessen: shell("kill -KILL $$") ergibt 0.

Das 128 + n-Schema kennt nur die Shell, die es aus der Signalinformation zusammensetzt. Wer den Unterschied braucht, lässt die Shell den Code melden (shell("cmd; echo $?") und Ausgabe auswerten).

Aus derselben Mechanik folgt: shell("exit 256") ergibt 0 — die Modulo-256-Falle wirkt auch für Kindprozesse (→ Exit-Codes).

try_wait benutzt zwei negative Sonderwerte: -2 = läuft noch, -1 = Fehler beim Warten. Sie sind keine Exit-Codes, sondern Statusmeldungen der Funktion — vor der Auswertung auf < 0 prüfen.

Schlägt execve in einem mit spawn gestarteten Kind fehl, beendet sich das Kind mit 127 — dieselbe Konvention, die die Shell für „Kommando nicht gefunden„ verwendet.

Autor: Andreas Röne
Copyright: 2024-2025 Andreas Röne


Typen

Process = int64

Handle-Konvention für Prozesse:

ExitCode = int64

Rückgabecode-Konvention für Prozesse:


Externe Funktionen

Extern deklarierte Funktionen (aus C-Bibliotheken):

Signatur Beschreibung
fork(): int64 Erzeugt Kindprozess als Kopie des Elternprozesses
execve(path: pchar, argv: pchar, envp: pchar): int64 Ersetzt Prozessabbild mit neuem Programm
execvp(path: pchar, argv: pchar): int64 Führt Programm über PATH-Suche aus
waitpid(pid: int64, status: int64, options: int64): int64 Wartet auf Statusänderung eines Kindprozesses
kill(pid: int64, sig: int64): int64 Sendet Signal an einen Prozess
getpid(): int64 Gibt Prozess-ID des aktuellen Prozesses zurück
 
Die rohen Syscall-Bindings fehlen. fork, execve, execvp, waitpid und kill stehen zwar in dieser Tabelle, melden beim Aufruf aber undefined symbol.

Verfügbar und geprüft ist die höhere Ebene: spawn, run, wait_for, try_wait, terminate, terminate_force und shell.
(Issue #1246)

Konstanten

Name Typ Wert Sichtbarkeit
WNOHANG int64 1 pub
SIGTERM int64 15 pub
SIGKILL int64 9 pub

Funktionen

Signatur Sichtbarkeit Beschreibung
spawn(prog: pchar): Process pub Startet Kindprozess und gibt dessen PID zurück
run(prog: pchar): ExitCode pub Startet Prozess und wartet auf Beendigung
wait_for(pid: int64): ExitCode pub Wartet blockierend auf Prozess-Ende
try_wait(pid: int64): ExitCode pub Prüft non-blocking ob Prozess beendet ist
proc_kill(pid: int64, sig: int64): int64 pub Sendet beliebiges Signal an Prozess
terminate(pid: int64): int64 pub Beendet Prozess mit SIGTERM
terminate_force(pid: int64): int64 pub Beendet Prozess erzwungen mit SIGKILL
is_running(pid: int64): bool pub Prüft ob ein Prozess noch läuft
self_pid(): int64 pub Gibt eigene Prozess-ID zurück
shell(cmd: pchar): ExitCode pub Führt Shell-Befehl aus und gibt Exit-Code zurück