Dateideskriptor - File descriptor

In Unix- und Unix-ähnlichen Computerbetriebssystemen ist ein Dateideskriptor ( FD , seltener fildes ) ein eindeutiger Bezeichner ( Handle ) für eine Datei oder eine andere Eingabe-/Ausgabe- Ressource , wie zB eine Pipe oder ein Netzwerk-Socket .

Dateideskriptoren haben typischerweise nicht negative ganzzahlige Werte, wobei negative Werte reserviert sind, um "kein Wert" oder Fehlerbedingungen anzuzeigen.

Dateideskriptoren sind ein Teil der POSIX- API . Jeder Unix- Prozess (außer vielleicht Daemons ) sollte drei Standard-POSIX-Dateideskriptoren haben, die den drei Standardströmen entsprechen :

Integer Wert Name < unistd.h > symbolische Konstante < stdio.h > Dateistream
0 Standardeingang STDIN_FILENO stdin
1 Standardausgabe STDOUT_FILENO stdout
2 Standart Fehler STDERR_FILENO stderr

Überblick

Dateideskriptoren für einen einzelnen Prozess, Dateitabelle und Inode- Tabelle. Beachten Sie, dass mehrere Dateideskriptoren auf denselben Dateitabelleneintrag verweisen können (z. B. als Ergebnis des Systemaufrufs dup und dass mehrere Dateitabelleneinträge wiederum auf denselben Inode verweisen können (wenn dieser mehrmals geöffnet wurde; die Tabelle ist noch vereinfacht, da er Inodes nach Dateinamen darstellt, obwohl ein Inode mehrere Namen haben kann. ) Der Dateideskriptor 3 verweist auf nichts in der Dateitabelle, was bedeutet, dass er geschlossen wurde.

In der traditionellen Implementierung von Unix indexieren Dateideskriptoren in einen Pro-Prozess vom Kernel verwaltete Dateideskriptortabelle , die wiederum in eine systemweite Tabelle der von allen Prozessen geöffneten Dateien indiziert, genannt dieDateitabelle . Diese Tabelle zeichnet denModus auf,mit dem die Datei (oder eine andere Ressource) geöffnet wurde: zum Lesen, Schreiben, Anhängen und möglicherweise anderen Modi. Es indiziert auch in eine dritte Tabelle, die alsInode-Tabellebezeichnet wird und die die eigentlichen zugrunde liegenden Dateien beschreibt. Um eine Eingabe oder Ausgabe durchzuführen, übergibt der Prozess den Dateideskriptor über einenSystemaufrufan den Kernel, und der Kernel greift im Namen des Prozesses auf die Datei zu. Der Prozess hat keinen direkten Zugriff auf die Datei- oder Inode-Tabellen.

Unter Linux kann auf die in einem Prozess geöffneten Dateideskriptoren unter dem Pfad zugegriffen werden /proc/PID/fd/, wobei PID die Prozesskennung ist .

In Unix-ähnlichen Systemen können sich Dateideskriptoren auf jeden Unix-Dateityp beziehen, der in einem Dateisystem genannt wird. Dazu gehören neben regulären Dateien auch Verzeichnisse , Block- und Zeichengeräte (auch "Spezialdateien" genannt), Unix-Domain-Sockets und Named Pipes . Dateideskriptoren können auch auf andere Objekte verweisen, die normalerweise nicht im Dateisystem vorhanden sind, wie zum Beispiel anonyme Pipes und Netzwerk-Sockets .

Die FILE-Datenstruktur in der C-Standard-I/O-Bibliothek enthält normalerweise einen Low-Level-Dateideskriptor für das fragliche Objekt auf Unix-ähnlichen Systemen. Die gesamte Datenstruktur bietet zusätzliche Abstraktion und wird stattdessen als Datei- Handle bezeichnet .

Operationen auf Dateideskriptoren

Das Folgende listet typische Operationen auf Dateideskriptoren auf modernen Unix-ähnlichen Systemen auf. Die meisten dieser Funktionen werden im <unistd.h>Header deklariert , einige jedoch <fcntl.h>stattdessen im Header.

Dateideskriptoren erstellen

  • öffnen ()
  • creat()
  • Steckdose()
  • annehmen()
  • Steckdosenpaar()
  • Rohr()
  • epoll_create() (Linux)
  • signalfd() (Linux)
  • eventfd() (Linux)
  • timerfd_create() (Linux)
  • memfd_create() (Linux)
  • userfaultfd() (Linux)
  • fanotify_init() (Linux)
  • inotify_init() (Linux)
  • clone() (mit Flag CLONE_PIDFD, Linux)
  • pidfd_open() (Linux)
  • open_by_handle_at() (Linux)

Ableiten von Dateideskriptoren

  • dirfd()
  • Dateinr()

Operationen an einem einzelnen Dateideskriptor

  • lesen (), schreiben ()
  • readv() , writev()
  • pread() , pwrite()
  • recv() , send()
  • recvfrom() , sendto()
  • recvmsg() , sendmsg() (wird auch zum Senden von FDs an andere Prozesse über einen Unix-Domain-Socket verwendet)
  • recvmmsg() , sendmmsg()
  • lseek() , llseek()
  • fstat()
  • fstatvfs()
  • fchmod()
  • fchown()
  • ftruncate()
  • fsync()
  • fdatasync()
  • fdopendir()
  • fgetxattr() , fsetxattr() (Linux)
  • flistxattr() , fremovexattr() (Linux)
  • statx (Linux)
  • setns (Linux)
  • vmsplice() (Linux)
  • pidfd_send_signal() (Linux)
  • waitid() (mit P_PIDFD-ID-Typ, Linux)
  • fdopen() (stdio-Funktion: konvertiert den Dateideskriptor in DATEI*)
  • dprintf() (stdio-Funktion: druckt in den Dateideskriptor)

Operationen an mehreren Dateideskriptoren

  • select() , pselect()
  • poll() , poll()
  • epoll_wait() , epoll_pwait() , epoll_pwait2() (Linux, benötigt einen einzelnen epoll-Dateideskriptor, um auf viele andere Dateideskriptoren zu warten)
  • epoll_ctl() (für Linux)
  • kqueue() (für BSD-basierte Systeme).
  • Datei senden()
  • splice() , tee() (für Linux)
  • copy_file_range() (für Linux)
  • close_range() (für Linux)

Operationen an der Dateideskriptortabelle

Die Funktion fcntl() wird verwendet, um verschiedene Operationen an einem Dateideskriptor auszuführen, abhängig vom übergebenen Befehlsargument. Es gibt Befehle zum Abrufen und Setzen von Attributen, die einem Dateideskriptor zugeordnet sind, einschließlich F_GETFD, F_SETFD, F_GETFL und F_SETFL .

  • nah dran()
  • closefrom() (nur BSD und Solaris; löscht alle Dateideskriptoren größer oder gleich der angegebenen Zahl)
  • dup() (dupliziert einen vorhandenen Dateideskriptor, der garantiert die niedrigste Anzahl verfügbarer Dateideskriptoren ist)
  • dup2() , dup3() (Schließe bei Bedarf fd1 und lasse den Dateideskriptor fd1 auf die geöffnete Datei von fd2 zeigen)
  • fcntl (F_DUPFD)

Vorgänge, die den Prozessstatus ändern

  • fchdir() (setzt das aktuelle Arbeitsverzeichnis des Prozesses basierend auf einem Verzeichnisdateideskriptor)
  • mmap () (bildet Bereiche einer Datei in den Adressraum des Prozesses ab)

Dateisperre

  • Herde()
  • fcntl() (F_GETLK, F_SETLK und F_SETLKW)
  • lockf()

Steckdosen

  • verbinden()
  • binden()
  • hören()
  • accept() (erstellt einen neuen Dateideskriptor für eine eingehende Verbindung)
  • Getsockname()
  • getpeername()
  • getockopt()
  • Setsockopt()
  • shutdown() (schaltet eine oder beide Hälften einer Vollduplex-Verbindung herunter)

Sonstig

  • ioctl() (eine große Sammlung verschiedener Operationen für einen einzelnen Dateideskriptor, die oft mit einem Gerät verbunden sind)

Anstehende Operationen

Eine Reihe neuer Operationen auf Dateideskriptoren wurde vielen modernen Unix-ähnlichen Systemen sowie zahlreichen C-Bibliotheken hinzugefügt, die in einer zukünftigen Version von POSIX standardisiert werden sollen . Die atNachsilbe bedeutet , dass die Funktion ein zusätzliches erstes Argument nimmt einen Dateideskriptor , aus dem Zuführen relative Pfade werden aufgelöst, fehlen die Formen die atSuffix somit immer eine äquivalente Dateideskriptor entsprechend das Strom zum Passieren Arbeitsverzeichnis . Der Zweck dieser neuen Operationen besteht darin, eine bestimmte Klasse von TOCTOU- Angriffen abzuwehren.

  • openat()
  • faccess ()
  • fchmodat()
  • fchownat()
  • fstat()
  • futimesat()
  • linkat()
  • mkdirat()
  • mknodate()
  • readlinkat()
  • umbenennen()
  • symbol ()
  • unlinkat()
  • mkfifoat()
  • fdopendir()

Dateideskriptoren als Fähigkeiten

Unix-Dateideskriptoren verhalten sich in vielerlei Hinsicht als Fähigkeiten . Sie können mit dem Systemaufruf zwischen Prozessen über Unix-Domänen-Sockets weitergegeben werden sendmsg(). Beachten Sie jedoch, dass tatsächlich ein Verweis auf eine "offene Dateibeschreibung" mit veränderlichem Status (der Datei-Offset und die Dateistatus- und Zugriffsflags) übergeben wird. Dies erschwert die sichere Verwendung von Dateideskriptoren als Fähigkeiten, denn wenn Programme gemeinsam auf dieselbe offene Dateibeschreibung zugreifen, können sie sich gegenseitig bei deren Verwendung stören, indem sie beispielsweise ihren Offset ändern oder ob sie blockieren oder nicht blockieren. In Betriebssystemen, die speziell als Fähigkeitssysteme konzipiert sind, gibt es sehr selten einen veränderlichen Zustand, der einer Fähigkeit selbst zugeordnet ist.

Die Dateideskriptortabelle eines Unix-Prozesses ist ein Beispiel für eine C-Liste .

Siehe auch

Verweise