table of contents
- stretch 1.22-1
- testing 2.12-1
- stretch-backports 2.11-1~bpo9+2
- unstable 2.12-1
OPEN(2) | Linux-Programmierhandbuch | OPEN(2) |
BEZEICHNUNG¶
open, openat, creat - eine Datei öffnen und möglicherweise erzeugenÜBERSICHT¶
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); int openat(int dirfd, const char *pathname, int flags); int openat(int dirfd, const char *pathname, int flags, mode_t mode);
Mit Glibc erforderliche Makros (siehe feature_test_macros(7)):
openat():
- Seit Glibc 2.10:
- _POSIX_C_SOURCE >= 200809L
- Vor Glibc 2.10:
- _ATFILE_SOURCE
BESCHREIBUNG¶
Für einen übergebenen pathname für eine Datei wird open() einen Dateideskriptor, d.h. eine kleine, nicht negative Ganzzahl, für die Verwendung in folgenden Systemaufrufen (read(2), write(2), lseek(2), fcntl(2) usw.) zurückliefern. Der bei einem erfolgreichen Aufruf zurückgelieferte Dateideskriptor wird der niedrigstzahlige, noch nicht für den Prozess offene Dateideskriptor sein.Standardmäßig bleibt der neue Dateideskriptor über ein execve(2) offen (d.h. der in fcntl(2) beschriebene Dateideskriptorschalter FD_CLOEXEC ist anfangs leer). Der weiter unten beschriebene Schalter O_CLOEXEC kann zum Ändern dieser Vorgabe verwandt werden. Der Dateiversatz wird auf den Anfang der Datei gesetzt (siehe lseek(2)).
Ein Aufruf von open() erstellt eine neue offene Dateideskription, einen Entrag in der systemweiten Tabelle von offenen Dateien. Die offene Dateideskription zeichnet den Dateiversatz und die Dateizustandsschalter (siehe unten) auf. Ein Dateideskriptor ist eine Referenz auf eine offene Dateideskription. Diese Referenz ist nicht betroffen, falls pathname im Folgenden entfernt oder so verändert wird, dass er auf eine andere Datei zeigt. Für weitere Details über offene Dateideskriptionen, siehe ANMERKUNGEN.
Das Argument flags muss einen der folgenden Zugriffsmodi enthalten: O_RDONLY, O_WRONLY oder O_RDWR. Diese erbitten, die Datei nur lesbar, nur schreibbar bzw. les-/schreibbar zu öffnen.
Zusätzlich können Null oder mehr Dateierstellungsschalter in flags mit einem bitweisen Oder zusammengebracht werden. Die Dateierstellungsschalter sind O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TMPFILE und O_TRUNC. Die restlichen unten aufgeführten Schalter sind die Dateistatusschalter. Der Unterschied zwischen diesen zwei Gruppen von Schaltern besteht darin, dass Dateistatussschalter abgefragt und (in einigen Fällen) verändert werden können; siehe fcntl(2) für Details.
Die komplette Liste der Dateierstellungs- und Dateistatusschalter ist wie folgt:
- O_APPEND
- Die Datei wird im Anhängemodus geöffnet. Vor jedem write(2) wird der Dateiversatz an das Ende der Datei positioniert, wie mit lseek(2). O_APPEND kann auf NFS-Dateisystemen zu beschädigten Dateien führen, falls mehr als ein Prozess auf einmal Daten an die Datei anhängt. Dies kommt daher, da NFS das Anhängen an Dateien nicht unterstützt und der Client-Kernel dies daher simulieren muss, was nicht ohne einen Wettlauf um Ressourcen passieren kann.
- O_ASYNC
- Aktiviert signalgetriebene E/A: erzeugt ein Signal (standardmäßig SIGIO, dies kann aber mit fcntl(2) geändert werden), wenn Ein- oder Ausgabe auf diesem Dateideskriptor möglich wird. Diese Funktionalität ist nur für Terminals, Pseudoterminals, Sockets und (seit Linux 2.6) Pipes und FIFOs verfügbar. Siehe fcntl(2) für weitere Details. Siehe auch FEHLER unten.
- O_CLOEXEC (seit Linux 2.6.23)
- Aktiviert den Schalter »close-on-exec« für den neuen
Dateideskriptor. Durch Festlegung dieses Schalters wird einem Programm
ermöglicht, zusätzliche
fcntl(2)-F_SETFD-Aktionen, um den Schalter FD_CLOEXEC
zu setzen, zu vermeiden.
Beachten Sie, dass die Verwendung dieses Schalters in einigen Multithread-Programmen notwendig ist, da die Verwendung einer separaten fcntl(2)-F_SETFD-Aktion, um den Schalter FD_CLOEXEC zu setzen, nicht ausreicht, um eine Race-Condition zu vermeiden, bei der ein Thread einen Dateideskriptor öffnet und versucht, dessen close-on-exec-Schalter mittels fcntl(2) zur gleichen Zeit zu setzen, zu der ein anderer Thread einen fork(2) kombiniert mit eine execve(2) durchführt. Abhängig von der Reihenfolge der Ausführung kann der Ressourcenwettlauf dazu führen, dass der von open(2) zurückgelieferte Dateideskriptor ungeplant von dem Programm durchgesickert ist, das von dem Kindprozess mittels fork(2) erzeugt wurde. (Diese Art von Ressourcenwettlauf ist prinzipiell für jeden Systemaufruf möglich, der einen Dateideskriptor erstellt, dessen Schalter close-on-exec gesetzt sein solte, und verschiedene andere Linux-Systemaufrufe stellen ein Äquivalent zu dem Schalter O_CLOEXEC bereit, um mit diesem Problem umzugehen.
- O_CREAT
- Falls die Datei nicht existiert, wird sie erstellt.
Der Eigentümer (Benutzer-ID) der neuen Datei wird auf die effektive Benutzer-ID des Prozesses gesetzt.
Die Gruppen-Eigentümerschaft (Gruppen-ID) der neuen Datei wird entweder auf die effektive Gruppen-ID des Prozesses (System-V-Semantik) oder auf die Gruppen-ID des Elternverzeichnisses (BSD-Semantik) gesetzt. Unter Linux hängt das Verhalten davon ab, ob das Modusbit set-group-ID auf dem Elternverzeichnis gesetzt ist. Falls das Bit gesetzt ist, gilt die BSD-Semantik, andernfalls gilt die System-V-Semantik. Bei einigen Dateisystemen hängt das Verhalten von den in mount(8) beschriebenen Einhängeoptionen bsdgroups und sysvgroups ab.
Das Argument mode legt die Dateimodusbits, die beim Erstellen einer neuen Dateien angewandt werden sollen, fest. Das Argument muss bereitgestellt werden, wenn O_CREAT oder O_TMPFILE in flags festgelegt wird. Falls weder O_CREAT noch O_TMPFILE festgelegt ist, wird mode ignoriert. Der effektive Modus wird durch die umask des Prozesses wie üblich verändert: in der Abwesenheit einer Standard-ACL ist der Modus der erstellten Datei (mode & ~umask). Beachten Sie, dass dieser Modus nur bei zukünftigen Zugriffen auf die neu erstellte Datei gilt; der Aufruf open(), der eine nur-lesbare Datei erstellte, kann sehr wohl einen lese- und schreibbaren Dateideskriptor zurückliefern.
Für mode werden die folgenden symbolischen Konstanten bereitgestellt:
- S_IRWXU
- 00700 Benutzer (Dateieigentümer) hat Lese-, Schreibe- und Ausführrechte
- S_IRUSR
- 00400 Benutzer hat Leserechte
- S_IWUSR
- 00200 Benutzer hat Schreibrechte
- S_IXUSR
- 00100 Benutzer hat Ausführrechte
- S_IRWXG
- 00070 Gruppe hat Lese-, Schreib- und Ausführrechte
- S_IRGRP
- 00040 Gruppe hat Leserechte
- S_IWGRP
- 00020 Gruppe hat Schreibrechte
- S_IXGRP
- 00010 Gruppe hat Ausführrechte
- S_IRWXO
- 00070 andere haben Lese-, Schreib- und Ausführrechte
- S_IROTH
- 00004 andere haben Leserechte
- S_IWOTH
- 00002 andere haben Schreibrechte
- S_IXOTH
- 00001 andere haben Ausführrechte
- Laut POSIX ist der Effekt, wenn andere Bits in mode gesetzt werden, nicht spezifiziert. Unter Linux werden auch die folgenden Bits in mode berücksichtigt:
- O_DIRECT (seit Linux 2.4.10)
- versucht die Zwischenspeichereffekte auf die E/A in und aus dieser Datei
zu minimieren. Im Allgemeinen reduziert das die Leistung, aber in
besonderen Situationen ist das nützlich, beispielsweise wenn
Anwendungen ihre eigene Zwischenspeicherung vornehmen. Datei-E/A erfolgt
direkt aus den Puffern des Benutzerraums. Der Schalter O_DIRECT
versucht, Daten synchron zu übertragen, gibt aber nicht die
Garantien des Schalters O_SYNC, dass Daten und notwendige Metadaten
übetragen wurden. Um synchrone E/A zu garantieren, muss
O_SYNC zusätzlich zu O_DIRECT verwandt werden. Siehe
ANMERKUNGEN für weitere Betrachtungen.
Eine semantisch ähnliche (aber misbilligte) Schnittstelle für Blockgeräte wird in raw(8) beschrieben.
- O_DIRECTORY
- Falls pathname kein Verzeichnis ist, schlägt damit open fehl. Dieser Schalter wurde in Kernel-Version 2.1.126 hinzugefügt, um Diensteverweigerungsangriffe zu vermeiden, falls opendir(3) mit einem FIFO oder Bandgerät aufgerufen wird.
- O_DSYNC
- Schreibaktionen auf der Datei werden entsprechend den Anforderungen der
synchronisierten
E/A-Daten-Integritätsvervollständigung
vervollständigt.
Zum Zeitpunkt der Rückkehr von write(2) (und ähnlichen) sind die Ausgabedaten zur darunterliegenden Hardware übertragen worden, zusammen mit allen Dateimetadaten, die zum Abfragen der Daten benötigt würden (d.h. als ob jedem write(2) ein Aufruf von fdatasync(2) gefolgt wäre). Siehe Hinweise unten.
- O_EXCL
- stellt sicher, dass dieser Aufruf die Datei erstellt. Falls dieser
Schalter zusammen mit O_CREAT festgelegt wird und pathname
bereits existiert, dann schlägt open() fehl.
Wenn diese zwei Schalter festgelegt werden, wird symbolischen Links nicht gefolgt. Falls pathname ein symbolischer Link ist, dann schlägt open() fehl, unabhängig davon, wohin der symbolische Link verweist.
Im Allgemeinen ist das Verhalten von O_EXCL undefiniert, falls es ohne O_CREAT verwandt wird. Es gibt eine Ausnahme: Unter Linux 2.6 und neuer kann O_EXCL ohne O_CREAT verwandt werden, falls sich pathname auf ein Blockgerät bezieht. Falls das Blockgerät vom System verwandt (d.h. eingehängt) ist, schlägt open() mit dem Fehler EBUSY fehl.
Unter NFS wird O_EXCL nur beim Einsatz von NFSv3 oder neuer unter Kernel 2.6 oder neuer unterstützt. In NFS-Umgebungen, in denen keine Unterstützung für O_EXCL bereit steht, werden Programme, die sich für Sperrungen darauf verlassen, eine Race-Condition enthalten. Portable Programme, die atomares Dateisperren mittels einer Sperrdatei durchführen wollen, und eine Abhängigkeit auf die Unterstützung von O_EXCL duch NFS vermeiden müssen, können eine eindeutige Datei auf dem gleichen Dateisystem erstellen (d.h. den Rechnernamen und die PID einbauen) und link(2) verwenden, um einen Link auf die Sperrdatei zu erstellen. Falls link(2) den Wert 0 zurückliefert, war die Sperrung erfolgreich. Andernfalls verwenden Sie stat(2) auf einer eindeutigen Datei, um zu prüfen, ob die Link-Anzahl sich auf 2 erhöht hat. Falls das der Fall ist, war die Sperre auch erfolgreich.
- O_LARGEFILE
- (LFS) Erlaubt Dateien, deren Größe nicht in einem off_t (aber in einem off64_t) dargestellt werden kann, geöffnet zu werden. Das Makro _LARGEFILE64_SOURCE muss (vor dem Einbinden aller Header-Dateien) definiert sein, um diese Definition zu erhalten. Das Setzen des Feature-Test-Makros _FILE_OFFSET_BITS auf 64 (statt der Verwendung von O_LARGEFILE) ist die bevorzugte Methode zum Zugriff auf große Dateien auf 32-Bit-Systemen (siehe feature_test_macros(7)).
- O_NOATIME (seit Linux 2.6.8)
- Aktualisiert die letzte Zugriffszeit der Datei (st_atime in dem
Inode) nicht, wenn ein read(2) auf der Datei erfolgt.
Dieser Schalter kann nur verwandt werden, falls eine der folgenden Bedingungen zutrifft:
- Die effektive UID des Prozesses passt auf die Eigentümer-UID des Datei.
- Der aufrufende Prozess verfügt über die Capability CAP_FOWNER in seinem Benutzernamensraum und es gibt eine Abbildung der Benutzer-UID der Datei in den Namensraum.
- Dieser Schalter ist für Indizierungs- und Backup-Programme gedacht, bei denen dessen Verwendung die Plattenaktivität signifikant reduzieren kann. Dieser Schalter funktioniert möglicherweise nicht auf allen Dateisystemen. Beispielsweise verwaltet bei NFS der Server die Zugriffszeit.
- O_NOCTTY
- Falls sich pathname auf ein Terminalgerät – siehe tty(4) – bezieht, wird es nicht das steuernde Terminal des Prozesses werden, selbst falls der Prozess noch keines hat.
- O_NOFOLLOW
- Falls pathname ein symbolischer Link ist, schlägt open fehl. Dies ist eine FreeBSD-Erweiterung, die Linux in Version 2.1.126 hinzugefügt wurde. Symbolische Links in früheren Teilen des Pfadnamens werden weiterhin aufgelöst. Siehe auch O_PATH weiter unten.
- O_NONBLOCK oder O_NDELAY
- Falls möglich, wird die Datei im nichtblockierenden Modus
geöffnet. Weder das open() noch folgende Aktionen auf dem
zurückgegebenen Dateideskriptor werden dazu führen, dass der
aufrufende Prozess warten muss.
Beachten Sie, dass dieser Schalter für reguläre Dateien und Blockgeräte keinen Effekt hat. Dies bedeutet, E/A-Aktionen werden (kurz) blockieren, wenn eine Geräteaktivität benötigt wird, unabhängig davon, ob O_NONBLOCK gesetzt ist. Da die Semantik von O_NONBLOCK irgendwann einmal implementiert werden könnte, sollten Anwendungen nicht vom blockierenden Verhalten bei regulären Dateien und Blockgeräten bei der Angabe dieses Schalters abhängen.
For the handling of FIFOs (named pipes), see also fifo(7). For a discussion of the effect of O_NONBLOCK in conjunction with mandatory file locks and with file leases, see fcntl(2).
- O_PATH (seit Linux 2.6.39)
- Erhält einen Dateideskriptor, der für zwei Zwecke eingesetzt
werden kann: um den Ort im Dateisystembaum anzuzeigen und um Aktionen
durchzuführen, die rein auf der Dateideskriptorebene agieren. Die
Datei selbst wird nicht geöffnet und andere Dateiaktionen (z.B.
read(2), write(2), fchmod(2), fchown(2),
fgetxattr(2), mmap(2)) schlagen mit dem Fehler EBADF
fehl.
Die folgenden Aktionen können mit dem entstandenen Dateideskriptor durchgeführt werden:
- close(2); fchdir(2) (seit Linux 3.5); fstat(2) (seit Linux 3.6).
- Duplizieren des Dateideskriptors (dup(2), fcntl(2) F_DUPFD, usw.).
- Ermitteln und Setzen von Dateideskriptorenschaltern (fcntl(2) F_GETFD und F_SETFD).
- Ermitteln von offenen Dateistatusschaltern mittels der Aktion F_GETFL von fcntl(2): Die zurückgelieferten Schalter werden das Bit O_PATH enthalten.
- Übergabe des Dateideskriptors als Argument dirfd von openat(2) und den anderen »*at()«-Systemaufrufen. Dazu gehört linkat(2) mit AT_EMPTY_PATH (oder mittels AT_SYMLINK_FOLLOW von Procfs), selbst falls die Datei kein Verzeichnis ist.
- Übergabe des Dateideskriptors an einen anderen Prozess mittels UNIX-Domain-Sockets (siehe SCM_RIGHTS in unix(7)).
- Wenn O_PATH in flags angegeben ist, werden die von
O_CLOEXEC, O_DIRECTORY und O_NOFOLLOW verschiedenen
Schalter-Bits ignoriert.
Falls pathname ein symbolischer Link ist und auch der Schalter O_NOFOLLOW angegeben ist, dann liefert der Aufruf einen Dateideskriptor zurück, der sich auf den symbolischen Link bezieht. Dieser Dateideskriptor kann als Argument dirfd in Aufrufen von fchownat(2), fstatat(2), linkat(2) und readlinkat(2) mit einem leeren Dateinamen verwandt werden, um Aufrufe auf den symbolischen Link anzuwenden.
- O_SYNC
- Schreibaktionen auf dieser Datei werden entsprechend den Anforderungen der
synchronisierten
E/A-Datei-Integritätsvervollständigung
vervollständigt (in Kontrast zu der durch O_DSYNC
bereitgestellten synchronisierten
E/A-Datei-Integritätsvervollständigung).
Zum Zeitpunkt, zu dem write(2) (und ähnliche) zurückkehren, wurden die Ausgabedaten und zugehörigen Dateimetadaten bereits an die darunterliegende Hardware übergeben (d.h. als ob jeder write(2) von einem Aufruf von fsync(2) gefolgt worden wäre.) Siehe ANMERKUNGEN unten.
- O_TMPFILE (seit Linux 3.11)
- Erstellt eine unbenannte temporäre Datei. Das Argument
pathname legt ein Verzeichnis fest; ein unbenannter Inode wird in
dem Dateisystem dieses Verzeichnisses erstellt. Alles, was in die
entstandene Datei geschrieben wird, geht verloren, wenn der letzte
Dateideskriptor geschlossen wird, sofern der Datei nicht ein Name gegeben
wurde.
O_TMPFILE muss als eines aus O_RDWR oder O_WRONLY und optional O_EXCL festgelegt werden. Falls O_EXCL nicht festgelegt wird, dann kann linkat(2) dazu verwandt werden, die temporäre Datei in das Dateisystem zu linken, womit diese permanent wird, unter Verwendung von Code wie dem folgenden:
char path[PATH_MAX]; fd = open("/Pfad/zu/Verz", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); /* Datei-E/A auf »fd«… */ snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd); linkat(AT_FDCWD, path, AT_FDCWD, "/Pfad/zur/Datei", AT_SYMLINK_FOLLOW);
In diesem Fall bestimmt das Argument mode von open() den Dateirechtemodus, wie bei O_CREAT.
Wird O_EXCL in Zusammenhang mit O_TMPFILE festgelegt, dann wird verhindert, dass die Datei in das Dateisystem in der oben beschriebenen Weise gelinkt wird. (Beachten Sie, dass die Bedeutung von O_EXCL in diesem Fall anders als sonst ist.)
Es gibt zwei Haupteinsatzgebiete für O_TMPFILE:
- Verbesserte Funktionalität von tmpfile(3): Ressourcen-Wettstreit-freie Erstellung temporärer Dateien die (1) automatisch gelöscht werden, wenn sie geschlossen werden; die (2) niemals mittels irgend eines Dateinamens erreicht werden können; die (3) nicht Subjekt eines Symlink-Angriffs sind und die (4) nicht vom Aufrufenden verlangen, sich eindeutige Namen auszudenken.
- Erstellen einer Datei, die ursprünglich unsichtbar ist, die dann mit den Daten gefüllt und angepasst wird, um die korrekten Dateisystemattribute zu erhalten ((fchown(2), fchmod(2), fsetxattr(2) usw.), bevor sie atomar in das Dateisystem in einer vollständigen Form gelinkt wird (mittels linkat(2) wie oben beschrieben).
- O_TMPFILE benötigt die Unterstützung des zugrundeliegenden Dateisystems. Nur eine Teilmenge der Linux-Dateisysteme unterstützt dies. In der anfänglichen Implementierung wurde die Unterstützung für die Dateisysteme Ext2, Ext3, Ext4, UDF, Minix und Shmem bereitgestellt. Die Unterstützung für weitere Dateisysteme wurde später wie folgt hinzugefügt: XFS (Linux 3.15), Btrfs (Linux 3.16), F2FS (Linux 3.16) und Ubifs (Linux 4.9).
- O_TRUNC
- Falls die Datei bereits existiert, eine reguläre Datei ist und der Zugriffsmodus Schreiben erlaubt (d.h. O_RDWR oder O_WRONLY ist), dann wird sie auf die Länge 0 abgeschnitten. Falls die Datei ein FIFO oder Terminalgerät ist, dann wird der Schalter O_TRUNC ignoriert. Andernfalls ist die Auswirkung von O_TRUNC nicht festgelegt.
creat()¶
Ein Aufruf von creat() is äquivalent zum Aufruf von open() mit flags identisch zu O_CREAT|O_WRONLY|O_TRUNC.openat()¶
Der Systemaufruf openat() arbeitet genau wie open(), außer den hier beschriebenen Unterschieden.Falls der in pathname angegebene Pfadname relativ ist, dann wird er relativ zu dem Verzeichnis interpretiert, auf das der Dateideskriptor dirfd verweist (statt relativ zu dem aktuellen Arbeitsverzeichnis des aufrufenden Prozesses, wie es bei open() für einen relativen Pfadnamen erfolgt).
Falls pathname relativ ist und dirfd den speziellen Wert AT_FDCWD enthält, dann wird pathname relativ zum aktuellen Arbeitsverzeichnis des aufrufenden Prozesses interpretiert (wie open()).
Falls pathname absolut ist wird dirfd ignoriert.
RÜCKGABEWERT¶
open(), openat() und creat() liefern den neuen Dateideskriptor zurück oder -1, falls ein Fehler auftrat (in diesem Fall wird errno entsprechend gesetzt).FEHLER¶
open(), openat() und creat() können mit den folgenden Fehlern fehlschlagen:- EACCES
- Der angeforderte Zugriff auf die Datei ist nicht erlaubt oder die Suchberechtigung ist für eines der Verzeichnisse im Pfadanteil von pathname verweigert oder die Datei existierte noch nicht oder Schreibzugriff auf das Elternverzeichnis ist nicht erlaubt. (Siehe auch path_resolution(7).)
- EDQUOT
- Wo O_CREAT angegeben ist existiert die Datei nicht und die Quota des Benutzers an Plattenblöcken oder Inodes auf dem Dateisystem ist erschöpft.
- EEXIST
- pathname existiert bereits und O_CREAT und O_EXCL wurden verwandt.
- EFAULT
- pathname zeigt aus dem für Sie zugänglichen Adressraum heraus.
- EFBIG
- siehe EOVERFLOW
- EINTR
- Während der Aufruf wartet, bis ein langsames Gerät vollständig geöffnet ist (z.B. ein FIFO, siehe fifo(7)), wurde er von einem Signal-Handler unterbrochen, siehe signal(7).
- EINVAL
- Das Dateisystem unterstützt den Schalter O_DIRECT nicht. Lesen Sie ANMERKUNGEN für weitere Informationen.
- EINVAL
- Unzulässiger Wert in flags.
- EINVAL
- O_TMPFILE wurde in flags angegeben, aber weder O_WRONLY noch O_RDWR wurden angegeben.
- EISDIR
- pathname bezieht sich auf ein Verzeichnis und der Zugriff beinhaltete Schreiben (d.h. O_WRONLY oder O_RDWR ist gesetzt).
- EISDIR
- pathname bezieht sich auf ein existierendes Verzeichnis, O_TMPFILE und entweder O_WRONLY oder O_RDWR wurde in flags angegeben, aber diese Kernelversion stellt die Funktionalität O_TMPFILE nicht zur Verfügung.
- ELOOP
- Bei der Auflösung von pathname wurden zu viele symbolische Links gefunden.
- ELOOP
- pathname war ein symbolischer Link und flags legte O_NOFOLLOW aber nicht O_PATH fest.
- EMFILE
- Die pro-Prozess-Begrenzung der Anzahl offener Dateideskriptoren wurde erreicht (siehe die Beschreibung von RLIMIT_NOFILE in getrlimit(2)).
- ENAMETOOLONG
- pathname war zu lang.
- ENFILE
- Die systemweite Beschränkung für die Gesamtzahl offener Dateien wurde erreicht.
- ENODEV
- pathname bezieht sich auf eine Geräte-Spezialdatei und kein entsprechendes Gerät existiert. (Dies ist ein Fehler im Linux-Kernel; in dieser Situation muss ENXIO zurückgeliefert werden.)
- ENOENT
- O_CREAT ist nicht gesetzt und die benannte Datei existiert nicht. Oder ein Verzeichnisteil in pathname existiert nicht oder ist ein toter symbolischer Link.
- ENOENT
- pathname bezieht sich auf ein nicht existierendes Verzeichnis, O_TMPFILE und entweder O_WRONLY oder O_RDWR wurde in flags angegeben, aber diese Kernelversion stellt die Funktionalität O_TMPFILE nicht zur Verfügung.
- ENOMEM
- Die benannte Datei ist ein FIFO, aber der Speicher für den FIFO-Puffer kann nicht bereitgestellt werden, da die benutzerbezogene harte Grenze bezüglich Speicherzuweisung für Pipes erreicht wurde und der Aufrufende keine Privilegien hat; siehe pipe(7).
- ENOMEM
- Es war nicht genügend Kernel-Speicher verfügbar.
- ENOSPC
- pathname sollte erstellt werden, aber das Gerät, das pathname enthält, hat für die neue Datei keinen Platz.
- ENOTDIR
- Eine als Verzeichnis verwandte Komponente in pathname ist tatsächlich kein Verzeichnis oder O_DIRECTORY wurde angegeben, aber pathname war kein Verzeichnis.
- ENXIO
- O_NONBLOCK | O_WRONLY ist gesetzt, die benannte Datei ist ein FIFO und kein Prozess hat den FIFO zum Lesen offen.
- ENXIO
- Die Datei ist eine Geräte-Spezialdatei und kein entsprechendes Gerät existiert.
- EOPNOTSUPP
- Das Dateisystem, das pathname enthält, unterstützt O_TMPFILE nicht.
- EOVERFLOW
- pathname bezieht sich auf eine normale Datei, die zu groß zum Öffnen ist. Das normale Szenario ist, dass eine auf einer 32-Bit-Plattform ohne -D_FILE_OFFSET_BITS=64 übersetzte Anwendung versuchte, eine Datei zu öffnen, deren Größe (1<<31)-1 byte überschritt; siehe auch O_LARGEFILE weiter oben. Dies ist der durch POSIX.1 festgelegte Fehler; in Kerneln vor 2.6.24 gab Linux in diesem Fall den Fehler EFBIG zurück.
- EPERM
- Der Schalter O_NOATIME war festgelegt, aber die effektive Benutzer-ID des Aufrufenden passte nicht auf den Eigentümer der Datei und der Aufrufende war nicht privilegiert.
- EPERM
- Die Aktion wurde durch eine Dateiversiegelung verhindert; siehe fcntl(2).
- EROFS
- pathname bezieht sich auf eine Datei auf einem schreibgeschützten Dateisystem, und Schreibzugriff wurde angefordert.
- ETXTBSY
- pathname bezieht sich auf ein ausführbares Abbild, das derzeit ausgeführt wird und Schreibzugriff wurde erbeten.
- EWOULDBLOCK
- Der Schalter O_NONBLOCK wurde angegeben und eine inkompatible Ausleihe wurde auf der Datei gehalten (siehe fcntl(2)).
Die folgenden zusätzlichen Fehler können bei openat() auftreten:
- EBADF
- dirfd ist kein zulässiger Dateideskriptor.
- ENOTDIR
- pathname ist ein relativer Pfadname und dirfd ist ein Dateideskriptor, der sich auf eine Datei statt auf ein Verzeichnis bezieht.
VERSIONEN¶
openat() wurde zu Linux in Kernel 2.6.16 hinzugefügt; Bibliotheksunterstützung wurde zu Glibc in Version 2.4 hinzugefügt.KONFORM ZU¶
open(), creat() SVr4, 4.3BSD, POSIX.1-2001, POSIX.1-2008.openat(): POSIX.1-2008.
Die Schalter O_DIRECT, O_NOATIME, O_PATH und O_TMPFILE sind Linux-spezifisch. Sie müssen _GNU_SOURCE definieren, um ihre Definitionen zu erhalten.
Die Schalter O_CLOEXEC, O_DIRECTORY und O_NOFOLLOW sind nicht in POSIX.1-2001 sondern in POSIX.1-2008 spezifiziert. Seit Glibc 2.12 kann ihre Definition erhalten werden, indem entweder _POSIX_C_SOURCE mit einem Wert größer als oder identisch zu 200809L definiert wird oder durch _XOPEN_SOURCE mit einem Wert größer als oder identisch zu 700. In Glibc 2.11 und älter kann die Definition über die Definition von _GNU_SOURCE erhalten werden.
Wie in feature_test_macros(7) angemerkt, müssen Feature-Test-Makros wie _POSIX_C_SOURCE, _XOPEN_SOURCE und _GNU_SOURCE definiert werden, bevor irgendeine Header-Datei mit »include« verwandt wird.
ANMERKUNGEN¶
Unter Linux gibt der Schalter O_NONBLOCK an, dass die Datei geöffnet werden soll, ohne aber notwendigerweise zu lesen oder zu schreiben. Dies wird typischerweise zum Öffnen von Geräten verwandt, um den Dateideskriptor für ioctl(2) zu erhalten.Der (undefinierte) Effekt von O_RDONLY | O_TRUNC unterscheidet sich in vielen Implementierungen. Auf vielen Systemen wird die Datei tatsächlich abgeschnitten.
Beachten Sie, dass open() Spezial-Gerätedateien öffnen kann, aber creat() sie nicht erstellen kann. Verwenden Sie stattdessen mknod(2).
Falls die Datei neu erstellt wurde, werden ihre Felder st_atime, st_ctime, st_mtime (Zeit des letzten Zugriffs, Zeit der letzten Statusänderung und Zeit der letzten Änderung, siehe stat(2)) auf die aktuelle Zeit gesetzt und ebenso die Felder st_ctime und st_mtime des Elternverzeichnisses. Andernfalls, falls die Datei aufgrund des Schalters O_TRUNC geändert wurde, werden ihre Felder st_ctime und st_mtime auf die aktuelle Zeit gesetzt.
Die Dateien im Verzeichnis /proc/[PID]/fd zeigen die offenen Dateideskriptoren des Prozesses mit der PID PID. Die Dateien im Verzeichnis /proc/[PID]/fdinfo zeigen noch mehr Informationen über diese Dateideskriptoren. Siehe proc(5) für weitere Details über beide Verzeichnisse.
Offene Dateideskriptionen:¶
Der Begriff offene Dateideskription wird von POSIX verwandt, um sich auf Einträge in der systemweiten Tabelle der offenen Dateien zu beziehen. In anderen Zusammenhängen wird dieses Objekt verschieden auch »offenes Dateiobjekt«, »Datei-Handle«, »offener Dateitabelleneintrag« oder – in der Sprache der Kernel-Entwickler – struct file genannt.Wenn ein Dateideskriptor (mit dup(2) oder ähnlichem) dupliziert wird, bezieht sich das Duplikat auf die gleiche offene Dateideskription wie der ursprüngliche Datedeskriptor und die zwei Dateideskriptoren haben konsequenterweise den gleichen Dateiversatz und die gleichen Dateistatusschalter. Solch ein gemeinsamer Satz kann auch zwischen Prozessen auftreten: ein mit fork(2) erstellter Kindprozess erbt Duplikate der Dateideskriptoren seines Elternprozesses und diese Duplikate beziehen sich auf die gleichen offenen Dateideskriptoren.
Jedes open() einer Datei erstellt eine neue offene Dateideskription; daher kann es mehrere offene Dateideskriptionen geben, die einem Datei-Inode entsprechen.
Unter Linux kann die Aktion KCMP_FILE von kcmp(2) zum Testen, ob sich zwei Dateideskriptoren (in dem gleichen Prozess oder in zwei verschiedenen Prozessen) auf die gleiche offene Dateideskription beziehen, verwandt werden.
Synchronisierte E/A¶
Die Option »synchronisierte E/A« von POSIX.1-2008 spezifiziert verschiedene Varianten der synchronisierten E/A und spezifiziert Schalter O_SYNC, O_DSYNC und O_RSYNC von open() für die Steuerung des Verhaltens. Unabhängig davon, ob eine Implementierung diese Option unterstützt muss sie mindestens die Verwendung von O_SYNC für reguläre Dateien unterstützen.Linux implementiert O_SYNC und O_DSYNC, aber nicht O_RSYNC. (Etwas inkorrekt definiert Glibc O_RSYNC auf den gleichen Wert wie O_SYNC.)
O_SYNC stellt synchronisierte E/A-Datei-Integritätsvervollständigung bereit. Das bedeutet, Schreibaktionen schieben ihre Daten und zugehörigen Metadaten an die darunterliegende Hardware. O_DSYNC stellt synchronisierte E/A-Daten-Integritätsvervollständigung bereit. Das bedeutet, Schreibaktionen schieben ihre Daten an die darunterliegende Hardware, aber schieben nur Metadatenaktualisierungen, die benötigt werden, um folgende Leseaktionen erfolgreich abzuschließen. Datenintegritätsvervollständigung kann die Anzahl der Aktionen reduzieren, die für Anwendungen notwendig werden, die keine Garantien für die Dateiintegritätsvervollständigung benötigen.
Um den Unterschied zwischen den zwei Arten von Vervollständigung zu verstehen, betrachen Sie zwei verschiedene Dateimetadaten: den Zeitstempel der letzten Änderung (st_mtime) und die Dateilänge. Alle Schreibaktionen aktualisieren den Zeitstempel der letzten Dateiänderung, aber nur Schreibaktionen, die Daten am Ende der Datei hinzufügen, müssen die Dateilänge ändern. Der Zeitstempel der letzten Änderung wird nicht benötigt, um sicherzustellen, dass eine Leseaktion erfolgreich abgeschlossen werden kann, aber die Dateilänge wird dafür benötigt. Daher würde O_DSYNC nur garantieren, dass Aktualisierungen der Dateilängen-Metadaten rausgeschoben werden (während O_SYNC immer auch das Metadatum des Zeitstempels der letzten Änderung rausschieben würde).
Vor Linux 2.6.33 implementierte Linux nur den Schalter O_SYNC für open(). Als dieser Schalter spezifiziert wurde, stellten die meisten Dateisysteme das Äquivalent von synchronisierter E/A-Daten-Integritätsvervollständigung bereit (d.h. O_SYNC war tatsächlich als Äquivalent von O_DSYNC implementiert).
Seit Linux 2.6.33 wird korrekte Unterstützung für O_SYNC bereitgestellt. Um Rückwärtskompatibilität sicherzustellen wurde aber O_DSYNC mit dem gleichen Wert wie das historische O_SYNC definiert und O_SYNC wurde als neuer (Zweibit-)Schalterwert definiert, der den Wert des Schalters O_DSYNC enthält. Das stellt sicher, dass Anwendungen, die gegen neue Header übersetzt wurden, mindestens die Semantik von O_DSYNC auf pre-2.6.33-Kerneln erhalten.
NFS¶
Es gibt mehrere Unglücklichkeiten im Protokoll, das NFS unterliegt, die unter anderem O_SYNC und O_NDELAY betreffen.Auf NFS-Dateisystemen mit aktivierter UID-Abbildung könnte open() einen Dateideskriptor zurückliefern, aber read(2)-Anfragen werden beispielsweise mit EACCES verweigert. Dies erfolgt, da der Client open() durchführt, indem er die Rechte prüft, aber die UID-Abbildung auf dem Server bei Lese- und Schreibanfragen erfolgt.
FIFOs¶
Öffnen des Lese- oder Schreibendes eines FIFOS blockiert, bis das andere Ende auch geöffnet wurde (durch einen anderen Prozess oder Thread). Siehe fifo(7) für weitere Details.Dateizugriffsmodus¶
Anders als andere Werte, die in flags festgelegt werden können, legen die Zugriffsmodus-Werte O_RDONLY, O_WRONLY und O_RDWR nicht individuelle Bits fest. Stattdessen definieren sie die untersten zwei Bits von flags und sind respektive als 0, 1 und 2 definiert. Mit anderen Worten, die Kombination O_RDONLY | O_WRONLY ist ein logischer Fehler und hat bestimmt nicht die gleiche Bedeutung wie O_RDWR.Linux reserviert den besonderen, nicht standardisierten Zugriffsmodus 3 (binär 11) in flags für folgendes: Prüfe auf Lese- und Schreibberechtigung der Datei und liefere einen Dateideskriptor zurück, der weder zum Lesen noch zum Schreiben verwandt werden kann. Dieser nicht standardisierte Zugriffsmodus wird von einigen Linux-Treibern verwandt, um einen Dateideskriptor zurückzuliefern, der nur für gerätespezifische ioctl(2)-Aktionen benutzt werden kann.
Begründung für openat()- und andere Verzeichnis-Dateideskriptor APIs¶
openat() und andere Systemaufrufe und Bibliotheksfunktionen, die ein Verzeichnis-Dateideskriptor als Argument akzeptieren (d.h. execveat(2), faccessat(2), fanotify_mark(2), fchmodat(2), fchownat(2), fstatat(2), futimesat(2), linkat(2), mkdirat(2), mknodat(2), name_to_handle_at(2), readlinkat(2), renameat(2), symlinkat(2), unlinkat(2), utimensat(2), mkfifoat(3) und scandirat(3)) werden aus zwei Gründen unterstützt. Hier erfolgt die Erläuterung am openat()-Aufruf, aber der Grund ist analog für die anderen Schnittstellen.Erstens erlaubt openat() es Anwendungen, Race-Conditions zu vermeiden, die bei der Verwendung von open() auftreten können, wenn Dateien geöffnet werden, die sich nicht im lokalen Verzeichnis befinden. Diese Race-Conditions entstammen der Tatsache, dass einige Komponenten des Verzeichnispräfixes, der an open() übergeben wird, parallel zum Aufruf von open() geändert werden können. Nehmen Sie beispielsweise an, dass Sie die Datei pfad/zu/xxx.dep öffnen möchten, falls pfad/zu/xxx existiert. Das Problem besteht darin, das sich zwischen der Existenzüberprüfung und dem Schritt der Dateierstellung pfad oder zu (die symbolischen Links sein können) geändert haben und auf einen anderen Ort zeigen können. Solche Ressourcenwettläufe können vermieden werden, indem ein Dateideskriptor für das Zielverzeichnis geöffnet wird und dann dieser Dateideskriptor als Argument dirfd von (beispielsweise) fstatat(2) und openat() verwandt wird.
Zweitens erlaubt openat() die Implementierung eines pro-Thread-»Arbeitsverzeichnisses«, mittels von der Anwendung verwalteten Datei-Deskriptor(en). (Diese Funktionalität kann weniger effizient auch mittels Tricks basierend auf der Verwendung von /proc/self/fd/dirfd erreicht werden.)
O_DIRECT¶
Der Schalter O_DIRECT könnte Ausrichtungsbeschränkungen in der Länge und Adresse der Puffer im Benutzerbereich und dem Dateiversatz von E/As verhängen. Unter Linux variieren die Ausrichtungsbeschränkungen je nach Dateisystem und Kernelversion und können auch ganz fehlen. Es gibt jedoch derzeit keine dateisystemunabhängige Schnittstelle für eine Anwendung, um diese Beschränkungen für eine gegebene Datei oder ein Dateisystem aufzufinden. Einige Dateisysteme stellen zu diesem Zweck ihre eigenen Schnittstellen bereit, beispielsweise die Aktion XFS_IOC_DIOINFO in xfsctl(3).Unter Linux 2.4 müssen Übertragungsgrößen, die Ausrichtung des Benutzerpuffers und der Dateiversatz Vielfache der logischen Blockgröße des Dateisystems sein. Seit Linux 2.6.0 reicht ein Ausrichtung an der logischen Blockgröße des darunterliegenden Speichers (normalerweise 512 byte) aus. Die logische Blockgröße kann mit der Aktion BLKSSZGET von ioctl(2) festgelegt werden oder mittels des Shell-Befehls:
blockdev --getss
O_DIRECT I/Os should never be run concurrently with the fork(2) system call, if the memory buffer is a private mapping (i.e., any mapping created with the mmap(2) MAP_PRIVATE flag; this includes memory allocated on the heap and statically allocated buffers). Any such I/Os, whether submitted via an asynchronous I/O interface or from another thread in the process, should be completed before fork(2) is called. Failure to do so can result in data corruption and undefined behavior in parent and child processes. This restriction does not apply when the memory buffer for the O_DIRECT I/Os was created using shmat(2) or mmap(2) with the MAP_SHARED flag. Nor does this restriction apply when the memory buffer has been advised as MADV_DONTFORK with madvise(2), ensuring that it will not be available to the child after fork(2).
Der Schalter O_DIRECT wurde in SGI IRIX eingeführt, wo er Ausrichtungsbeschränkungen hat, die denen von Linux 2.4 ähnlich sind. IRIX hat außerdem einen fcntl(2)-Aufruf, um geeignete Ausrichtungen und Größen abzufragen. FreeBSD 4.x führte einen gleichnamigen Schalter ein, jedoch ohne Ausrichtungsbeschränkungen.
Die Unterstützung für O_DIRECT wurde unter Linux in Kernel Version 2.4.10 hinzugefügt. Ältere Kernel werden diesen Schalter einfach ignorieren. Einige Dateisysteme könnten den Schalter nicht implementieren und open() wird mit EINVAL fehlschlagen, falls er verwandt wird.
Anwendungen sollten das Vermischen von O_DIRECT und normaler E/A auf der gleichen Datei vermeiden, insbesondere für überlappende Regionen in der gleichen Datei. Selbst wenn das Dateisystem die Kohärenzprobleme in dieser Situation korrekt handhabt, ist der Gesamt-E/A-Durchsatz wahrscheinlich geringer, als wenn einer der beiden Modi allein verwandt worden wäre. Entsprechend sollten Anwendungen das Mischen von mmap(2) von Dateien mit direktem E/A auf die gleichen Dateien vermeiden.
Das Verhalten von O_DIRECT mit NFS wird sich vom lokalen Dateisystem unterscheiden. Ältere Kernel oder Kernel, die in bestimmter Weise konfiguriert wurden, unterstützen diese Kombination möglicherweise nicht. Das NFS-Protokoll unterstützt die Übergabe des Schalters an den Server nicht, daher wird O_DIRECT-E/A den Seitenzwischenspeicher auf dem Client umgehen. Der Server könnte weiterhin die E/A zwischenspeichern. Der Client bittet den Server, die E/A zu synchronisieren, damit die synchrone Semantik von O_DIRECT aufrechterhalten wird. Einige Server werden unter diesen Umständen unzureichende Leistung erbringen, insbesondere bei kleiner E/A-Größe. Einige Server sind möglicherweise auch so konfiguriert, dass sie ihre Clients darüber belügen, dass die E/A stabilen Speicher erreicht haben. Dies wird die Leistungseinbuße bei gleichzeitigem Risiko der Datenintegrität im Fall eines Stromausfalls verhindern. Der Linux-NFS-Client legt keine Ausrichtungsbeschränkungen bei O_DIRECT-E/A fest.
In Zusammenfassung: O_DIRECT ist ein extrem leistungsfähiges Werkzeug, das mit Vorsicht verwandt werden sollte. Es wird empfohlen, dass Anwendungen die Verwendung von O_DIRECT als Leistungssteigerungsoption betrachten, die standardmäßig deaktiviert ist.
FEHLER¶
Derzeit ist es nicht möglich, Signal-getriebene E/A zu aktivieren, indem O_ASYNC beim Aufruf von open() verwandt wird; siehe fcntl(2), um diesen Schalter zu aktivieren.Es muss auf zwei verschiedene Fehler-Codes, EISDIR und ENOENT geprüft werden, wenn versucht wird, zu bestimmen, ob der Kernel die Funktionalität O_TMPFILE unterstützt.
Wenn sowohl O_CREAT als auch O_DIRECTORY in flags angegeben sind und die durch pathname angegebene Datei nicht existiert, wird open() eine normale Datei erstellen (d.h. O_DIRECTORY wird ignoriert).
SIEHE AUCH¶
chmod(2), chown(2), close(2), dup(2), fcntl(2), link(2), lseek(2), mknod(2), mmap(2), mount(2), open_by_handle_at(2), read(2), socket(2), stat(2), umask(2), unlink(2), write(2), fopen(3), acl(5), fifo(7), path_resolution(7), symlink(7)KOLOPHON¶
Diese Seite ist Teil der Veröffentlichung 4.09 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 Note: File description → Dateideskription, Helge Kreutzmann <debian@helgefjell.de>, Mario Blättermann <mario.blaettermann@gmail.com> und Chris Leick <c.leick@vollbio.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 <debian-l10n-german@lists.debian.org>.
12. Dezember 2016 | Linux |