Die Erklärung unter
darüber, warum openat
benötigt wird, liest teilweise:
openat () ermöglicht einer Anwendung, Race-Bedingungen zu vermeiden kann auftreten, wenn Sie open () zum Öffnen von Dateien in anderen Verzeichnissen verwenden das aktuelle Arbeitsverzeichnis Diese Rennbedingungen ergeben sich aus der Tatsache, dass eine Komponente des Verzeichnispräfixes an open () übergeben wurde könnte parallel zum Aufruf von open () geändert werden. Angenommen, für Beispiel, dass wir die Datei path / to / xxx.dep erstellen möchten, wenn die Datei Pfad / zu / xxx existiert. Das Problem ist das zwischen der Existenzprüfung und der Dateierstellungsschritt, Pfad oder zu (der möglicherweise symbolisch ist Links) könnten so modifiziert werden, dass sie auf einen anderen Ort zeigen.
Ich verstehe nicht, warum dieses Rennen ein Problem ist. Wenn eine App nach der Existenz einer Datei suchen möchte und wenn ja, erstellen Sie eine andere Datei, dann sind dies natürlich zwei Schritte, und die App sollte entweder dafür sorgen, dass nichts dazwischen kommt, oder die Konsequenzen eines Zweier akzeptieren Schrittbetrieb. Nur wenn ein einzelner Aufruf von open()
eine Race-Bedingung verursachen könnte, könnte ein anderer Syscall wie openat()
benötigt werden. Andernfalls ist dies nicht für Systemaufrufe zu lösen, aber es ist eine Verantwortung der Anwendung zu bewältigen.
Was verstehe ich hier nicht?
TL; DR
openat()
ermöglicht es Ihnen, einen gesamten Verzeichnispfad zu sperren, die Racebedingung nur einmal zu lösen und dann Dateien relativ zu diesem Pfad sicher zu öffnen, ohne sich um Race-Bedingungen kümmern zu müssen.
Details
Sie sind richtig, dass die Race-Bedingung immer noch in der Verantwortung Ihres Programms ist, zu antizipieren und zu behandeln, aber die openat()
-Funktion erlaubt Ihnen, nur einmal für mehrere Dateien zu machen. Wenn Sie mehrere Dateien innerhalb desselben Verzeichnisses öffnen möchten, können Sie dies mit individuellen Aufrufen von open()
tun, aber Sie müssen jedes Mal mit der Wettlaufbedingung rechnen. Stattdessen können Sie mit openat()
zuerst einen Dateideskriptor für das übergeordnete Verzeichnis abrufen, wodurch verhindert wird, dass andere Prozesse diesen Pfad ändern oder entfernen. Sie können jetzt openat()
verwenden, um mehrere Dateien relativ zu diesem gesperrten Pfad sicher zu öffnen, ohne sich Gedanken um die Wettkampfbedingungen machen zu müssen, die normalerweise beim Öffnen absoluter Pfade auftreten.
Anderer Anwendungsfall
Beachten Sie auch, dass die Race-Bedingung nicht unbedingt zwischen Ihren Programm-Eröffnungsdateien und anderen Programmen besteht, die Pfade ändern oder löschen - es ist auch zwischen Threads innerhalb Ihres Programms. openat()
ist nützlich, wenn Sie mit relativen Pfaden arbeiten möchten und sich in einer Multithread-Umgebung befinden. Denken Sie daran, dass wenn Sie Ihr Arbeitsverzeichnis in einem Thread ändern, es für den gesamten Prozess und seine Threads ändert.
Wenn Sie also mehrere Threads abzweigen, können sie jeweils einen Dateideskriptor für verschiedene Verzeichnisse abrufen und openat()
mit diesen Verzeichnis -Dateideskriptoren und relativen Pfaden von ihnen verwenden, um Dateien ohne Bedenken zu öffnen darüber, was die anderen Threads mit dem Arbeitsverzeichnis der gesamten Prozesse machen oder eine Last von absoluten Pfaden halten.
Dieser Anwendungsfall wird in der zweiten Anmerkung in der Manpage für openat
:
Zweitens erlaubt openat () die Implementierung eines "aktuellen Arbeitsverzeichnisses" pro Thread über Dateideskriptoren, die von der Anwendung verwaltet werden. (Diese Funktionalität kann auch durch Tricks erreicht werden, die auf der Verwendung von / proc / self / fd / dirfd basieren, aber weniger effizient.
Randnotiz
Ich möchte nicht zu tief in eine Diskussion darüber gehen, welche Verantwortlichkeiten von Systemaufrufen angenommen werden sollten, weil es subjektiv wird, aber beachte, dass openat
nicht wirklich Rennbedingungen löst - das kannst du Sie haben immer noch eine, wenn Sie versuchen, das übergeordnete Verzeichnis zu sperren, und das liegt allein in Ihrer Verantwortung. Es ist ein Werkzeug, das Ihnen hilft, Race-Bedingungen zu verhindern, nachdem Sie einmal die Auflösung erreicht haben. Ich denke, das ist ein nützlicher und vernünftiger Mechanismus, der in ein Betriebssystem als Systemaufruf integriert werden kann.
Tags und Links linux-kernel