OPEN(2)

名称
open - 読取りまたは書込み用にファイルをオープンする、または作成する

ライブラリ
libc

書式
<fcntl.h> int open(const char *path, int flags, ...)

解説
path によって指定されるファイルを、引数 flags によって指定されたように読取りまたは書込み (またはその両方) 用にオープンし、 そのファイル記述子を呼び出し元プロセスに返します。 ファイルが存在しない場合にはファイルを作成するように、 flags 引数で指示できます (O_CREAT フラグを指定する)。 この場合、 open() には 3 番目の引数 mode_t mode が必要であり、ファイルは chmod(2) で説明されているようにモード mode で作成され、プロセスの umask 値によって修正されます (umask(2) を参照)。

指定されたフラグは次の値の論理和 (or) で作成されます。

    O_RDONLY	読取り専用でオープン
    O_WRONLY	書込み専用でオープン
    O_RDWR		読取りと書込み用にオープン
    O_NONBLOCK	オープンするときにブロックしない
    O_APPEND	書込みのたびに末尾に追加する
    O_CREAT		ファイルが存在しない場合、作成する
    O_TRUNC		サイズを 0 に切り捨てる
    O_EXCL		作成するファイルが既に存在した場合、エラーとする
    O_SHLOCK	共有ロックを不可分に取得する
    O_EXLOCK	排他的ロックを不可分に取得する
    O_DIRECT	キャッシュの効果を無くすまたは減らす
    O_FSYNC		同期的に書き込む
    O_NOFOLLOW	シンボリックリンクを辿らない

O_APPEND を設定してファイルをオープンすると、 ファイルへの書込みはすべてファイルの末尾に追加されます。 O_TRUNC が指定されていてファイルが存在する場合、ファイルは長さ 0 に切り捨てられます。 O_EXCL が O_CREAT とともに設定されていてファイルが既に存在する場合、 open() はエラーを返します。 これを使用して、簡単な排他的アクセスロッキングメカニズムを実現できます。 O_EXCL が設定されていてパス名の最後の構成要素がシンボリックリンクの場合、 たとえシンボリックリンクが存在しない名前を指していたとしても open() は処理に失敗します。 O_NONBLOCK フラグが指定されていて open() システムコールの結果、プロセスが何らかの理由でブロックされると (たとえば、 ダイアルアップ回線でキャリアを待っている場合)、 open() は即座に戻ります。 記述子は、その後の操作のために非ブロッキングモードのままにされます。

O_FSYNC がマスクに使用された場合、すべての書込みは直ちにディスクに書き込まれ、 カーネルは書き込まれたデータをキャッシュせず、 書き込むべきすべてのデータが完了するまでは この記述子に対するすべての書込みは戻りません。

O_NOFOLLOW がマスクに使用された場合で open() に渡された対象ファイルがシンボリックリンクの場合、 open() は失敗します。

ファイルをオープンするときに、 flock(2) を使ったロックを得るには、共有ロックについては O_SHLOCK 、 排他的ロックについては O_EXLOCK を設定します。 O_CREAT でファイルを作成する場合、ロック要求が失敗すること はありません (ただし、下層にあるファイルシステムが ロックをサポートしている場合に限ります)。

読み書きにおけるキャッシュの効果を最小化もしくは無くすために O_DIRECT を使用可能です。 システムは、読み書きするデータのキャッシングを避けようとします。 データのキャッシングが避けられない場合、 データのキャッシュに対する影響を最小化します。 注意せずに使用すると、本フラグは劇的に性能を劣化させます。

正常に完了すると、 open() は、ファイル記述子を示す負でない整数を返します。 処理に失敗すると -1 を返します。 ファイル内の現在の位置をマークする ファイルポインタはファイルの先頭に設定されます。

新しいファイルが作成される場合、そのグループは ファイルが含まれるディレクトリのグループに設定されます。

新しい記述子は execve(2) システムコールを通じてオープンされたままであるように設定されます。 close(2) と fcntl(2) を参照してください。

システムには、1 つのプロセスによって同時にオープンできる ファイル記述子数に制限があります。 getdtablesize(2) システムコールは現在のシステム制限を返します。

戻り値
正常に完了すると、 open() はファイル記述子である負でない整数を返します。 処理に失敗すると -1 が返され、エラーを示すために errno が設定されます。

エラー
指定のファイルは次の場合を除いてオープンされます:

[ENOTDIR]
    パスの構成要素中にディレクトリ以外のものが含まれています。

[ENAMETOOLONG]
    パス名の構成要素が 255 文字を越えているか、 またはパス名全体が 1023 文字を越えています。

[ENOENT]
    指定されたファイルが存在せず、 O_CREAT も設定されていません。

[ENOENT]
    存在しなければならないパス名の構成要素が存在しません。

[EACCES]
    指定されたパスには、検索が許可されていないディレクトリが含まれています。

[EACCES]
    要求されたパーミッション (読取りまたは書込み用、または両方) が 指定のフラグに拒否されています。

[EACCES]
    O_CREAT が指定されていて、ファイルが存在せず、かつファイルを作成する ディレクトリに書込み許可がありません。

[ELOOP]
    パス名を変換するときに検出されたシンボリックリンクが多すぎます。

[EISDIR]
    指定のファイルがディレクトリであり、これを書込み用に オープンするように引数が指定されています。

[EROFS]
    指定されたファイルは読取り専用ファイルシステム上にあり、 そのファイルを修正しようとしています。

[EMFILE]
    プロセスは、すでにオープンできるファイル記述子に関する制限に達しています。

[ENFILE]
    システムファイルテーブルが満杯です。

[EMLINK]
    O_NOFOLLOW が指定され、対象がシンボリックリンクです。

[ENXIO]
    指定のファイルはキャラクタ型特殊ファイルまたはブロック型特殊ファイルであり、 この特殊ファイルに結び付けられたデバイスは存在していません。

[ENXIO]
    指定されたファイルは FIFO パイプで、どのプロセスからも 読取り用にオープンされていないにも関らず、 これを書込み用にオープンしようとしました。

[EINTR]
    open() 操作がシグナルによって割り込みされました。

[EOPNOTSUPP]
    O_SHLOCK または O_EXLOCK が指定されましたが、下層となっているファイルシステムは ロックをサポートしていません。

[EOPNOTSUPP]
    指定されたファイルはスペシャルファイルであり、 それにアクセスすることをサポートしていない ファイルシステム (例えば NFS) を通してマウントされています。

[EWOULDBLOCK]
    O_NONBLOCK と、 O_SHLOCK か O_EXLOCK のどちらかが指定されましたが、ファイルはロックされています。

[ENOSPC]
    O_CREAT が指定されていて、ファイルが存在せず、新しいファイル用のエントリを 配置中のディレクトリは、そのディレクトリを含むファイルシステムに 空間が残っていないため拡張できません。

[ENOSPC]
    O_CREAT が指定されていて、ファイルが存在せず、かつファイルが作成中の ファイルシステム上に未使用の inode がありません。

[EDQUOT]
    O_CREAT が指定されていて、ファイルが存在せず、かつ新しいファイル用の エントリを配置中のディレクトリは、そのディレクトリを含む ファイルシステム上でディスクブロックの ユーザのクォータが枯渇したために拡張できません。

[EDQUOT]
    O_CREAT が指定されていて、ファイルが存在せず、かつファイルを作成中の ファイルシステム上で inode のユーザのクォータが枯渇しています。

[EIO]
    ディレクトリエントリを作成中、または O_CREAT 用の inode を割り当て中に入出力エラーが発生しました。

[ETXTBSY]
    ファイルは純粋な手続き (共有テキスト) ファイルで、 open() システムコールが書込みアクセスを要求しましたが、ファイルは実行中です。

[EFAULT]
    path 引数は、プロセスに割り当てられたアドレス空間の範囲外を指しています。

[EEXIST]
    O_CREAT と O_EXCL が指定されていて、ファイルが存在します。

[EOPNOTSUPP]
    ソケットをオープンしようとしました (現時点では実装されていません)。

[EINVAL]
    O_RDONLY, O_WRONLY および O_RDWR の不正な組合わせで記述子をオープンしようとしました。

関連項目
chmod(2), close(2), dup(2), getdtablesize(2), lseek(2), read(2), umask(2), write(2), fopen(3)

歴史
open() 関数は AT&T UNIX で登場しました。