Inhaltsverzeichnis

std.pipe

Pipes & fd-Duplikation (WP-2): Erstellt unidirektionale anonyme Pipes für die Prozesskommunikation und dupliziert Dateideskriptoren (dup/dup2/dup3). Typischer Einsatz: Eltern-Kind-Kommunikation nach fork, Stdout/Stderr-Umleitung und Pipe-Kaskaden.

Standard Library · std.process · std.mqueue


Konstanten

Alle Konstanten dieser Unit:

Konstante Wert Beschreibung
O_CLOEXEC 524288 fd bei exec() schließen (0x80000)
O_NONBLOCK 2048 Pipe-fds nicht-blockierend (0x800)

Funktionen

Alle öffentlichen Funktionen dieser Unit im Überblick:

Pipe erstellen

Übersicht:

Signatur Beschreibung
PipeCreate(readFdOut: int64, writeFdOut: int64): int64 Erstellt ein Pipe-Paar. readFdOut und writeFdOut sind je alloc(8)-Buffer; nach Aufruf via peek64 lesen. Gibt 0 bei Erfolg zurück
Pipe2(readFdOut: int64, writeFdOut: int64, flags: int64): int64 Wie PipeCreate, aber mit Flags (O_CLOEXEC, O_NONBLOCK oder Kombination)

fd-Duplikation

Übersicht:

Signatur Beschreibung
FdDup(oldFd: int64): int64 Dupliziert oldFd auf den nächst-freien fd. Gibt den neuen fd zurück
FdDup2(oldFd: int64, newFd: int64): int64 Dupliziert oldFd auf newFd (schließt newFd falls bereits offen). Gibt newFd zurück
FdDup3(oldFd: int64, newFd: int64, flags: int64): int64 Wie FdDup2, aber mit Flags (z. B. O_CLOEXEC)

Verwendung

Grundlegendes Anwendungsbeispiel:

Eltern-Kind-Kommunikation

Beispiel:

import std.pipe;
import std.process;
import std.alloc;
import std.io;

fn Main(): void {
    var rBuf: int64 := alloc(8);
    var wBuf: int64 := alloc(8);
    PipeCreate(rBuf, wBuf);

    var rFd := peek64(rBuf);
    var wFd := peek64(wBuf);
    free(rBuf, 8);
    free(wBuf, 8);

    var pid := Fork();
    if (pid == 0) {
        // Kindprozess: liest von der Pipe
        close(wFd);
        var buf: int64 := alloc(64);
        var n := read(rFd, buf, 64);
        PrintLn("Kind empfing: " + buf as pchar);
        free(buf, 64);
        close(rFd);
    } else {
        // Elternprozess: schreibt in die Pipe
        close(rFd);
        var msg: pchar := "Hallo Kind";
        write(wFd, msg as int64, 11);
        close(wFd);
        Wait(pid);
    }
}

Stdout auf Pipe umleiten (FdDup2)

Beispiel:

import std.pipe;
import std.alloc;

fn RedirectStdout(): int64 {
    var rBuf: int64 := alloc(8);
    var wBuf: int64 := alloc(8);
    Pipe2(rBuf, wBuf, O_CLOEXEC);

    var rFd := peek64(rBuf);
    var wFd := peek64(wBuf);
    free(rBuf, 8);
    free(wBuf, 8);

    // fd 1 (stdout) auf Schreib-Ende der Pipe umleiten
    FdDup2(wFd, 1);
    close(wFd);

    // Alles was jetzt über fd 1 geschrieben wird, landet in der Pipe.
    // Lese-Ende (rFd) zurückgeben.
    return rFd;
}

Nicht-blockierende Pipe

Beispiel:

import std.pipe;
import std.alloc;
import std.io;

fn TryRead(pipeFd: int64): bool {
    var buf: int64 := alloc(256);
    var n := read(pipeFd, buf, 256);
    free(buf, 256);

    if (n < 0) {
        // n == -11 bedeutet EAGAIN — keine Daten vorhanden
        return false;
    }
    return true;
}

fn SetupNonblocking(): int64 {
    var rBuf: int64 := alloc(8);
    var wBuf: int64 := alloc(8);
    Pipe2(rBuf, wBuf, O_NONBLOCK | O_CLOEXEC);
    var rFd := peek64(rBuf);
    free(rBuf, 8);
    free(wBuf, 8);
    return rFd;
}


Hinweise

Wichtige Hinweise für den Einsatz dieser Unit:


Verwandte Units

Enthaltene Untermodule im Überblick:

Letzte Aktualisierung: 2026-06-05