Your Browser is not longer supported

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

{{viewport.spaceProperty.prod}}

Interaktion von Dateideskriptoren und Datenströmen

&pagelevel(4)&pagelevel

Auf eine Dateibeschreibung kann über einen Dateideskriptor zugegriffen werden, der durch open() oder pipe() erzeugt worden ist, oder über einen Datenstrom, der durch fopen() oder popen() erzeugt worden ist. Sowohl ein Dateideskriptor als auch ein Datenstrom wird ein Verweis auf die Dateibeschreibung genannt; auf eine Dateibeschreibung können mehrere Verweise zeigen.

Verweise können durch konkrete Benutzeraktionen erzeugt oder gelöscht werden, ohne die zu Grunde liegende Dateibeschreibung zu beeinflussen. Funktionen, die solche Verweise erzeugen, sind z.B. fcntl(), dup(), fdopen(), fileno() und fork(). Diese Verweise können zumindest mit den Funktionen fclose(), close() und den exec-Funktionen wieder gelöscht werden.

Wird ein Dateideskriptor niemals in einer Operation verwendet, welche die Dateiposition beeinflusst (d.h. read(), write() oder lseek()), so gilt dieser Dateideskriptor nicht als Verweis. Er kann aber zu einem solchen werden, z.B. als Ergebnis von fdopen(), dup() oder fork(). Ein Dateideskriptor, der einem Datenstrom zu Grunde liegt, ist niemals eine solche Ausnahme, gleichgültig ob er durch fopen() oder fdopen() erzeugt wurde, solange er nicht direkt von der Anwendung benutzt wird, um die Dateiposition zu beeinflussen. read() und write() beeinflussen die Dateiposition implizit; lseek() beeinflusst sie explizit.

Das Ergebnis von Funktionsaufrufen, die nur mit einem Verweis arbeiten (dem aktiven Verweis), kann im Nachschlageteil nachgelesen werden. Wenn jedoch zwei oder mehr Verweise benutzt werden und einer davon ein Datenstrom ist, werden deren Aktionen so koordiniert, wie dies im folgenden Abschnitt „Aktionen“ beschrieben wird.

Ein Verweis, der ein Datenstrom ist, gilt dann als geschlossen, wenn entweder die Funktion fclose() oder die Funktion freopen() für diesen ausgeführt wird (das Ergebnis von freopen() ist dann ein neuer Datenstrom, der kein Verweis auf dieselbe Dateibeschreibung sein kann, auf die sein vorheriger Wert verwiesen hat), oder wenn der Prozess, zu dem dieser Datenstrom gehört, mit exit() oder abort() beendet wird. Ein Dateideskriptor wird durch close(), _exit() oder eine der exec-Funktionen mit für diesen Dateideskriptor gesetztem FD_CLOEXEC-Bit geschlossen.

Damit ein Verweis zum aktiven Verweis wird, müssen zwischen der letzten Verwendung des ersten, zurzeit aktiven Verweises, und der ersten Verwendung des zweiten, zukünftig aktiven Verweises die unten beschriebenen Aktionen erfolgen. Dadurch wird der zweite Verweis zum aktiven Verweis. Alle die Dateiposition für den ersten Verweis beeinflussenden Aktivitäten der Anwendung müssen solange unterbunden werden, bis dieser wieder der aktive Verweis ist. Für eine Funktion zur Bearbeitung eines Datenstroms, die eine zu Grunde deliegende Funktion aufruft, die ihrerseits die Position in der Datei verändert, wird angenommen, dass die aufrufende Funktion zur Bearbeitung des Datenstroms selbst die Dateiposition verändert. Die jeweils zu Grunde liegenden Funktionen werden unten beschrieben.

Die Verweise müssen nicht im selben Prozess vorhanden sein, damit diese Regeln Anwendung finden.

Aktionen

Wenn nach der Ausführung der jeweiligen Aktionen der Verweis noch offen ist, kann ihn die Anwendung schließen.

  • Wenn eine der folgenden Bedingungen erfüllt ist, ist für den ersten Verweis keine Aktion notwendig:

    • Der Verweis ist ein Dateideskriptor oder ein ungepufferter Datenstrom.

    • Die einzige weitere auszuführende Aktion für einen Verweis ist das Schließen.

    • Der Verweis ist ein zeilengepufferter Datenstrom und die letzte Aktion hat denselben Effekt auf die zugehörige Datei wie fputs().

    • Der Verweis ist ein zum Lesen geöffneter Datenstrom und feof() liefert TRUE.

  • Wenn keine der oben aufgelisteten Bedingungen zutrifft, muss in folgenden Fällen fflush() ausgeführt oder der Datenstrom geschlossen werden:

    • Wenn es sich um einen zum Schreiben oder Anfügen geöffneten Datenstrom handelt, der nicht gleichzeitig zum Lesen geöffnet ist.

    • Wenn der Datenstrom auf eine Art geöffnet ist, die das Lesen gestattet, und wenn die zu Grunde liegende Dateibeschreibung auf ein Gerät verweist, das positionieren kann.

  • In allen anderen Fällen ist das Ergebnis undefiniert.

Für den zweiten Verweis gilt Folgendes:

Wenn ein vorher aktiver Verweis von einer Funktion verwendet wurde, welche die Dateiposition ausdrücklich veränderte, außer wie oben für den ersten Verweis benötigt, dann muss die Anwendung, je nach Art des Verweises, eine der Funktionen lseek() oder fseek() ausführen, um an die entsprechende Position zu positionieren.

Wenn der aktive Verweis aufhört, zugreifbar zu sein, bevor die Anforderungen für den ersten Verweis erfüllt sind, dann geht die Dateibeschreibung in einen undefinierten Zustand über. Dies kann dann der Fall sein, wenn eine Funktion fork() oder exit() ausgeführt wird.

Die exec-Funktionen sorgen dafür, dass auf alle Datenströme, die zum Zeitpunkt ihres Aufrufs offen sind, nicht mehr zugegriffen werden kann, gleichgültig, welche Datenströme oder Dateideskriptoren für das Speicherabbild des neuen Prozesses zur Verfügung stehen.

Die C-Laufzeitbibiliothek stellt sicher, dass eine Anwendung, auch wenn sie aus mehreren Prozessen besteht, stets korrekte Ergebnisse liefert, d.h. dass beim Schreiben keine Daten verlorengehen oder doppelt geschrieben werden, dass alle Daten in der richtigen Reihenfolge geschrieben werden (außer bei einer entsprechenden Änderung durch das Positionieren) und dass beim sequenziellen Lesen alle Daten gefunden werden, sofern nach den oben angeführten Regeln vorgegangen wird. Dabei spielt es keine Rolle, in welcher Reihenfolge die Verweise verwendet werden. Werden die oben aufgeführten Regeln nicht befolgt, dann ist das Ergebnis undefiniert.

Siehe auch Handbuch „POSIX-Grundlagen“ [1].