2017-12-18 9 views
1

Ist es möglich, einen Dateideskriptor zu klonen? Ich weiß über dup, aber ich hätte gerne einen Dateideskriptor, der einen separaten Status (Position) hat, als ob ich die gleiche Datei wieder geöffnet hätte, mit den gleichen Flags (das Problem mit der Wiedereröffnung ist, dass a) ich habe um den Dateipfad zu speichern, der momentan nicht in meinem Code benötigt wird und b) Wenn die Datei gelöscht wurde, kann ich sie nicht erneut öffnen).Ist es möglich, einen Dateideskriptor zu klonen?

Wenn es nicht möglich ist, dann ist meine Idee, dup und pread/pwrite zu verwenden, so verwalte ich Dateiposition selbst. Gibt es irgendwelche Nachteile dieser Idee?

+0

Kloniert 'dup2' einen Dateideskriptor nicht? – jww

+0

@jww Es tut, aber die Deskriptoren sind nicht unterscheidbar. Liest und schreibt mit einem Update auch die Dateiposition für den anderen. – bnaecker

Antwort

1

Ich glaube nicht, dass es eine einzelne Bibliotheksfunktion oder einen Systemaufruf gibt, der unter Linux funktioniert. Aber Sie können folgendes tun:

  1. Verwenden readlink(3) oder realpath(3) auf die Datei /proc/self/fd/<X>, wo <X> ist der Dateideskriptor Sie duplizieren möchten. Dies gibt den vollständigen Pfad zu der fraglichen Datei zurück.
  2. Rufen Sie an, um einen brandneuen Deskriptor für diese Datei zu erhalten.
  3. Verwenden Sie den zweiten Dateideskriptor, den Sie möchten. Seine read(2) s und write(2) s sind unabhängig.

Dies wird Ihre Sorge um Speicherung den Dateipfad herum, nur um es dynamisch bekommen, wenn nötig.

Ich verstehe Ihren zweiten Punkt jedoch nicht, der eine über das Löschen der Datei. Wenn dieser Prozess löscht die Datei, warum sollten Sie einen doppelten Deskriptor dafür erstellen? Unabhängig davon, ob dieser oder ein anderer Prozess die Datei löscht, ist die Datei weiterhin zugänglich, bis der Dateideskriptor selbst geschlossen wird. Die Duplizierung wie oben beschrieben sollte gültig sein, bis alle offenen Deskriptor auf die Datei geschlossen ist. (Obwohl Sie den Link /proc/self/fd/<X> nicht verwenden können, wenn dieser Prozess löscht die Datei und schließt seinen Deskriptor. Sie benötigen eine andere Möglichkeit zur Wiederherstellung des Dateinamens aus dem Dateideskriptor. Aber in diesem Fall die Frage macht keinen Sinn, da Sie sowieso keinen gültigen Deskriptor mehr haben!)

Auch die Erstellung eines zweiten, unabhängigen Dateideskriptors erscheint mir ein wenig komisch. Ich würde wahrscheinlich nur mit lseek(2) + read(2) oder pread(2) gehen. Abgesehen davon, dass ich unterschiedliche Dateipositionen verwalten muss, sehe ich keine besonderen Nachteile.

+0

Danke für die Antwort! Der Grund für den Klon ist, dass ich eine Klasse habe, die ein fd hat (eigentlich ist es komplizierter, aber das ist eine Grundeinstellung), was eine Zip-Datei ist. Und diese Klasse hat eine "open" -Funktion (sie öffnet eine Datei aus der zip), die das 'fd' klont und ein zip-decompressor-Objekt zurückgibt (welches das geklonte' fd' verwendet). Und mehrere (unabhängige) Dateien können von einem Zip geöffnet werden. So funktioniert 'lseek' hier nicht, da ich für jeden Zip-Stream eine separate Position benötige. Ich dachte, dass es einen Systemaufruf gibt, der die Datei für mich wieder öffnet. Aber es scheint, dass es keine gibt. – geza

Verwandte Themen