2017-08-22 1 views
5

the related standard documentationを注意深く読んでも、O_CREAT|O_DIRECTORYを含むopenシステムコールが呼び出されたときに、POSIX準拠のシステムで期待される動作がわかりません。open(name、O_CREAT | O_DIRECTORY、mode)の期待される動作は何ですか?

標準は、要求されたアクセスモードはどちらもO_WRONLYもO_RDWRで、結果は不定である

O_CREATとO_DIRECTORYが設定されている場合ことを指定します。

ただし、(O_CREAT|O_DIRECTORY|O_WRONLY)(O_CREAT|O_DIRECTORY|O_RDWR)のどちらのシステムの動作も指定していません。確かに(私が理解できる限り)、EISDIRの動作は、の既存のディレクトリにのみ適用されます。 O_CREATEに関連するセクションで

は、標準の名前のファイルが存在しない場合、ことを指定し、

O_DIRECTORY ファイルは通常のファイルとして作成されなければならないが設定されていない場合。 [...]

が、再び、それはO_DIRECTORYがあまりにも設定されている場合は何が起こるかを指定しません。

NetBSD(POSIX準拠についてはよく知られています)とLinux(実際にはPOSIXではないにしても広く使われているシステムです)のマニュアルページを見てきましたが、何も分かりません。

両方のフラグの使用が指定されていないと言っても間違いありませんか? もしそうなら、最も一般的な行動は何ですか?

open(name, O_CREAT|O_DIRECTORY, mode)は、POSIX準拠のOSでmkdirに相当しますか?

+0

オープンフラグ(または、おそらく 'O_EXEC'または' O_SEARCH')に 'O_RDONLY'、' O_WRONLY'、および 'O_RDWR'のいずれかを含める必要があることに注意してください。歴史的には、それらを省略すると 'O_RDONLY'(通常は0、' O_WRONLY'は通常1、 'O_RDWR'は通常2)を指定するのと同じですが、これらはビット値ではありません。 (POSIXで指定された 'O_EXEC'と' O_SEARCH'オプションは人生を複雑にしますが、Linux(Ubuntu 16.04 LTS)もmacOS 10.12.6もどちらもサポートしていません)。あなたの 'open()'コマンドは私が厳密にルールを遵守していなかったことを意識せずに。 –

+0

POSIX仕様の['open()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html)の根拠節には、次のように書いてあります。さらに、 'open() '関数は、O_DIRECTORYフラグがセットされていれば非ディレクトリを開くことを拒否します。これにより、特権付きアプリケーションの実行中に機密ファイル(デバイスやFIFOなど)にハードリンクを置き換えることで、ユーザーがシステムを侵害する可能性のある競合状態が回避されます。読み取りアクセスの場合でもファイルを開くと、 ._ –

答えて

2

のNetBSD自体はvn_openに次の内容が含まれます。

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

ので、これらの2との任意の組み合わせがまっすぐに拒否されます。 Linuxでの

それはもう少し毛深いのですが、どんな些細なテストは、ディレクトリがいずれかに作成されていないことを示しますが、あなたは私も決して終わらないのFreeBSDを、確認キック用のファイル

で終わることができます最初の場所にO_DIRECTORYで何かを作成すること

あなたが探しているものがfdを返すmkdirなら、私は何も並べ替えがありません。 O_DIRECTORYでmkdirされたものを安全に開くことができるはずです。

3

O_DIRECTORYは、あなたが誤解していると思います。 ディレクトリを作成するのではなく、open(2)によって開かれた "ファイル"がディレクトリであることを確認することです。

O_DIRECTORY
パスは、非ディレクトリファイルに解決に失敗し、[ENOTDIR]をerrnoに設定した場合。

正確には、POSIXがそれを文書化しています(上記参照)。

それはどちらを使用してシステムの動作を指定していませんが(O_CREAT | O_DIRECTORY | O_WRONLY)も(O_CREAT | O_DIRECTORY | O_RDWR)を

O_CREAT|O_DIRECTORY|O_WRONLYO_CREAT|O_DIRECTORY|O_RDWRの行動はO_CREAT|O_WRONLYと同等ですO_CREAT|O_RDWR はそれぞれのパス名(open(2)の最初の引数)がディレクトリです。 O_DIRECTORYの存在は、開かれているファイルを確実にすることです。 はディレクトリです。何も影響しません。

両方のフラグの使用が指定されていないと言うのは間違いありませんか?もしそうなら、最も一般的な行動は何ですか?

それはO_CREAT | O_DIRECTORYが指定されていない特定の組み合わせの動作を意味します。個々のフラグを使用することを意味するものではありません。 (他のフラグの有無にかかわらず)は指定されていません。

POSIX準拠のOSでmkdirと同等の名前(O_CREAT | O_DIRECTORY、mode)を開いていますか?

全くありません。だからこそ、が指定されていませんとなってしまいました。 Linuxでは、it's definitely not - 通常のファイルが作成されます。

O_CREATとO_DIRECTORYの両方がflagsに指定され、パス名で指定されたファイル が存在しない、オープン()定期 ファイルを作成します(つまり、O_DIRECTORYを無視されます)。

ディレクトリを作成するには、mkdir(2)を使用します。

1

これまでの回答は正しくありません。実装はO_CREAT|O_DIRECTORY|O_WRONLYまたはO_CREAT|O_DIRECTORY|O_RDWRでディレクトリ作成を自由にサポートしますが、必須ではありません。 あなたがbug tracker of the Austin groupで見ることができるように、これは、2014年に明らかになった。

open("/path/to/existing/directory", O_CREAT)EISDIRで失敗するはずですが、実装は、作成および拡張

としてopen("/path/to/directory", O_CREAT|O_DIRECTORY)経由でディレクトリを開くサポートするために許可する必要があります次のような根拠があります。

open()がで呼び出されたときの動作は指定されていません(またはO_CREAT|O_SEARCH)を既存のディレクトリに追加します。さらに、一部のシステムでは、open()機能を使用してディレクトリを作成できます。これは許可されている必要がありますが、必須ではありません。

O_CREATとO_DIRECTORYを設定し、要求されたアクセスモードはどちらもO_WRONLYもO_RDWRでいる場合は、標準

current versionから引用した文言は、結果は不定です。

は、それを可能にするために行われた変更の1つでした。

これを許可する理由の1つは、Rich Felknerで説明されているように、ディレクトリをアトミックに作成して開くためのインターフェイスを提供するということです。

しかし、そこにPOSIXの実装が実際にopenを介してディレクトリの作成を提供するかどうかわかりません。

関連する問題