open(2) System Calls Manual open(2) BEZEICHNUNG open, openat, creat - eine Datei offnen und moglicherweise erzeugen BIBLIOTHEK Standard-C-Bibliothek (libc, -lc) UBERSICHT #include int open(const char *Pfadname, int Schalter, /* mode_t Modus */ ); int creat(const char *Pfadname, mode_t Modus); int openat(int Verzdd, const char *Pfadname, int Schalter, /* mode_t Modus */ ); /* Separat in openat2(2) dokumentiert: */ int openat2(int Verzdd, const char *Pfadname, const struct open_how *wie, size_t Grosse); Mit Glibc erforderliche Feature-Test-Makros (siehe feature_test_macros(7)): openat(): Seit Glibc 2.10: _POSIX_C_SOURCE >= 200809L Vor Glibc 2.10: _ATFILE_SOURCE BESCHREIBUNG Der Systemaufruf open() offnet eine durch Pfadname angegebene Datei. Falls die angegebene Datei nicht existiert, kann sie optional (falls O_CREAT in Schalter angegeben wurde) durch open() erstellt werden. Der Ruckgabewert von open() ist ein Dateideskriptor, eine kleine, nicht negative Ganzzahl, die ein Index fur einen Eintrag in der Tabelle der offenen Dateideskriptoren des Prozesses ist. Der Dateideskriptor wird in nachfolgenden Systemaufrufen (read(2), write(2), lseek(2), fcntl(2) usw.) genutzt, um den Bezug zu der offenen Datei herzustellen. Der bei einem erfolgreichen Aufruf zuruckgelieferte Dateideskriptor wird der niedrigstzahlige, noch nicht fur den Prozess offene Dateideskriptor sein. Standardmassig bleibt der neue Dateideskriptor uber 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 Andern 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 Pfadname im Folgenden entfernt oder so verandert wird, dass er auf eine andere Datei zeigt. Fur weitere Details uber offene Dateideskriptionen, siehe ANMERKUNGEN. Das Argument Schalter 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 offnen. Zusatzlich konnen Null oder mehr Dateierstellungsschalter in Schalter 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 aufgefuhrten Schalter sind die Dateistatusschalter. Der Unterschied zwischen diesen zwei Gruppen von Schaltern besteht darin, dass die Dateierstellungsschalter die Semantik der Open-Aktion selbst betreffen, wahrend die Dateistatusschalter die Semantik der nachfolgenden E/A-Aktionen betreffen. Die Dateistatussschalter konnen abgefragt und (in einigen Fallen) verandert werden; siehe fcntl(2) fur Details. Die komplette Liste der Dateierstellungs- und Dateistatusschalter ist wie folgt: O_APPEND Die Datei wird im Anhangemodus geoffnet. Vor jedem write(2) wird der Dateiversatz an das Ende der Datei positioniert, wie mit lseek(2). Die Veranderung des Dateiversatzes und die Schreibaktion werden als einzelner, atomarer Schritt durchgefuhrt. O_APPEND kann auf NFS-Dateisystemen zu beschadigten Dateien fuhren, falls mehr als ein Prozess auf einmal Daten an die Datei anhangt. Dies kommt daher, da NFS das Anhangen an Dateien nicht unterstutzt 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 (standardmassig SIGIO, dies kann aber mit fcntl(2) geandert werden), wenn Ein- oder Ausgabe auf diesem Dateideskriptor moglich wird. Diese Funktionalitat ist nur fur Terminals, Pseudoterminals, Sockets und (seit Linux 2.6) Pipes und FIFOs verfugbar. Siehe fcntl(2) fur weitere Details. Siehe auch FEHLER unten. O_CLOEXEC (seit Linux 2.6.23) Aktiviert den Schalter >>close-on-exec<< fur den neuen Dateideskriptor. Durch Angabe dieses Schalters wird einem Programm ermoglicht, zusatzliche 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 offnet 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) durchfuhrt. Abhangig von der Reihenfolge der Ausfuhrung kann der Ressourcenwettlauf dazu fuhren, dass der von open(2) zuruckgelieferte Dateideskriptor ungeplant von dem Programm durchgesickert ist, das von dem Kindprozess mittels fork(2) erzeugt wurde. (Diese Art von Ressourcenwettlauf ist prinzipiell fur jeden Systemaufruf moglich, der einen Dateideskriptor erstellt, dessen Schalter close-on-exec gesetzt sein solte, und verschiedene andere Linux-Systemaufrufe stellen ein Aquivalent zu dem Schalter O_CLOEXEC bereit, um mit diesem Problem umzugehen. O_CREAT Falls Pfadname nicht existiert, wird eine normale Datei erstellt. Der Eigentumer (Benutzerkennung) der neuen Datei wird auf die effektive Benutzerkennung des Prozesses gesetzt. Die Gruppen-Eigentumerschaft (Gruppenkennung) der neuen Datei wird entweder auf die effektive Gruppenkennung des Prozesses (System-V-Semantik) oder auf die Gruppenkennung des Elternverzeichnisses (BSD-Semantik) gesetzt. Unter Linux hangt 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 hangt das Verhalten von den in mount(8) beschriebenen Einhangeoptionen bsdgroups und sysvgroups ab. Das Argument Modus gibt die Dateimodusbits, die beim Erstellen einer neuen Dateien angewandt werden sollen, an. Falls weder O_CREAT noch O_TMPFILE angegeben ist, wird Modus ignoriert (und kann daher als 0 angegeben oder einfach weggelassen werden). Das Argument Modus muss angegeben werden, falls O_CREAT oder O_TMPFILE in Schalter angegeben ist; wird es nicht angegeben, werden einige willkurliche Bytes aus dem Stack als Dateimodus gesetzt. Der effektive Modus wird durch die umask des Prozesses wie ublich verandert: in der Abwesenheit einer Standard-ACL ist der Modus der erstellten Datei (mode & ~umask). Beachten Sie, dass dieser Modus nur bei zukunftigen Zugriffen auf die neu erstellte Datei gilt; der Aufruf open(), der eine nur-lesbare Datei erstellte, kann sehr wohl einen les- und schreibbaren Dateideskriptor zuruckliefern. Fur Modus werden die folgenden symbolischen Konstanten bereitgestellt: S_IRWXU 00700 Benutzer (Dateieigentumer) hat Lese-, Schreibe- und Ausfuhrrechte S_IRUSR 00400 Benutzer hat Leserechte S_IWUSR 00200 Benutzer hat Schreibrechte S_IXUSR 00100 Benutzer hat Ausfuhrrechte S_IRWXG 00070 Gruppe hat Lese-, Schreib- und Ausfuhrrechte S_IRGRP 00040 Gruppe hat Leserechte S_IWGRP 00020 Gruppe hat Schreibrechte S_IXGRP 00010 Gruppe hat Ausfuhrrechte S_IRWXO 00070 andere haben Lese-, Schreib- und Ausfuhrrechte S_IROTH 00004 andere haben Leserechte S_IWOTH 00002 andere haben Schreibrechte S_IXOTH 00001 andere haben Ausfuhrrechte Laut POSIX ist der Effekt, wenn andere Bits in Modus gesetzt werden, nicht spezifiziert. Unter Linux werden auch die folgenden Bits in Modus berucksichtigt: S_ISUID 0004000 set-user-ID-Bit S_ISGID 0002000 set-group-ID-Bit (siehe inode(7)) S_ISVTX 0001000 Sticky-Bit (siehe inode(7)) 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 nutzlich, 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 ubertragen, gibt aber nicht die Garantien des Schalters O_SYNC, dass Daten und notwendige Metadaten ubetragen wurden. Um synchrone E/A zu garantieren, muss O_SYNC zusatzlich zu O_DIRECT verwandt werden. Siehe ANMERKUNGEN fur weitere Betrachtungen. Eine semantisch ahnliche (aber missbilligte) Schnittstelle fur Blockgerate wird in raw(8) beschrieben. O_DIRECTORY Falls Pfadname kein Verzeichnis ist, schlagt damit open fehl. Dieser Schalter wurde in Linux-Version 2.1.126 hinzugefugt, um Diensteverweigerungsangriffe zu vermeiden, falls opendir(3) mit einem FIFO oder Bandgerat aufgerufen wird. O_DSYNC Schreibaktionen auf der Datei werden entsprechend den Anforderungen der synchronisierten E/A-Daten-Integritatsvervollstandigung vervollstandigt. Zum Zeitpunkt der Ruckkehr von write(2) (und ahnlichen) sind die Ausgabedaten zur darunterliegenden Hardware ubertragen worden, zusammen mit allen Dateimetadaten, die zum Abfragen der Daten benotigt wurden (d.h. als ob jedem write(2) ein Aufruf von fdatasync(2) gefolgt ware). Siehe Hinweise unten. O_EXCL stellt sicher, dass dieser Aufruf die Datei erstellt. Falls dieser Schalter zusammen mit O_CREAT angegeben wird und Pfadname bereits existiert, dann schlagt open() mit dem Fehler EEXIST fehl. Wenn diese zwei Schalter angegeben werden, wird symbolischen Links nicht gefolgt. Falls Pfadname ein symbolischer Link ist, dann schlagt open() fehl, unabhangig 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 Pfadname auf ein Blockgerat bezieht. Falls das Blockgerat vom System verwandt (d.h. eingehangt) ist, schlagt open() mit dem Fehler EBUSY fehl. Unter NFS wird O_EXCL nur beim Einsatz von NFSv3 oder neuer unter Kernel 2.6 oder neuer unterstutzt. In NFS-Umgebungen, in denen keine Unterstutzung fur O_EXCL bereit steht, werden Programme, die sich fur Sperrungen darauf verlassen, eine Race-Condition enthalten. Portable Programme, die atomares Dateisperren mittels einer Sperrdatei durchfuhren wollen, und eine Abhangigkeit auf die Unterstutzung von O_EXCL duch NFS vermeiden mussen, konnen 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 zuruckliefert, war die Sperrung erfolgreich. Andernfalls verwenden Sie stat(2) auf einer eindeutigen Datei, um zu prufen, ob die Link-Anzahl sich auf 2 erhoht hat. Falls das der Fall ist, war die Sperre auch erfolgreich. O_LARGEFILE (LFS) Erlaubt Dateien, deren Grosse nicht in einem off_t (aber in einem off64_t) dargestellt werden kann, geoffnet 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 grosse 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: o Die effektive UID des Prozesses passt auf die Eigentumer-UID des Datei. o Der aufrufende Prozess verfugt uber die Capability CAP_FOWNER in seinem Benutzernamensraum und es gibt eine Abbildung der Benutzer-UID der Datei in den Namensraum. Dieser Schalter ist fur Indizierungs- und Backup-Programme gedacht, bei denen dessen Verwendung die Plattenaktivitat signifikant reduzieren kann. Dieser Schalter funktioniert moglicherweise nicht auf allen Dateisystemen. Beispielsweise verwaltet bei NFS der Server die Zugriffszeit. O_NOCTTY Falls sich Pfadname auf ein Terminalgerat - siehe tty(4) - bezieht, wird es nicht das steuernde Terminal des Prozesses werden, selbst falls der Prozess noch keines hat. O_NOFOLLOW Falls die abschliessende Komponenten (d.h. der Basisname) von Pfadname ein symbolischer Link ist, schlagt das Offnen mit dem Fehler ELOOP fehl. Symbolische Links in fruheren Komponenten des Pfadnamens werden weiterhin aufgelost. (Beachten Sie, dass der in diesem Fall moglich Fehler ELOOP ununterscheidbar vom dem Fall ist, in dem ein Offnen fehlschlagt, da es zu viele symbolische Links beim Auflosen von Komponenten im Prafixanteil des Pfadnamens gibt.) Dieser Schalter ist eine FreeBSD-Erweiterung, die in Version 2.1.126 in Linux hinzugefugt und schliesslich in POSIX.1-2008 standardisiert wurde. Siehe auch O_PATH weiter unten. O_NONBLOCK oder O_NDELAY Falls moglich, wird die Datei im nichtblockierenden Modus geoffnet. Weder das open() noch folgende E/A-Aktionen auf dem zuruckgegebenen Dateideskriptor werden dazu fuhren, dass der aufrufende Prozess warten muss. Beachten Sie, dass das Setzen dieses Schalters keine Wirkung auf die Aktion von poll(2), select(2), epoll(7) und ahnlichen Funktionen hat, da deren Schnittstellen den Aufrufenden lediglich daruber informieren, ob ein Dateideskriptor >>bereit<< ist, was bedeutet, dass eine auf dem Datei-Deskriptor durchgefuhrte E/A-Aktion mit dem O_NONBLOCK-Schalter clear nicht blockieren wurde. Beachten Sie, dass dieser Schalter fur regulare Dateien und Blockgerate keinen Effekt hat. Dies bedeutet, E/A-Aktionen werden (kurz) blockieren, wenn eine Gerateaktivitat benotigt wird, unabhangig davon, ob O_NONBLOCK gesetzt ist. Da die Semantik von O_NONBLOCK irgendwann einmal implementiert werden konnte, sollten Anwendungen nicht vom blockierenden Verhalten bei regularen Dateien und Blockgeraten bei der Angabe dieses Schalters abhangen. Fur die Handhabung von FIFOs (benannten Pipes), siehe auch fifo(7). Fur eine Diskussion des Effekts von O_NONBLOCK im Zusammenhang mit verpflichtenden Sperren und mit Datei-Ausleihen, siehe fcntl(2). O_PATH (seit Linux 2.6.39) Erhalt einen Dateideskriptor, der fur zwei Zwecke eingesetzt werden kann: um den Ort im Dateisystembaum anzuzeigen und um Aktionen durchzufuhren, die rein auf der Dateideskriptorebene agieren. Die Datei selbst wird nicht geoffnet und andere Dateiaktionen (z.B. read(2), write(2), fchmod(2), fchown(2), fgetxattr(2), ioctl(2), mmap(2)) schlagen mit dem Fehler EBADF fehl. Die folgenden Aktionen konnen mit dem entstandenen Dateideskriptor durchgefuhrt werden: o close(2). o fchdir(2), falls der Dateideskriptor auf ein Verzeichnis verweist (seit Linux 3.5). o fstat(2) (seit Linux 3.6). o fstatfs(2) (seit Linux 3.12). o Duplizieren des Dateideskriptors (dup(2), fcntl(2) F_DUPFD, usw.). o Ermitteln und Setzen von Dateideskriptorenschaltern (fcntl(2) F_GETFD und F_SETFD). o Ermitteln von offenen Dateistatusschaltern mittels der Aktion F_GETFL von fcntl(2): Die zuruckgelieferten Schalter werden das Bit O_PATH enthalten. o Ubergabe des Dateideskriptors als Argument Verzdd von openat() und den anderen >>*at()<<-Systemaufrufen. Dazu gehort linkat(2) mit AT_EMPTY_PATH (oder mittels AT_SYMLINK_FOLLOW von Procfs), selbst falls die Datei kein Verzeichnis ist. o Ubergabe des Dateideskriptors an einen anderen Prozess mittels UNIX-Domain-Sockets (siehe SCM_RIGHTS in unix(7)). Wenn O_PATH in Schalter angegeben ist, werden die von O_CLOEXEC, O_DIRECTORY und O_NOFOLLOW verschiedenen Schalter-Bits ignoriert. Offnen einer Datei oder eines Verzeichnisses mit dem Schalter O_PATH benotigt keine Rechte an dem Objekt selber (allerdings benotigt es Ausfuhrrechte auf den Verzeichnissen im Pfadprafix). Abhangig von nachfolgenden Aktionen kann eine Uberprufung auf geeignete Dateiberechtigungen durchgefuhrt werden (z.B. benotigt fchdir(2) Ausfuhrrechte auf das durch sein Dateideskriptorargument referenzierte Verzeichnis). Im Gegensatz dazu benotigt das Erlangen einer Referenz auf ein Dateisystemobjekt durch Offen mit dem Schalter O_RDONLY, dass der Aufrufende Leseberechtigungen am Objekt hat, selbst wenn nachfolgende Aktionen (z.B. fchdir(2), fstat(2)) keine Leseberechtigungen am Objekt benotigen. Falls Pfadname ein symbolischer Link ist und auch der Schalter O_NOFOLLOW angegeben ist, dann liefert der Aufruf einen Dateideskriptor zuruck, der sich auf den symbolischen Link bezieht. Dieser Dateideskriptor kann als Argument Verzdd 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. Falls sich Pfadname auf einen Selbsteinhangepunkt bezieht, der noch nicht ausgelost wurde, so dass dort noch kein Dateisystem eingehangt ist, dann wird der Aufruf einen Dateideskriptor zuruckliefern, der sich auf das Selbsteinhangeverzeichnis bezieht, ohne das Einhangen auszulosen. fstatfs(2) kann dann dazu verwandt werden, zu bestimmen, ob es sich tatsachlich um ein unausgelosten Selbsteinhangepunkt handelt (.f_type == AUTOFS_SUPER_MAGIC). Eine Einsatz von O_PATH fur regulare Dateien ist die Bereitstellung des Aquivalents der Funktionalitat O_EXEC von POSIX.1. Dies erlaubt es, eine Datei zu offen, fur die Ausfuhr- aber keine Leserechte vorliegen, und dann diese Datei mittels Schritten der folgenden Art auszufuhren: char buf[PATH_MAX]; fd = open("ein_Programm", O_PATH); snprintf(buf, PATH_MAX, "/proc/self/fd/%d", fd); execl(buf, "ein_Programm", (char *) NULL); Ein O_PATH-Dateideskriptor kann auch an das Argument von fexecve(3) weitergegeben werden. O_SYNC Schreibaktionen auf dieser Datei werden entsprechend den Anforderungen der synchronisierten E/A-Datei-Integritatsvervollstandigung vervollstandigt (in Kontrast zu der durch O_DSYNC bereitgestellten synchronisierten E/A-Datei-Integritatsvervollstandigung). Zum Zeitpunkt, zu dem write(2) (und ahnliche) zuruckkehrt, wurden die Ausgabedaten und zugehorigen Dateimetadaten bereits an die darunterliegende Hardware ubergeben (d.h. als ob jeder write(2) von einem Aufruf von fsync(2) gefolgt worden ware.) Siehe ANMERKUNGEN unten. O_TMPFILE (seit Linux 3.11) Erstellt eine unbenannte temporare normale Datei. Das Argument Pfadname gibt ein Verzeichnis an; 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 temporare Datei in das Dateisystem zu linken, womit diese permanent wird, unter Verwendung von Code wie dem folgenden: char path[PATH_MAX]; fd = open("/Pfad/zum/Verzeichnis", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); /* Datei-E/A auf >>fd<< */ linkat(fd, "", AT_FDCWD, "/Pfad/zur/Datei", AT_EMPTY_PATH); /* Falls der Aufrufende nicht uber die Capability CAP_DAC_READ_SEARCH verfugt (die zur Verwendung von AT_EMPTY_PATH mit linkat(2)) erforderlich ist) und ein proc(5)-Dateisystem eingehangt ist, kann der obige Aufruf von linkat(2) wie folgt ersetzt werden: 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 Modus 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 fur O_TMPFILE: o Verbesserte Funktionalitat von tmpfile(3): Ressourcen-Wettstreit-freie Erstellung temporarer Dateien die (1) automatisch geloscht werden, wenn sie geschlossen werden; die (2) niemals mittels irgend eines Dateinamens erreicht werden konnen; die (3) nicht Subjekt eines Symlink-Angriffs sind und die (4) nicht vom Aufrufenden verlangen, sich eindeutige Namen auszudenken. o Erstellen einer Datei, die ursprunglich unsichtbar ist, die dann mit den Daten gefullt und angepasst wird, um die korrekten Dateisystemattribute zu erhalten ((fchown(2), fchmod(2), fsetxattr(2) usw.), bevor sie atomar in das Dateisystem in einer vollstandigen Form gelinkt wird (mittels linkat(2) wie oben beschrieben). O_TMPFILE benotigt die Unterstutzung des zugrundeliegenden Dateisystems. Nur eine Teilmenge der Linux-Dateisysteme unterstutzt dies. In der anfanglichen Implementierung wurde die Unterstutzung fur die Dateisysteme Ext2, Ext3, Ext4, UDF, Minix und Tmpfs bereitgestellt. Die Unterstutzung fur weitere Dateisysteme wurde spater wie folgt hinzugefugt: 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 regulare Datei ist und der Zugriffsmodus Schreiben erlaubt (d.h. O_RDWR oder O_WRONLY ist), dann wird sie auf die Lange 0 abgeschnitten. Falls die Datei ein FIFO oder Terminalgerat ist, dann wird der Schalter O_TRUNC ignoriert. Andernfalls ist die Auswirkung von O_TRUNC nicht festgelegt. creat() Ein Aufruf von creat() is aquivalent zum Aufruf von open() mit Schalter identisch zu O_CREAT|O_WRONLY|O_TRUNC. openat() Der Systemaufruf openat() arbeitet genau wie open(), ausser den hier beschriebenen Unterschieden. Das Verzdd-Argument wird in Verbindung mit dem Pfadname-Argument wie folgt verwendet: o Falls der in Pfadname ubergebene Pfadname absolut ist, wird Verzdd ignoriert. o Falls der angegebene Pfadname relativ ist und Verzdd den speziellen Wert AT_FDCWD enthalt, dann wird Pfadname relativ zum aktuellen Arbeitsverzeichnis des aufrufenden Prozesses interpretiert (wie open()). o Falls der in Pfadname angegebene Pfadname relativ ist, dann wird er relativ zu dem Verzeichnis interpretiert, auf das der Dateideskriptor Verzdd verweist (statt relativ zu dem aktuellen Arbeitsverzeichnis des aufrufenden Prozesses, wie es bei open() fur einen relativen Pfadnamen erfolgt). In diesem Fall muss Verzdd ein Verzeichnis sein, das zum Lesen geoffnet wurde, oder den Schalter O_PATH vewenden. Falls der angegebene Pfadname relativ und Verzdd kein gultiger Dateideskriptor ist, wird ein Fehler (EBADF) ausgegeben. (Die Angabe einer ungultigen Dateideskriptornummer in Verzdd kann dazu verwendet werden, um sicherzustellen, dass der Pfadname absolut ist.) openat2(2) Der Systemaufruf openat2(2) ist eine Erweiterung von openat() und stellt eine Obermenge der Funtionalitaten von openat() zur Verfugung. Er ist separat in openat2(2) dokumentiert. RUCKGABEWERT open(), openat() und creat() liefern bei Erfolg den neuen Dateideskriptor zuruck (eine nicht negative Ganzzahl) oder -1, falls ein Fehler auftrat (in diesem Fall wird errno gesetzt, um den Fehler anzuzeigen). FEHLER open(), openat() und creat() konnen mit den folgenden Fehlern fehlschlagen: EACCES Der angeforderte Zugriff auf die Datei ist nicht erlaubt oder die Suchberechtigung ist fur eines der Verzeichnisse im Pfadanteil von Pfadname verweigert oder die Datei existierte noch nicht oder Schreibzugriff auf das Elternverzeichnis ist nicht erlaubt. (Siehe auch path_resolution(7).) EACCES Ist O_CREAT angegeben, dann ist der protected_fifos- oder protected_regular-Sysctl aktiviert, die Datei existiert bereits und ist ein FIFO oder eine regulare Datei, der Eigentumer der Datei ist weder der aktuelle Benutzer noch der Eigentumer des enthaltenden Verzeichnisses und das enthaltende Verzeichnis ist sowohl durch alle als auch durch die Gruppe schreibbar und >>sticky<<. Fur Details siehe die Beschreibung von /proc/sys/fs/protected_fifos und /proc/sys/fs/protected_regular in proc(5). EBADF (openat()) Der Pfadname ist relativ, aber Verzdd ist weder AT_FDCWD noch ein gultiger Dateideskriptor. EBUSY O_EXCL wurde in Schalter angegeben und Pfadname bezieht sich auf ein blockorientiertes Gerat, das vom System verwendet wird (zum Beispiel, wenn es eingehangt ist). EDQUOT Wo O_CREAT angegeben ist existiert die Datei nicht und das Kontingent des Benutzers an Plattenblocken oder Inodes auf dem Dateisystem ist erschopft. EEXIST Pfadname existiert bereits und O_CREAT und O_EXCL wurden verwandt. EFAULT Pfadname zeigt aus dem fur Sie zuganglichen Adressraum heraus. EFBIG siehe EOVERFLOW EINTR Wahrend der Aufruf wartet, bis ein langsames Gerat vollstandig geoffnet ist (z.B. ein FIFO, siehe fifo(7)), wurde er von einem Signal-Handler unterbrochen, siehe signal(7). EINVAL Das Dateisystem unterstutzt den Schalter O_DIRECT nicht. Lesen Sie ANMERKUNGEN fur weitere Informationen. EINVAL Unzulassiger Wert in flags. EINVAL O_TMPFILE wurde in Schalter angegeben, aber weder O_WRONLY noch O_RDWR wurden angegeben. EINVAL O_CREAT wurde in Schalter angegeben und die abschliessende Komponente (>>basename<<) des Pfadname der neuen Datei ist ungultig (d.h. sie enthalt im unterliegenden Dateisystem nicht erlaubte Zeichen). EINVAL Die abschliessende Komponente (>>basename<<) des Pfadnames ist ungultig (d.h. sie enthalt im unterliegenden Dateisystem nicht erlaubte Zeichen). EISDIR Pfadname bezieht sich auf ein Verzeichnis und der Zugriff beinhaltete Schreiben (d.h. O_WRONLY oder O_RDWR ist gesetzt). EISDIR Pfadname bezieht sich auf ein existierendes Verzeichnis, O_TMPFILE und entweder O_WRONLY oder O_RDWR wurde in Schalter angegeben, aber diese Kernelversion stellt die Funktionalitat O_TMPFILE nicht zur Verfugung. ELOOP Bei der Auflosung von Pfadname wurden zu viele symbolische Links gefunden. ELOOP Pfadname war ein symbolischer Link und Schalter 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 Pfadname war zu lang. ENFILE Die systemweite Beschrankung fur die Gesamtzahl offener Dateien wurde erreicht. ENODEV Pfadname bezieht sich auf eine Gerate-Spezialdatei und kein entsprechendes Gerat existiert. (Dies ist ein Fehler im Linux-Kernel; in dieser Situation muss ENXIO zuruckgeliefert werden.) ENOENT O_CREAT ist nicht gesetzt und die angegebene Datei existiert nicht. ENOENT Eine Verzeichniskomponente von Pfadname existiert nicht oder ist ein toter symbolischer Link. ENOENT Pfadname bezieht sich auf ein nicht existierendes Verzeichnis, O_TMPFILE und entweder O_WRONLY oder O_RDWR wurde in Schalter angegeben, aber diese Kernelversion stellt die Funktionalitat O_TMPFILE nicht zur Verfugung. ENOMEM Die benannte Datei ist ein FIFO, aber der Speicher fur den FIFO-Puffer kann nicht bereitgestellt werden, da die benutzerbezogene harte Grenze bezuglich Speicherzuweisung fur Pipes erreicht wurde und der Aufrufende keine Privilegien hat; siehe pipe(7). ENOMEM Es war nicht genugend Kernelspeicher verfugbar. ENOSPC Pfadname sollte erstellt werden, aber das Gerat, das Pfadname enthalt, hat fur die neue Datei keinen Platz. ENOTDIR Eine als Verzeichnis verwandte Komponente in Pfadname ist tatsachlich kein Verzeichnis oder O_DIRECTORY wurde angegeben, aber Pfadname war kein Verzeichnis. ENOTDIR (openat()) Pfadname ist ein relativer Pfadname und Verzdd ist ein Dateideskriptor, der sich auf eine Datei statt auf ein Verzeichnis bezieht. 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 Gerate-Spezialdatei und kein entsprechendes Gerat existiert. ENXIO Die Datei ist ein UNIX Domain Socket. EOPNOTSUPP Das Dateisystem, das Pfadname enthalt, unterstutzt O_TMPFILE nicht. EOVERFLOW Pfadname bezieht sich auf eine normale Datei, die zu gross zum Offnen ist. Das normale Szenario ist, dass eine auf einer 32-Bit-Plattform ohne -D_FILE_OFFSET_BITS=64 ubersetzte Anwendung versuchte, eine Datei zu offnen, deren Grosse (1<<31)-1 byte uberschritt; siehe auch O_LARGEFILE weiter oben. Dies ist der durch POSIX.1 festgelegte Fehler; in Versionen vor 2.6.24 gab Linux in diesem Fall den Fehler EFBIG zuruck. EPERM Der Schalter O_NOATIME war angegeben, aber die effektive Benutzerkennung des Aufrufenden passte nicht auf den Eigentumer der Datei und der Aufrufende war nicht privilegiert. EPERM Die Aktion wurde durch eine Dateiversiegelung verhindert; siehe fcntl(2). EROFS Pfadname bezieht sich auf eine Datei auf einem schreibgeschutzten Dateisystem, und Schreibzugriff wurde angefordert. ETXTBSY Pfadname bezieht sich auf ein ausfuhrbares Abbild, das derzeit ausgefuhrt wird und Schreibzugriff wurde erbeten. ETXTBSY Pfadname bezieht sich auf eine Datei, die derzeit als Auslagerungsdatei verwandt wird und O_TRUNC wurde festgelegt. ETXTBSY Pfadname bezieht sich auf eine Datei, die derzeit vom Kernel gelesen wird (z.B. fur das Laden von Modulen/Firmware) und Schreibzugriff wurde erbeten. EWOULDBLOCK Der Schalter O_NONBLOCK wurde angegeben und eine inkompatible Ausleihe wurde auf der Datei gehalten (siehe fcntl(2)). VERSIONEN Der (undefinierte) Effekt von O_RDONLY | O_TRUNC unterscheidet sich in vielen Implementierungen. Auf vielen Systemen wird die Datei tatsachlich abgeschnitten. 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() fur die Steuerung des Verhaltens. Unabhangig davon, ob eine Implementierung diese Option unterstutzt muss sie mindestens die Verwendung von O_SYNC fur regulare Dateien unterstutzen. 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_RSYNC wird auf HP PA-RISC in der Linux-Header-Datei definiert, aber nicht benutzt.) O_SYNC stellt synchronisierte E/A-Datei-Integritatsvervollstandigung bereit. Das bedeutet, Schreibaktionen schieben ihre Daten und zugehorigen Metadaten an die darunterliegende Hardware. O_DSYNC stellt synchronisierte E/A-Daten-Integritatsvervollstandigung bereit. Das bedeutet, Schreibaktionen schieben ihre Daten an die darunterliegende Hardware, aber schieben nur Metadatenaktualisierungen, die benotigt werden, um folgende Leseaktionen erfolgreich abzuschliessen. Datenintegritatsvervollstandigung kann die Anzahl der Aktionen reduzieren, die fur Anwendungen notwendig werden, die keine Garantien fur die Dateiintegritatsvervollstandigung benotigen. Um den Unterschied zwischen den zwei Arten von Vervollstandigung zu verstehen, betrachen Sie zwei verschiedene Dateimetadaten: den Zeitstempel der letzten Anderung (st_mtime) und die Dateilange. Alle Schreibaktionen aktualisieren den Zeitstempel der letzten Dateianderung, aber nur Schreibaktionen, die Daten am Ende der Datei hinzufugen, mussen die Dateilange andern. Der Zeitstempel der letzten Anderung wird nicht benotigt, um sicherzustellen, dass eine Leseaktion erfolgreich abgeschlossen werden kann, aber die Dateilange wird dafur benotigt. Daher wurde O_DSYNC nur garantieren, dass Aktualisierungen der Dateilangen-Metadaten rausgeschoben werden (wahrend O_SYNC immer auch das Metadatum des Zeitstempels der letzten Anderung rausschieben wurde). Vor Linux 2.6.33 implementierte Linux nur den Schalter O_SYNC fur open(). Als dieser Schalter spezifiziert wurde, stellten die meisten Dateisysteme das Aquivalent von synchronisierter E/A-Daten-Integritatsvervollstandigung bereit (d.h. O_SYNC war tatsachlich als Aquivalent von O_DSYNC implementiert). Seit Linux 2.6.33 wird korrekte Unterstutzung fur O_SYNC bereitgestellt. Um Ruckwartskompatibilitat 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 enthalt. Das stellt sicher, dass Anwendungen, die gegen neue Header ubersetzt wurden, mindestens die Semantik von O_DSYNC auf Linux vor 2.6.33 erhalten. Unterschiede C-Bibliothek/Kernel Seit Version 2.26 setzt die Glibc-Wrapper-Funktion fur open() den Systemaufruf openat() statt des Systemaufrufs open() des Kernels ein. Fur bestimmte Architekturen stimmt dies auch fur Glibc-Versionen vor 2.26. STANDARDS open() creat() openat() POSIX.1-2008. openat2(2) Linux. Die Schalter O_DIRECT, O_NOATIME, O_PATH und O_TMPFILE sind Linux-spezifisch. Sie mussen _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 grosser als oder identisch zu 200809L definiert wird oder durch _XOPEN_SOURCE mit einem Wert grosser als oder identisch zu 700. In Glibc 2.11 und alter kann die Definition uber die Definition von _GNU_SOURCE erhalten werden. GESCHICHTE open() creat() SVr4, 4.3BSD, POSIX.1-2001. openat() POSIX.1-2008. Linux 2.6.16, Glibc 2.4. ANMERKUNGEN Unter Linux wird der Schalter O_NONBLOCK manchmal in Fallen benutzt, in denen die Datei geoffnet werden soll, ohne aber notwendigerweise zu lesen oder zu schreiben. Beispielsweise kann dies dazu verwandt werden, ein Gerat zu offnen, um einen Dateideskriptor fur ioctl(2) zu erhalten. Beachten Sie, dass open() Spezial-Geratedateien offnen 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 Statusanderung und Zeit der letzten Anderung, 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 geandert 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 uber diese Dateideskriptoren. Siehe proc(5) fur weitere Details uber beide Verzeichnisse. Die Linux-Header-Datei definiert O_ASYNC nicht, es wird stattdessen das (von BSD abgeleitete) Synonym FASYNC definiert. Offene Dateideskriptionen: Der Begriff offene Dateideskription wird von POSIX verwandt, um sich auf Eintrage in der systemweiten Tabelle der offenen Dateien zu beziehen. In anderen Zusammenhangen 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 ahnlichem) dupliziert wird, bezieht sich das Duplikat auf die gleiche offene Dateideskription wie der ursprungliche 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. NFS Es gibt mehrere Unglucklichkeiten im Protokoll, das NFS unterliegt, die unter anderem O_SYNC und O_NDELAY betreffen. Auf NFS-Dateisystemen mit aktivierter UID-Abbildung konnte open() einen Dateideskriptor zuruckliefern, aber read(2)-Anfragen werden beispielsweise mit EACCES verweigert. Dies erfolgt, da der Client open() durchfuhrt, indem er die Rechte pruft, aber die UID-Abbildung auf dem Server bei Lese- und Schreibanfragen erfolgt. FIFOs Offnen des Lese- oder Schreibendes eines FIFOS blockiert, bis das andere Ende auch geoffnet wurde (durch einen anderen Prozess oder Thread). Siehe fifo(7) fur weitere Details. Dateizugriffsmodus Anders als andere Werte, die in Schalter angegeben werden konnen, legen die Zugriffsmodus-Werte O_RDONLY, O_WRONLY und O_RDWR nicht individuelle Bits fest. Stattdessen definieren sie die untersten zwei Bits von Schalter 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 (binar 11) in Schalter fur folgendes: Prufe auf Lese- und Schreibberechtigung der Datei und liefere einen Dateideskriptor zuruck, der weder zum Lesen noch zum Schreiben verwandt werden kann. Dieser nicht standardisierte Zugriffsmodus wird von einigen Linux-Treibern verwandt, um einen Dateideskriptor zuruckzuliefern, der nur fur geratespezifische ioctl(2)-Aktionen benutzt werden kann. Begrundung fur 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), fspick(2), fstatat(2), futimesat(2), linkat(2), mkdirat(2), mknodat(2), mount_setattr(2), move_mount(2), name_to_handle_at(2), open_tree(2), openat2(2), readlinkat(2), renameat(2), renameat2(2), statx(2), symlinkat(2), unlinkat(2), utimensat(2), mkfifoat(3) und scandirat(3)) behandeln zwei Probleme mit der alteren Schnittstelle, die dieser voranging. Hier erfolgt die Erlauterung am openat()-Aufruf, aber der Grund ist analog fur die anderen Schnittstellen. Erstens erlaubt openat() es Anwendungen, Race-Conditions zu vermeiden, die bei der Verwendung von open() auftreten konnen, wenn Dateien geoffnet werden, die sich nicht im lokalen Verzeichnis befinden. Diese Race-Conditions entstammen der Tatsache, dass einige Komponenten des Verzeichnisprafixes, der an open() ubergeben wird, parallel zum Aufruf von open() geandert werden konnen. Nehmen Sie beispielsweise an, dass Sie die Datei dir1/dir2/xxx.dep offnen mochten, falls dir1/dir2/xxx existiert. Das Problem besteht darin, das sich zwischen der Existenzuberprufung und dem Schritt der Dateierstellung dir1 oder dir2 (die symbolischen Links sein konnen) geandert haben und auf einen anderen Ort zeigen konnen. Solche Ressourcenwettlaufe konnen vermieden werden, indem ein Dateideskriptor fur das Zielverzeichnis geoffnet wird und dann dieser Dateideskriptor als Argument Verzdd von (beispielsweise) fstatat(2) und openat() verwandt wird. Die Verwendung des Dateideskriptors Verzdd hat auch weitere Vorteile: o Der Dateideskriptor ist eine stabile Referenz zu dem Verzeichnis, selbst falls das Verzeichnis umbenannt wird. o Der offene Dateideskriptor verhindert, dass das darunterliegende Dateisystem ausgehangt wird, genauso als wenn ein Prozess sein aktuelles Arbeitsverzeichnis auf dem Dateisystem hat. Zweitens erlaubt openat() die Implementierung eines pro-Thread->>Arbeitsverzeichnisses<<, mittels von der Anwendung verwalteten Datei-Deskriptor(en). (Diese Funktionalitat kann weniger effizient auch mittels Tricks basierend auf der Verwendung von /proc/self/fd/Verzdd erreicht werden.) Das Argument Verzdd fur diese APIs kann mittels open() oder openat() zum Offnen eines Verzeichnisses erhalten werden (mit entweder dem Schalter O_RDONLY oder O_PATH). Alternativ kann ein solcher Dateideskriptor durch Anwendung von dirfd(3) auf einen mittels opendir(3) erzeugten Verzeichnisdatenstrom erhalten werden. Wird diesen APIs ein Verzdd-Argument von AT_FDCWD ubergeben oder der angegebene Pfadname ist absolut, dann handhaben sie ihr Pfadnamenargument auf die gleiche Art wie entsprechende konventionelle APIs. In diesem Fall haben allerdings mehrere der APIs das Argument Schalter, das Zugriff auf die Funktionalitat gewahrt, die mit den entsprechenden konventionellen APIs nicht verfugbar ist. O_DIRECT Der Schalter O_DIRECT konnte Ausrichtungsbeschrankungen in der Lange und Adresse der Puffer in der Anwendungsebene und dem Dateiversatz von E/As verhangen. Unter Linux variieren die Ausrichtungsbeschrankungen je nach Dateisystem und Kernelversion und konnen auch ganz fehlen. Der Umgang mit nicht ausgerichtetem O_DIRECT-E/A unterscheidet sich auch; er kann entweder mit EINVAL fehlschlagen oder auf gepufferten E/A ausweichen. Seit Linux 6.1 konnen die Unterstutzung fur O_DIRECT und Ausrichtungsbeschrankungen fur eine Datei mittels statx(2) unter Verwendung des Schalters STATX_DIOALIGN abgefragt werden. Die Unterstutzung fur STATX_DIOALIGN unterscheidet sich je nach Dateisystem; siehe statx(2). Einige Dateisysteme stellen ihre eigene Schnnittstelle zur Abfrage von O_DIRECT-Ausrichtungsbeschrankungen bereit. Wenn verfugbar, sollte STATX_DIOALIGN stattdessen verwendet werden. Falls keines der obigen verfugbar ist, dann konnen die Unterstutzung fur direkte E/A und Ausrichtungsbeschrankungen nur von bekannten Charakteristika des Dateisystems, der einzelnen Datei, des oder der zugrunde liegenden Speichergerate und der Kernelversion abgeschatzt werden. In Linux 2.4 benotigten die meisten auf Blockgeraten basierenden Dateisysteme, dass der Dateiversatz und die Lange und Speicheradresse samtlicher E/A-Segmente Vielfaches der Dateisystemblockgrosse (typischerweise 4096 byte) sind. In Linux 2.6.0 wurde dies auf die logische Blockgrosse des Blockgerates (typischerweise 512 byte) gelockert. Die logische Blockgrosse eines Blockgerates kann mit der Aktion ioctl(2) BLKSSZGET oder von der Shell mittels folgendem Befehl ermittelt werden: blockdev --getss O_DIRECT-E/As sollten niemals gleichzeitig mit dem Systemaufruf fork(2) ausgefuhrt werden, falls der Speicherpuffer ein privates Mapping ist (das heisst, jede mit dem Schalter MAP_PRIVATE von mmap(2) erzeugtes Mapping; dies beinhaltet im Heap zugewiesenen Speicher und statisch zugewiesene Puffer). Und solche E/As, ganz gleich ob uber eine asynchrone E/A-Schnittstelle oder uber einen anderen Thread im Prozess ubergeben, sollten abgeschlossen sein, bevor fork(2) aufgerufen wird. Tun Sie dies nicht, kann Beschadigung von Daten und undefiniertes Verhalten in Eltern- und Kindprozessen die Folge sein. Diese Einschrankung gilt nicht, wenn der Speicherpuffer fur die O_DIRECT-E/As mittels shmat(2) oder mmap(2) mit dem Schalter MAP_SHARED erzeugt wurde. Ausserdem gilt die Einschrankung nicht, wenn der Speicherpuffer mit madvise(2) als MADV_DONTFORK deklariert wurde, was sicherstellt, dass es nach dem Aufruf von fork(2) fur den Kindprozess nicht verfugbar ist. Der Schalter O_DIRECT wurde in SGI IRIX eingefuhrt, wo er Ausrichtungsbeschrankungen hat, die denen von Linux 2.4 ahnlich sind. IRIX hat ausserdem einen fcntl(2)-Aufruf, um geeignete Ausrichtungen und Grossen abzufragen. FreeBSD 4.x fuhrte einen gleichnamigen Schalter ein, jedoch ohne Ausrichtungsbeschrankungen. Die Unterstutzung fur O_DIRECT wurde unter Linux in Version 2.4.10 hinzugefugt. Altere Linux-Kernel werden diesen Schalter einfach ignorieren. Einige Dateisysteme konnten den Schalter nicht implementieren. In diesem Fall schlagt open() mit dem Fehler EINVAL fehl, falls er verwandt wird. Anwendungen sollten das Vermischen von O_DIRECT und normaler E/A auf der gleichen Datei vermeiden, insbesondere fur uberlappende Regionen in der gleichen Datei. Selbst wenn das Dateisystem die Koharenzprobleme in dieser Situation korrekt handhabt, ist der Gesamt-E/A-Durchsatz wahrscheinlich geringer, als wenn einer der beiden Modi allein verwandt worden ware. 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. Altere Kernel oder Kernel, die in bestimmter Weise konfiguriert wurden, unterstutzen diese Kombination moglicherweise nicht. Das NFS-Protokoll unterstutzt die Ubergabe des Schalters an den Server nicht, daher wird O_DIRECT-E/A den Seitenzwischenspeicher auf dem Client umgehen. Der Server konnte 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 Umstanden unzureichende Leistung erbringen, insbesondere bei kleiner E/A-Grosse. Einige Server sind moglicherweise auch so konfiguriert, dass sie ihre Clients daruber belugen, dass die E/A stabilen Speicher erreicht haben. Dies wird die Leistungseinbusse bei gleichzeitigem Risiko der Datenintegritat im Fall eines Stromausfalls verhindern. Der Linux-NFS-Client legt keine Ausrichtungsbeschrankungen bei O_DIRECT-E/A fest. In Zusammenfassung: O_DIRECT ist ein extrem leistungsfahiges Werkzeug, das mit Vorsicht verwandt werden sollte. Es wird empfohlen, dass Anwendungen die Verwendung von O_DIRECT als Leistungssteigerungsoption betrachten, die standardmassig deaktiviert ist. FEHLER Derzeit ist es nicht moglich, 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 gepruft werden, wenn versucht wird, zu bestimmen, ob der Kernel die Funktionalitat O_TMPFILE unterstutzt. Wenn sowohl O_CREAT als auch O_DIRECTORY in Schalter angegeben sind und die durch Pfadname 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), openat2(2), read(2), socket(2), stat(2), umask(2), unlink(2), write(2), fopen(3), acl(5), fifo(7), inode(7), path_resolution(7), symlink(7) UBERSETZUNG Die deutsche Ubersetzung dieser Handbuchseite wurde von Mario Blattermann , Chris Leick , Dr. Tobias Quathamer und Helge Kreutzmann erstellt. Diese Ubersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezuglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG ubernommen. Wenn Sie Fehler in der Ubersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Ubersetzer . Linux man-pages 6.06 16. Januar 2024 open(2)