2017-08-22 5 views
5

Trotz sorgfältiger Lese von the related standard documentation kann ich nicht verstehen, was das erwartete Verhalten in POSIX-konformen Systemen ist, wenn ein open-Systemaufruf mit Flags einschließlich O_CREAT|O_DIRECTORY aufgerufen wird.Was ist das erwartete Verhalten von open (Name, O_CREAT | O_DIRECTORY, Modus)?

Der Standard legt fest, dass

Wenn O_CREAT und O_DIRECTORY gesetzt und der angeforderten Zugriffsmodus weder O_WRONLY ist noch O_RDWR, das Ergebnis ist nicht spezifiziert.

Es gibt jedoch weder das Verhalten des Systems mit (O_CREAT|O_DIRECTORY|O_WRONLY) noch (O_CREAT|O_DIRECTORY|O_RDWR). In der Tat (soweit ich das verstehen kann) gilt das Verhalten auf EISDIR nur für bestehende Verzeichnisse.

Im Abschnitt zu O_CREATE Zusammenhang gibt die Norm, dass, wenn die angegebene Datei nicht existiert,

wenn O_DIRECTORY nicht die Datei als reguläre Datei erstellt wird gesetzt wird; [...]

aber es wird auch nicht angegeben, was passieren wird, wenn O_DIRECTORY auch gesetzt ist.

Ich habe die Handbücher der beiden NetBSD (die sich notorisch viel um POSIX-Compliance kümmert) und Linux (das ist ein weit verbreitetes System, obwohl nicht eigentlich ein POSIX), aber ich kann keine Klarstellung finden.

Ist es richtig zu sagen, dass die Verwendung beider Flags nicht spezifiziert ist? Und wenn ja, was ist das häufigste Verhalten?

Ist open(name, O_CREAT|O_DIRECTORY, mode) äquivalent zu mkdir auf einem POSIX-kompatiblen Betriebssystem?

+0

Beachten Sie, dass Sie eine der 'O_RDONLY',' O_WRONLY' und 'O_RDWR' in die offenen Flags (oder möglicherweise' O_EXEC' oder 'O_SEARCH') aufnehmen sollten. Historisch gesehen ist das Auslassen von diesen gleichbedeutend mit der Angabe von 'O_RDONLY' (es ist normalerweise 0;' O_WRONLY' ist normalerweise 1, und 'O_RDWR' ist normalerweise 2), aber dies sind keine Bitwerte. (Die von POSIX angegebenen 'O_EXEC'- und' O_SEARCH'-Optionen erschweren das Leben, aber weder Linux (Ubuntu 16.04 LTS) noch Mac OS 10.12.6 unterstützt beide.) Ich sehe jetzt, wo ich meinen "fehlerhaften" Code herbekomme - ich kopiere Ihr 'open()' Befehl ohne zu merken, dass ich mich nicht streng an die Regeln hielt. –

+0

Im Begründungsteil der POSIX-Spezifikation für ['open()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html) steht: _Darüber hinaus ist das 'open() 'Funktion weigert sich, Nicht-Verzeichnisse zu öffnen, wenn das O_DIRECTORY-Flag gesetzt ist. Dies vermeidet Race-Bedingungen, wodurch ein Benutzer das System kompromittieren könnte, indem er eine harte Verbindung zu einer empfindlichen Datei (z. B. einem Gerät oder einem FIFO) während der Ausführung einer privilegierten Anwendung austauscht, wobei das Öffnen einer Datei selbst für den Lesezugriff unerwünschte Nebenwirkungen haben könnte ._ –

Antwort

2

netbsd selbst enthält die folgenden in vn_open:

if ((fmode & (O_CREAT | O_DIRECTORY)) == (O_CREAT | O_DIRECTORY)) 
     return EINVAL; 

so dass jede Kombination mit diesen 2 gerade nach oben abgewiesen.

in Linux ein wenig behaarten es ist, aber jeder trivialer Test werden Ihnen zeigen, dass das Verzeichnis entweder nicht erstellt, aber Sie können auch freebsd geprüft, die nie endet

für Kicks mit einer Datei am Ende i alles mit O_DIRECTORY an erster Stelle

wenn was Sie suchen, ist ein mkdir, die Ihnen die fd zurückgibt, ich fürchte, es gibt nichts von der Sorte. Auf der anderen Seite sollten Sie in der Lage sein, mit O_DIRECTORY sicher alles zu öffnen, was Sie mkdir'ed.

3

Ich denke, Sie haben missverstanden, was O_DIRECTORY gemeint ist. Es ist nicht erstellen ein Verzeichnis, aber um sicherzustellen, dass die "Datei" von geöffnet ist ein Verzeichnis.

O_DIRECTORY
Wenn Pfad zu einer nicht-Verzeichnisdatei aufgelöst wird, fehlschlagen und errno auf [ENOTDIR].

Genau so dokumentiert POSIX es (zitiert oben).

aber es nicht das Verhalten des Systems angeben, weder mit (O_CREAT | O_DIRECTORY | O_WRONLY) noch (O_CREAT | O_DIRECTORY | O_RDWR)

Das Verhalten von O_CREAT|O_DIRECTORY|O_WRONLY und O_CREAT|O_DIRECTORY|O_RDWR entspricht O_CREAT|O_WRONLY und O_CREAT|O_RDWR bzw. Pfadname (erstes Argument zu öffnen (2)) ist ein Verzeichnis. Das Vorhandensein von O_DIRECTORY soll sicherstellen, dass die geöffnete Datei ein Verzeichnis ist - es betrifft nichts anderes.

Ist es richtig zu sagen, dass die Verwendung beider Flags nicht spezifiziert ist? Und wenn ja, was ist das häufigste Verhalten?

Es bedeutet, das Verhalten der spezifischen KombinationO_CREAT | O_DIRECTORY nicht angegeben ist; bedeutet nicht, die einzelnen Flags zu verwenden (mit oder ohne andere Flags) ist nicht angegeben.

Ist der Name (Name, O_CREAT | O_DIRECTORY, Modus) äquivalent zu mkdir auf einem POSIX-kompatiblen Betriebssystem?

Überhaupt nicht. Deshalb ist es links nicht näher. Unter Linux it's definitely not - eine reguläre Datei erstellt:

Wenn beide O_CREAT und O_DIRECTORY in Flags angegeben werden und die Datei durch Pfadnamen angegeben ist nicht vorhanden, open() wird eine regelmäßige -Datei erstellen (dh O_DIRECTORY wird ignoriert).

Um ein Verzeichnis zu erstellen, verwenden Sie mkdir(2).

1

Die Antworten sind bisher nicht korrekt. Implementierungen können die Verzeichniserstellung über O_CREAT|O_DIRECTORY|O_WRONLY oder O_CREAT|O_DIRECTORY|O_RDWR unterstützen, müssen dies aber nicht tun. Dies wurde im Jahr 2014 geklärt, wie Sie in den bug tracker of the Austin group sehen:

open("/path/to/existing/directory", O_CREAT) soll mit EISDIR scheitern, aber Implementierungen erlaubt sein soll, zu unterstützen, zu schaffen und ein Verzeichnis über open("/path/to/directory", O_CREAT|O_DIRECTORY) als Erweiterung der Öffnungs

mit folgenden Begründung:

der Standard das Verhalten nicht angeben, wenn open() mitaufgerufen(oder O_CREAT|O_SEARCH) in einem vorhandenen Verzeichnis.Darüber hinaus möchten einige Systeme die Erstellung von Verzeichnissen mithilfe der Funktion open() ermöglichen. Dies sollte eine erlaubte, aber nicht erforderliche Erweiterung sein.

Die Formulierung, die Sie aus dem current version der Standard

zitiert

Wenn O_CREAT und O_DIRECTORY eingestellt sind und die angeforderte Zugriffsmodus ist weder O_WRONLY noch O_RDWR, ist das Ergebnis nicht spezifiziert.

wurde genau eine der Änderungen vorgenommen, um es zu ermöglichen.

Einer der Gründe, dies zuzulassen, wie von Rich Felkner beschrieben, ist, dass es eine Schnittstelle zum atomaren Erstellen und Öffnen eines Verzeichnisses bereitstellen würde.

Ich weiß jedoch nicht, ob irgendeine POSIX-Implementierung tatsächlich die Verzeichniserstellung über open bereitstellt.

Verwandte Themen