Start · Sprachen · PHP · Referenz · dio_fcntl

dio_fcntl

Funktion

Führt einen <code>fcntl</code>-Systemaufruf auf einem direkten Dateideskriptor durch, um Datei-Flags, Sperren oder andere Eigenschaften zu setzen oder abzufragen.

seit PHP 4.2.0 Kategorie: io

Signatur

dio_fcntl(resource $fd, int $cmd, mixed $arg = null): mixed

Beschreibung

dio_fcntl ist die PHP-Schnittstelle zum POSIX-Systemaufruf fcntl(2) und ermöglicht die Low-Level-Steuerung von Dateideskriptoren, die mit dio_open geöffnet wurden. Typische Anwendungsfälle sind das Setzen von Dateideskriptor-Flags (z. B. O_NONBLOCK), das Abfragen vorhandener Flags sowie das Anlegen und Prüfen von Advisory-Sperren (Record Locking).

Der Parameter cmd steuert, welche Operation ausgeführt wird. Häufig verwendete Konstanten sind F_GETFL (aktuelle Flags lesen), F_SETFL (Flags setzen), F_GETLK (Sperrinformation abfragen), F_SETLK (Sperre setzen oder aufheben) und F_SETLKW (blockierend auf Sperre warten). Diese Konstanten sind direkt von der POSIX-C-Bibliothek übernommen.

Der optionale Parameter arg nimmt entweder einen Integer-Wert (bei Flag-Operationen) oder ein assoziatives Array mit den Schlüsseln type, whence, start und length (bei Sperr-Operationen) entgegen. Die Funktion ist nur auf Systemen verfügbar, die die POSIX-Erweiterung dio unterstützen (Linux, macOS, BSD); unter Windows ist sie nicht verfügbar.

Hinweis: Die dio-Erweiterung ist nicht standardmäßig in PHP eingebaut und muss explizit kompiliert oder als PECL-Paket installiert werden. Sie eignet sich für Szenarien, in denen die Standard-PHP-Datei-API zu viel abstrahiert, etwa bei der Arbeit mit seriellen Schnittstellen, Named Pipes oder wenn präzises Datei-Locking auf Kernel-Ebene erforderlich ist.

Parameter

Name Typ Default Beschreibung
$fd Pflicht resource Ein Dateideskriptor-Ressource, der zuvor mit dio_open geöffnet wurde.
$cmd Pflicht int Die auszuführende Steuerkonstante, z. B. F_GETFL, F_SETFL, F_GETLK, F_SETLK oder F_SETLKW.
$arg mixed null Optionaler Argument-Wert. Bei Flag-Kommandos (F_SETFL) ein Integer mit dem neuen Flag-Wert. Bei Sperr-Kommandos ein assoziatives Array mit den Schlüsseln type (F_RDLCK, F_WRLCK, F_UNLCK), whence, start und length.

Rückgabewert

Typ
mixed
Beschreibung
Bei Abfrage-Kommandos (z. B. F_GETFL) wird der aktuelle Flag-Wert als Integer zurückgegeben. Bei F_GETLK wird ein assoziatives Array mit den Sperrinformationen zurückgegeben. Bei Setz-Kommandos wird bei Erfolg 0 zurückgegeben. Im Fehlerfall wird -1 oder false zurückgegeben.

Beispiele

Non-blocking-Flag auf einem Dateideskriptor setzen

<?php
// Datei im Lese-/Schreibmodus öffnen
$fd = dio_open('/tmp/testpipe', O_RDWR | O_CREAT, 0644);

if ($fd === false) {
    die('Konnte Dateideskriptor nicht öffnen.');
}

// Aktuelle Flags abfragen
$flags = dio_fcntl($fd, F_GETFL);
echo 'Aktuelle Flags: ' . $flags . PHP_EOL;

// Non-blocking-Modus hinzufügen
$result = dio_fcntl($fd, F_SETFL, $flags | O_NONBLOCK);
if ($result === -1) {
    echo 'Fehler beim Setzen der Flags.' . PHP_EOL;
} else {
    echo 'Non-blocking-Modus erfolgreich aktiviert.' . PHP_EOL;
}

dio_close($fd);
Aktuelle Flags: 2 Non-blocking-Modus erfolgreich aktiviert.

Exklusive Schreibsperre mit F_SETLK setzen

<?php
$fd = dio_open('/tmp/locked_resource.dat', O_RDWR | O_CREAT, 0644);

if ($fd === false) {
    die('Konnte Dateideskriptor nicht öffnen.');
}

// Exklusive Schreibsperre für die gesamte Datei anfordern
$lockArg = [
    'type'   => F_WRLCK,  // Schreibsperre
    'whence' => SEEK_SET,
    'start'  => 0,
    'length' => 0,        // 0 = bis zum Dateiende
];

$result = dio_fcntl($fd, F_SETLK, $lockArg);

if ($result === -1) {
    echo 'Sperre konnte nicht gesetzt werden (bereits gesperrt?).' . PHP_EOL;
} else {
    echo 'Schreibsperre erfolgreich gesetzt.' . PHP_EOL;

    // Kritischen Schreibvorgang durchführen
    dio_write($fd, 'Exklusiver Inhalt' . PHP_EOL);

    // Sperre wieder freigeben
    $unlockArg = [
        'type'   => F_UNLCK,
        'whence' => SEEK_SET,
        'start'  => 0,
        'length' => 0,
    ];
    dio_fcntl($fd, F_SETLK, $unlockArg);
    echo 'Sperre freigegeben.' . PHP_EOL;
}

dio_close($fd);
Schreibsperre erfolgreich gesetzt. Sperre freigegeben.

// Wichtig · Fallstricke

Plattformabhängigkeit: dio_fcntl ist ausschließlich auf POSIX-kompatiblen Systemen (Linux, macOS, BSD) verfügbar. Unter Windows steht die Funktion nicht zur Verfügung.

Erweiterung erforderlich: Die dio-Erweiterung ist nicht Bestandteil der PHP-Standardinstallation. Sie muss entweder beim Kompilieren von PHP mit --enable-dio aktiviert oder über PECL installiert werden (pecl install dio).

Sperren sind Advisory Locks: POSIX-Dateisperren via fcntl sind beratende Sperren (Advisory Locks) und werden nur dann respektiert, wenn alle beteiligten Prozesse ebenfalls fcntl-Sperren verwenden. Prozesse, die die Datei ohne Sperrprüfung öffnen, können trotzdem darauf zugreifen.

Vererbung: Bei F_SETLKW blockiert der aufrufende Prozess, bis die Sperre verfügbar ist. Dies kann bei Deadlock-Situationen zu einem dauerhaft blockierten Prozess führen — daher sollte ein Timeout-Mechanismus über Signale (SIGALRM) erwogen werden.