Ich versuche die Verwendung von dup2
und zu verstehen dup
.
Von der Manpage:
DESCRIPTION
dup and dup2 create a copy of the file descriptor oldfd.
After successful return of dup or dup2, the old and new descriptors may
be used interchangeably. They share locks, file position pointers and
flags; for example, if the file position is modified by using lseek on
one of the descriptors, the position is also changed for the other.
The two descriptors do not share the close-on-exec flag, however.
dup uses the lowest-numbered unused descriptor for the new descriptor.
dup2 makes newfd be the copy of oldfd, closing newfd first if necessary.
RETURN VALUE
dup and dup2 return the new descriptor, or -1 if an error occurred
(in which case, errno is set appropriately).
Warum sollte ich diesen Systemaufruf brauchen? Was nützt es, den Dateideskriptor zu duplizieren?
Wenn ich den Dateideskriptor habe, warum sollte ich eine Kopie davon erstellen wollen?
Ich würde mich freuen, wenn Sie mir erklären und ein Beispiel geben könnten, wo dup2
/ dup
benötigt wird.
Vielen Dank
dup
oder implementierendup2
? Sie müssen anrufenpipe(2)
und dann einen der Dateideskriptoren habendup
STDIN_FILENO
Antworten:
Der dup-Systemaufruf dupliziert einen vorhandenen Dateideskriptor und gibt einen neuen zurück, der auf dasselbe zugrunde liegende E / A-Objekt verweist.
Mit Dup können Shells folgende Befehle implementieren:
Das 2> & 1 weist die Shell an, dem Befehl einen Dateideskriptor 2 zu geben, der ein Duplikat von Deskriptor 1 ist (dh stderr & stdout zeigen auf denselben fd).
Jetzt wird die Fehlermeldung zum Aufrufen von ls für eine nicht vorhandene Datei und die korrekte Ausgabe von ls für eine vorhandene Datei in der Datei tmp1 angezeigt .
Der folgende Beispielcode führt das Programm wc mit Standardeingabe aus, die an das Leseende einer Pipe angeschlossen ist.
Das Kind kopiert das Leseende auf den Dateideskriptor 0, schließt die Datei de scriptors in p und führt wc aus. Wenn wc von seiner Standardeingabe liest, liest es von der Pipe.
Auf diese Weise werden Pipes mit dup implementiert. Nun, bei einer Verwendung von dup verwenden Sie Pipe, um etwas anderes zu erstellen. Das ist das Schöne an Systemaufrufen. Sie erstellen eine Sache nach der anderen mit Tools, die bereits vorhanden sind. Diese Tools wurden von innen erstellt etwas anderes so weiter .. Am Ende sind Systemaufrufe die grundlegendsten Werkzeuge, die Sie im Kernel erhalten
Prost :)
quelle
dup
also hilfreich für den Anrufer und nicht für dasls
Programm selbst? Gibt es einen Vorteil,dup
wenn Sie ein Programm wie ls selbst verwendet haben, wenn Sie bereits Zugriff auf die Datei haben? Hier werden zum Beispiells
Fehler geschrieben, auf2
die fest codiert ist, sodass ich als Verbraucher von die Möglichkeit habe, sie zu überschreibenls
. Ich denke, das ist ein subtiler Punkt, nein?dup(p[STDIN])
, werfen dann aber das Ergebnis weg. Wolltest du verwendendup2(p[STDIN], 0)
?dup
gibt den "Deskriptor mit der niedrigsten Nummer zurück, der derzeit vom Prozess nicht verwendet wird". Da fd 0 gerade geschlossen wurde,dup
sollte 0 zurückgegeben werden. Esdup2
wird explizit angegeben, welches fd verwendet werden soll, anstatt nur das niedrigste freie fd zu verwenden, daher würde ich das vorziehen.exec*
von einem Multithread-Prozess aus anrufen . Aber ich bin kein Threading-Experte :)Ein weiterer Grund für das Duplizieren eines Dateideskriptors ist die Verwendung mit
fdopen
.fclose
Schließt den Dateideskriptor, an den übergebenfdopen
wurde. Wenn Sie also nicht möchten, dass der ursprüngliche Dateideskriptor geschlossen wird, müssen Sie ihndup
zuerst duplizieren .quelle
fdopen()
Anscheinend wird kein Dateideskriptor dupliziert, sondern nur ein Puffer im Benutzerbereich erstellt.dup
das fd möglicherweise möchten, bevor Sie es übergeben,fdopen
dafclose
es geschlossen wird.FILE
Handle für den Zugriff auf eine bereits vorhandene geöffnete Datei über stdio-Schnittstellen zuweisen , müssen Sie aufrufenfclose
,FILE
um die Zuordnung dieses Handles aufzuheben . Wenn Sie die zugrunde liegende geöffnete Datei weiterhin verwenden möchten oder wenn Ihre Softwarearchitektur so ist, dass der ursprüngliche "Eigentümer" -Code für den Dateideskriptor dies tutclose
, ist die Tatsache, dassfclose
auch der zugrunde liegende Dateideskriptor, den Sie übergeben haben, geschlossenfdopen
wird, ein Problem. Sie können dieses Problem vermeiden, indem Siedup
einen neuen Dateideskriptor für dieselbe geöffnete Datei erstellen, an die übergeben werden sollfdopen
, damitfclose
die ursprüngliche Datei nicht geschlossen wird.FILE
, anstatt sie zu kopieren . Das sollten Benutzer beachten. Verbraucher, diefd
zusätzlich zumFILE
Objekt ein verwendbares Handle behalten müssen, müssen das duplizierenfd
. Das ist alles.FILE
sobald Sie das Eigentum darauf verlagern.dup wird verwendet, um die Ausgabe eines Prozesses umleiten zu können.
Wenn Sie beispielsweise die Ausgabe eines Prozesses speichern möchten, duplizieren Sie die Ausgabe (fd = 1), leiten die duplizierte fd in eine Datei um, geben den Prozess auf und führen ihn erneut aus. Wenn der Prozess abgeschlossen ist, leiten Sie die Ausgabe erneut um fd zur Ausgabe gespeichert.
quelle
Einige Punkte im Zusammenhang mit dup / dup2 können bitte notiert werden
dup / dup2 - Technisch gesehen besteht der Zweck darin, einen Dateitabelleneintrag innerhalb eines einzelnen Prozesses durch verschiedene Handles gemeinsam zu nutzen. (Wenn wir forken, wird der Deskriptor im untergeordneten Prozess standardmäßig dupliziert und der Dateitabelleneintrag wird ebenfalls freigegeben.)
Das bedeutet, dass wir mit der Funktion dup / dup2 mehr als einen Dateideskriptor mit möglicherweise unterschiedlichen Attributen für einen einzelnen Eintrag in einer offenen Dateitabelle haben können.
(Obwohl derzeit anscheinend nur das FD_CLOEXEC-Flag das einzige Attribut für einen Dateideskriptor ist).
http://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html
Unterschiede sind (für den letzten) - Abgesehen von einigen Fehlern zwischen dup2 und fcntl close, gefolgt von fcntl, können sich die Rennbedingungen erhöhen, da zwei Funktionsaufrufe beteiligt sind.
Details können unter http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html überprüft werden
Ein Anwendungsbeispiel -
Ein interessantes Beispiel für die Implementierung der Jobsteuerung in einer Shell, in der die Verwendung von dup / dup2 unter dem folgenden Link zu sehen ist
http://www.gnu.org/software/libc/manual/html_node/Launching-Jobs.html#Launching-Jobs
quelle