Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

lockf, lockf64 - Dateiabschnitt sperren

&pagelevel(4)&pagelevel

Definition

#include <unistd.h>

int lockf(int fildes, int function, off_t size);
int lockf64(int fildes, int function, off64_t size);

Beschreibung

Mit lockf() können Dateiabschnitte gesperrt werden; dabei hängen empfohlene oder obligatorische Schreibsperren jeweils von den Modusbits der Datei ab (siehe chmod()). Sperraufrufe von anderen Prozessen, die versuchen, einen bereits gesperrten Dateiabschnitt zu sperren, führen entweder zur Rückgabe eines Fehlerwerts oder pausieren solange, bis das Betriebsmittel freigegeben wird. Alle Sperren für einen Prozess werden aufgehoben, wenn der Prozess beendet wird. lockf() kann auf normale Dateien angewendet werden.

fildes ist ein offener Dateideskriptor. Der Dateideskriptor muss die O_WRONLY- oder O_RD-WR-Erlaubnis haben, damit die Sperre mit diesem Funktionsaufruf eingerichtet werden kann.

function ist ein Steuerwert, der die zu treffenden Maßnahmen angibt. Die zulässigen Werte für function sind, wie folgt, in unistd.h definiert:

#define    F_ULOCK   0   /* gesperrten Abschnitt freigeben */
#define    F_LOCK    1   /* Abschnitt exklusiv sperren */
#define    F_TLOCK   2   /* Abschnitt testen und exklusiv sperren */
#define    F_TEST    3   /* Abschnitt auf Sperren anderer Prozesse testen */

Alle anderen Werte von function sind für zukünftige Erweiterungen reserviert und führen zu einer Fehlermeldung, wenn sie nicht implementiert sind.

F_TEST wird verwendet, um festzustellen, ob in einem Abschnitt eine Sperre eines anderen Prozesses existiert. F_LOCK und F_TLOCK sperren jeweils einen Abschnitt einer Datei, wenn dieser Abschnitt verfügbar ist. F_ULOCK hebt die Sperren eines Dateiabschnitts auf.

size ist die Anzahl zusammenhängender Bytes, die gesperrt oder entsperrt werden sollen. Das zu sperrende oder entsperrende Betriebsmittel beginnt am aktuellen Offset in der Datei und erstreckt sich vorwärts für ein positives size und rückwärts für ein negatives size (die vorhergehenden Bytes bis ausschließlich des aktuellen Offsets). Wenn size null ist, wird der Abschnitt vom aktuellen Offset bis zum größten Datei-Offset gesperrt, d.h. vom aktuellen Offset bis zum gegenwärtigen oder bis zu jedem zukünftigen Dateiende. Ein Bereich braucht nicht einer Datei zugewiesen sein, damit er gesperrt werden kann, weil diese Sperren auch über das Ende der Datei hinausgehen können.

Die mit F_LOCK oder F_TLOCK gesperrten Abschnitte können einen vorher von demselben Prozess gesperrten Abschnitt ganz oder teilweise enthalten bzw. in diesem Abschnitt enthalten sein. Wenn diese Situation in diesem oder in benachbarten Abschnitten eintritt, werden die Abschnitte zu einem Abschnitt zusammengefasst. Wenn mit der Anforderung ein neues Element zur Tabelle der aktiven Sperren hinzugefügt werden muss und diese Tabelle bereits voll ist, erfolgt eine Fehlermeldung, und der neue Abschnitt wird nicht gesperrt.

Die Anforderungen von F_LOCK und F_TLOCK unterscheiden sich nur in der Maßnahme, die getroffen wird, wenn das Betriebsmittel nicht zur Verfügung steht. F_LOCK bewirkt, dass der aufrufende Prozess pausiert, bis das Betriebsmittel zur Verfügung steht. F_TLOCK bewirkt, dass die Funktion -1 zurückgibt und errno auf den Fehler EACCES setzt, wenn der Abschnitt bereits von einem anderen Prozess gesperrt ist.

Gesperrte Abschnitte werden durch den ersten close-Aufruf freigegeben, den der Prozess, der die Sperre gesetzt hat, für einen Dateideskriptor der zugehörigen Datei durchführt.

F_ULOCK-Anforderungen können einen oder mehrere gesperrte, vom Prozess gesteuerte Abschnitte teilweise oder ganz freisetzen. Gesperrte Abschnitte werden ab dem Punkt des Offsets entsperrt, bis size Bytes entsperrt worden sind oder bis zum Dateiende, wenn size den Wert (off_t)0 hat. Wenn die Abschnitte nicht ganz entsperrt werden, bleiben die übrigen Abschnitte weiterhin vom Prozess gesperrt. Die Freigabe des mittleren Abschnitts eines gesperrten Abschnitts erfordert einen zusätzlichen Eintrag in der Tabelle der aktiven Sperren. Wenn diese Tabelle voll ist, wird errno auf ENOLK gesetzt und der angeforderte Abschnitt nicht freigegeben.

Die Möglichkeit eines Deadlocks entsteht, wenn ein Prozess, der ein gesperrtes Betriebsmittel kontrolliert, durch Anforderung des gesperrten Betriebsmittels eines anderen Prozesses zum Pausieren veranlasst wird. Daher wird bei Aufruf von lockf() oder fcntl() zunächst auf mögliche Deadlocks geprüft, bevor der Prozess bis zur Freigabe eines noch gesperrten Betriebsmittels angehalten wird. Wenn das Warten auf ein gesperrtes Betriebsmittel einen Deadlock verursachen würde, schlägt der Aufruf fehl und errno wird auf EDEADLK gesetzt.

Das gleichzeitige Sperren mit lockf() und fcntl() führt zu undefinierten Wechselwirkungen.

Das Warten auf ein Betriebsmittel wird mit einem beliebigen Signal unterbrochen. Der Systemaufruf alarm() kann für die Bereitstellung einer Zeitsperre bei Anwendungen verwendet werden, die eine derartige Einrichtung benötigen.

Es besteht kein funktionaler Unterschied zwischen lock() und lock64(), außer dass lockf64() die Größe des zu sperrenden Bereichs in einem Offset-Typ off64_t angibt.

Werden Threads verwendet, so wirkt sich die Funktion auf den Prozess oder auf einen Thread wie folgt aus:

Sperren eines Dateiabschnitts; Sperraufrufe von anderen Threads, die versuchen, einen bereits gesperrten Dateiabschnitt zu sperren, führen entweder zur Rückgabe eines Fehlerwerts oder blockieren den aufrufenden Thread solange, bis der Abschnitt freigegeben wird. Alle Sperren für einen Prozess werden aufgehoben, wenn der Prozess beendet wird.

Returnwert

0

bei Erfolg.

 

-1

bei Fehler. errno wird gesetzt, um den Fehler anzuzeigen. Bestehende Sperren werden nicht geändert.

Fehler

lockf() und lockf64() schlagen fehl, wenn gilt:

 

EBADF

fildes ist kein gültiger, offener Dateideskriptor, oder function ist F_LOCK oder  F_TLOCK und die über fildes angesprochene Datei ist nicht zum Schreiben geöffnet.

 

EACCES

function ist F_TLOCK oder F_TEST, und der Abschnitt ist bereits von einem anderen Prozess gesperrt.

 

EDEADLK

function ist F_LOCK und ein Deadlock würde auftreten.

 

EINTR

Während der Ausführung der Funktion wurde ein Signal abgefangen.

 

EAGAIN

function ist F_LOCK oder F_TLOCK und die Datei wurde mit mmap() erzeugt.

 

ENOLCK

function function ist F_LOCK, F_TLOCK oder F_ULOCK, und der Speicherplatz reicht für weitere Einträge in der Sperrtabelle nicht mehr aus.

 

EINVAL

fildes zeigt auf einen Dateityp, der in dieser Implementierung nicht gesperrt werden kann oder
der Inhalt von function ist ungültig; oder
die Summe von size plus dem aktuellen Datei-Offset ist kleiner 0 oder größer als der höchste zulässige Datei-Offset.

 

ECOMM

fildes ist auf einem fernen Rechner, und die Verbindung zu diesem Rechner ist nicht mehr aktiv.

 

EOVERFLOW

Der Offset des ersten Byte oder, wenn die Größe ungleich 0 ist, des letzten Byte im angeforderten Abschnitt, kann in einem Objekt des Typs off_t nicht korrekt dargestellt werden.

Hinweise

Unerwartete Ergebnisse können in Prozessen auftreten, die im Adressraum des Benutzers puffern. Der Prozess kann später Daten lesen oder schreiben, die gesperrt sind bzw. waren. Das Standard-E/A-Paket ist die häufigste Ursache für unerwartete Pufferungen. Es sollten statt dessen einfachere Funktionen verwendet werden, die ungepuffert arbeiten, wie z.B open().

Da die Variable errno in Zukunft auf EAGAIN und nicht auf EACCES gesetzt wird, wenn ein Dateiabschnitt bereits von einem anderen Prozess gesperrt ist, müssen portable Anwenderprogramme beide Werte erwarten und prüfen.

Die Funktion alarm() kann verwendet werden, um einen eventuellen Timeout zu überwachen.

Siehe auch

alarm(), chmod(), close(), creat(), fcntl() ,mmap(), open(), read(), write(), unistd.h.