DUP(2) Linux-Programmierhandbuch DUP(2)

dup, dup2 - dupliziert einen Datei-Deskriptor

ÜBERSICHT

#include <unistd.h>
int dup(int altdd);
int dup2(int altdd, int neudd);
#define _GNU_SOURCE             /* siehe feature_test_macros(7) */
#include <fcntl.h>              /* Definition der O_*-Konstanten */
#include <unistd.h>
int dup3(int altdd, int neudd, int schalter);

Der Systemaufruf dup() reserviert einen neuen Dateideskriptor, der sich auf die gleiche offene Dateideskription wie der Deskriptor altdd bezieht. (Für eine Beschreibung von offenen Dateideskriptionen, siehe open(2).) Die neue Dateideskriptornummer ist garantiert der Dateideskriptor mit der niedrigsten Nummer, die in dem aufrufenden Prozess verfügbar war.

Nach der erfolgreichen Rückkehr können die alten und neuen Datei-Deskriptoren synonym benutzt werden. Da die zwei Dateideskriptoren sich auf die gleichen offenen Dateideskriptionen beziehen, teilen sie sich dadurch Dateiversatz (file offset) und Dateistatusschalter. Falls der Dateiversatz zum Beispiel durch lseek(2) auf einem der Dateideskriptoren geändert wurde, wird der Versatz auch für den anderen Dateideskriptor verändert.

Die beiden Dateideskriptoren teilen sich keine Datei-Deskriptor-Schalter (den Schalter »close-on-exec«). Der Schalter »close-on-exec« (FD_CLOEXEC; siehe fcntl(2)) für das Duplikat ist aus.

Der Systemaufruf dup2() führt dieselben Aufgaben wie dup() durch, verwendet jedoch statt des kleinsten nicht benutzten Dateideskriptors die in neudd angegebene Zahl. Mit anderen Worten, der Dateideskriptor neudd wird angepasst, so dass er sich jetzt auf die gleiche offene Dateideskription wie altdd bezieht.

Falls der Dateideskriptor neudd vorher offen war, wird er vor der erneuten Benutzung geschlossen; das Schließen erfolgt stillschweigend (d.h. es werden mögliche Fehler während des Schließens nicht durch dup2() gemeldet).

Die Schritte zum Schließen und erneuten Verwenden des Dateideskriptors neudd werden atomar (als logische Einheit) durchgeführt. Dies ist wichtig, da der Versuch gleichwertige Funktionalität mittels close(2) und dup()zu implementieren, Gegenstand von Race Conditions sein könnte, bei denen neudd zwischen zwei Schritten erneut benutzt wird. Ein derartiges erneutes Verwenden kann vorkommen, da das Hauptprogramm durch ein Signalverarbeitungsprogramm unterbrochen wird, der einen Dateideskriptor reserviert oder weil ein paralleler Thread einen Dateideskriptor reserviert.

Beachten Sie die folgenden Punkte:

  • Falls altdd kein gültiger Datei-Deskriptor ist, schlägt der Aufruf fehl und neudd wird nicht geschlossen.
  • Falls altdd ein gültiger Datei-Deskriptor ist und neudd den gleichen Wert wie altdd hat, dann tut dup2() nichts und gibt neudd zurück.

dup3() entspricht dup2(), außer dass:

  • Der Aufrufende kann erzwingen, dass der Schalter »close-on-exec« für den neuen Datei-Deskriptor durch Angabe von O_CLOEXEC in schalter gesetzt wird. Lesen Sie die Beschreibung des gleichnamigen Schalters in open(2), um zu erfahren, warum dies nützlich sein könnte.
  • Falls altdd neudd entspricht, schlägt dup3() mit dem Fehler EINVAL fehl.

Bei Erfolg geben diese Systemaufrufe den neuen Dateideskriptor zurück. Im Fehlerfall wird -1 zurückgegeben und errno gesetzt, um den Fehler anzuzeigen.

altdd ist kein Deskriptor für eine geöffnete Datei.
neudd liegt außerhalb des erlaubten Bereichs für Datei-Deskriptoren (siehe die Erläuterung von RLIMIT_NOFILE in getrlimit(2)).
(nur Linux) Dies könnte von dup2() oder dup3() während einer Gleichzeitigkeitsbedingung mit open(2) und dup() zurückgegeben werden.
Der Aufruf von dup2() oder dup3() wurde von einem Signal unterbrochen; lesen Sie signal(7).
(dup3()) schalter enthalten einen ungültigen Wert.
(dup3()) altdd entsprach neudd.
Die Beschränkung der Anzahl offener Datei-Deskriptoren pro Prozess wurde erreicht (siehe die Erläuterung von RLIMIT_NOFILE in getrlimit(2)).

dup3() wurde in Version 2.6.27 zu Linux hinzugefügt; Glibc-Unterstützung ist seit Version 2.9 verfügbar.

dup(), dup2(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

dup3() ist Linux-spezifisch.

Der von dup2 zurückgegebene Fehler unterscheidet sich von dem, der von fcntl(…, F_DUPFD,…) zurückgegeben wird, wenn neudd außerhalb des Bereiches ist. Weiterhin gibt dup2 auf einigen Systemen EINVAL wie F_DUPFD zurück.

Falls neudd geöffnet war, sind alle Fehler verlorengegangen, die in dieser Zeit an close(2) gemeldet worden wären. Falls dies von Bedeutung ist, ist die korrekte Herangehensweise, – sofern das Programm nicht in einem einzigen Thread läuft und keine Dateideskriptoren in Signalverarbeitungsprogrammen reserviert –, neudd vor dem Aufruf von dup2() wegen der oben beschriebenen Race Conditions nicht zu schließen. Stattdessen kann Code wie der folgende verwendet werden:


/* Erhält ein Duplikat von »neudd«, das nachfolgend benutzt

werden kann, um auf Fehler von close() zu prüfen. Ein
EBADF-Fehler bedeutet, dass »neudd« nicht geöffnet war. */ tmpfd = dup(neudd); if (tmpfd == -1 && errno != EBADF) {
/* behandelt unerwartete dup()-Fehler */ } /* »altdd« atomar auf »neudd« duplizieren */ if (dup2(altdd, neudd) == -1) {
/* dup2()-Fehler behandeln */ } /* Nun wird auf close()-Fehler für die Datei, auf die sich
»neudd« ursprünglich bezog, geprüft. */ if (tmpfd != -1) {
if (close(tmpfd) == -1) {
/* close-Fehler behandeln */
} }

close(2), fcntl(2), open(2), pidfd_getfd(2)

Diese Seite ist Teil der Veröffentlichung 5.13 des Projekts Linux-man-pages. Eine Beschreibung des Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG

Die deutsche Übersetzung dieser Handbuchseite wurde von Aldo Valente <aldo@dagobar.rhein.de>, Chris Leick <c.leick@vollbio.de> und Helge Kreutzmann <debian@helgefjell.de> erstellt.

Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.

Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Übersetzer.

22. März 2021 Linux