OPEN(2) | Linux Programmer's Manual | OPEN(2) |
名前
open, creat -ファイルやデバイスのオープン、作成を行う書式
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char * pathname , int flags );
int open(const char * pathname , int flags , mode_t mode );
int creat(const char *pathname, mode_t mode);
説明
ファイルの pathname を与えると、 open() はファイルディスクリプタを返す。ファイルディスクリプタは、この後に続くシステムコール ( read(2), write(2), lseek(2), fcntl(2) など) で使用される小さな非負の整数である。このシステムコールが成功した場合に返されるファイルディスクリプタはそのプロセスがその時点でオープンしていないファイルディスクリプタのうち最小の数字のものとなる。デフォルトでは、新しいファイルディスクリプタは execve(2) を実行した後もオープンされたままとなる (つまり、 fcntl(2) に説明がある FD_CLOEXEC ファイルディスクリプタフラグは最初は無効である;後述の O_CLOEXEC フラグを使うとこのデフォルトを変更することができる)。ファイルオフセット (file offset) はファイルの先頭に設定される ( lseek(2) 参照)。
open() を呼び出すと、「オープンファイル記述」 (open file description) が作成される。ファイル記述とは、システム全体のオープン中のファイルのテーブルのエントリである。このエントリは、ファイルオフセットとファイル状態フラグ ( fcntl(2) F_SETFL 操作により変更可能) が保持する。ファイルディスクリプタはこれらのエントリの一つへの参照である。この後で pathname が削除されたり、他のファイルを参照するように変更されたりしても、この参照は影響を受けない。新しいオープンファイル記述は最初は他のどのプロセスとも共有されていないが、 fork(2) で共有が起こる場合がある。
引き数 flags には、アクセスモード O_RDONLY, O_WRONLY, O_RDWR のどれかひとつが入っていなければならない。これらはそれぞれ読み込み専用、書き込み専用、読み書き用にファイルをオープンすることを要求するものである。
さらに、 flags には、ファイル作成フラグ (file creation flag) とファイル状態フラグ (file status flag) を 0 個以上「ビット単位の OR (bitwise-or)」で指定することができる。 ファイル作成フラグ は O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TRUNC, O_TTY_INIT である。 ファイル状態フラグ は以下のリストのうち上記以外の残りのものである。二種類のフラグの違いは、ファイル状態フラグの方は fcntl(2) を使ってその内容を取得したり (場合によっては) 変更したりできる点にある。ファイル作成フラグとファイル状態フラグの全リストを以下に示す:
- O_APPEND
- ファイルを追加 (append) モードでオープンする。毎回の write(2) の前に lseek(2) を行ったかのように、ファイルポインタをファイルの最後に移動する。 NFS ファイルシステムで、 O_APPEND を使用すると、複数のプロセスがひとつのファイルに同時にデータを追加した場合、ファイルが壊れてしまうことがある。これは NFS が追加モードをサポートしていないため、クライアントのカーネル (kernel) がそれをシミュレートしなければならないのだが、競合状態を避けることはできないからである。
- O_ASYNC
- シグナル駆動 I/O (signal-driven I/O) を有効にする: このファイルディスクリプタへの入力または出力が可能になった場合に、シグナルを生成する (デフォルトは SIGIO であるが、 fcntl(2) によって変更可能である)。この機能が使用可能なのは端末、疑似端末、ソケットのみであり、 (Linux 2.6 以降では) パイプと FIFO に対しても使用できる。さらに詳しい説明は fcntl(2) を参照すること。
- O_CLOEXEC (Linux 2.6.23 以降)
- 新しいファイルディスクリプタに対して close-on-exec フラグを有効にする。このフラグを指定することで、プログラムは FD_CLOEXEC フラグをセットするための fcntl(2) F_SETFD 操作を別途呼び出す必要がなくなる。また、ある種のマルチスレッドのプログラムはこのフラグの使用は不可欠である。なぜなら、個別に FD_CLOEXEC フラグを設定する fcntl(2) F_SETFD 操作を呼び出したとしても、あるスレッドがファイルディスクリプタをオープンするのと同時に別のスレッドが fork(2) と execve(2) を実行するという競合条件を避けるのには十分ではないからである。
- O_CREAT
- ファイルが存在しなかった場合は作成 (create) する。ファイルの所有者 (ユーザー ID) は、プロセスの実効ユーザー ID に設定される。グループ所有権 (グループ ID) は、プロセスの実効グループ ID または親ディレクトリのグループ ID に設定される (これは、ファイルシステムタイプ、マウントオプション、親ディレクトリのモードに依存する。 mount(8) で説明されているマウントオプション bsdgroups と sysvgroups を参照)。
mode は新しいファイルを作成する場合に使用するアクセス許可 (permission) を指定する。 flags に O_CREAT が指定されている場合、 mode を指定しなければならない。 O_CREAT が指定されていない場合、 mode は無視される。有効なアクセス許可は、普段と同じようにプロセスの umask によって修正され、作成されたファイルの許可は (mode & ~umask) となる。このモードは、新しく作成されたファイルに対するそれ以降のアクセスにのみ適用される点に注意すること。読み取り専用のファイルを作成する open() コールであっても、読み書き可能なファイルディスクリプタを返すことがありうる。
mode のために以下のシンボル定数が提供されている :
- S_IRWXU
- 00700 ユーザー (ファイルの所有者) に読み込み、書き込み、実行の許可がある。
- S_IRUSR
- 00400 ユーザーに読み込みの許可がある。
- S_IWUSR
- 00200 ユーザーに書き込みの許可がある。
- S_IXUSR
- 00100 ユーザーに実行の許可がある。
- S_IRWXG
- 00070 グループに読み込み、書き込み、実行の許可がある。
- S_IRGRP
- 00040 グループに読み込みの許可がある。
- S_IWGRP
- 00020 グループに書き込みの許可がある。
- S_IXGRP
- 00010 グループに実行の許可がある。
- S_IRWXO
- 00007 他人 (others) に読み込み、書き込み、実行の許可がある。
- S_IROTH
- 00004 他人に読み込みの許可がある。
- S_IWOTH
- 00002 他人に書き込みの許可がある。
- S_IXOTH
- 00001 他人に実行の許可がある。
- O_DIRECT (Linux 2.4.10 以降)
-
このファイルに対する I/O のキャッシュの効果を最小化しようとする。このフラグを使うと、一般的に性能が低下する。しかしアプリケーションが独自にキャッシングを行っているような特別な場合には役に立つ。ファイルの I/O はユーザー空間バッファに対して直接行われる。
O_DIRECT フラグ自身はデータを同期で転送しようとはするが、
O_SYNC フラグのようにデータと必要なメタデータの転送が保証されるわけではない。同期 I/O を保証するためには、
O_DIRECT に加えて
O_SYNC を使用しなければならない。下記の「注意」の節の議論も参照。
- O_DIRECTORY
- pathname がディレクトリでなければオープンは失敗する。このフラグは Linux 特有であり、 opendir(3) が FIFO やテープデバイスに対してコールされた場合のサービス不能 (denial-of-service) 攻撃を避けるためにカーネル 2.1.126 で追加された。しかしこれは opendir(3) の実装以外では使用するべきではない。
- O_EXCL
-
この呼び出しでファイルが作成されることを保証する。このフラグが
O_CREAT と一緒に指定され、
pathname のファイルが既に存在した場合、
open() は失敗する。
- O_LARGEFILE
- (LFS) off_t ではサイズを表せない (だだし off64_t ではサイズを表せる)ファイルをオープン可能にする。この定義を有効にするためには、( どのヘッダファイルをインクルードするよりも前に) _LARGEFILE64_SOURCE マクロを定義しなければならない。 32 ビットシステムにおいて大きなファイルにアクセスしたい場合、 ( O_LARGEFILE を使うよりも) _FILE_OFFSET_BITS 機能検査マクロを 64 にセットする方が望ましい方法である ( feature_test_macros(7) を参照)。
- O_NOATIME (Linux 2.6.8 以降)
- ファイルに対して read(2) が実行されたときに、最終アクセス時刻 (inode の st_atime) を更新しない。このフラグはインデックス作成やバックアッププログラムで使うことを意図している。これを使うとディスクに対する操作を大幅に減らすことができる。このフラグは全てのファイルシステムに対して有効であるわけではない。その一例が NFS であり、サーバがアクセス時刻を管理している。
- O_NOCTTY
- pathname が端末 (terminal) デバイス— tty(4) 参照—を指している場合に、たとえそのプロセスが制御端末を持っていなくても、オープンしたファイルは制御端末にはならない。
- O_NOFOLLOW
- pathname がシンボリックリンクだった場合、オープンは失敗する。これは FreeBSD の拡張で、Linux には 2.1.126 より追加された。 pathname の前のコンポーネント (earlier component;訳註: 最後のディレクトリセパレータより前の部分) がシンボリックリンクである場合には、それが指す先が参照される。
- O_NONBLOCK または O_NDELAY
- 可能ならば、ファイルは非停止 (nonblocking) モードでオープンされる。 open() も、返したファイルディスクリプタに対する以後のすべての操作も呼び出したプロセスを待たせることはない。 FIFO (名前付きパイプ) を扱う場合には fifo(7) も参照すること。強制ファイルロック (mandatory file lock) やファイルリース (file lease) と組み合わせた場合の、 O_NONBLOCK の効果についての議論は、 fcntl(2) を参照すること。
- O_SYNC
- ファイルは同期 (synchronous) I/O モードでオープンされる。 open() が返したファイルディスクリプタに対して write(2) を行うと、必ず呼び出したプロセスをブロックし、該当ハードウェアに物理的に書き込まれるまで返らない。 以下の「注意」の章も参照。
- O_TRUNC
- ファイルが既に存在し、通常ファイルであり、書き込み可モードでオープンされている (つまり、 O_RDWRまたは O_WRONLY の) 場合、長さ 0 に切り詰め (truncate) られる。ファイルが FIFO または端末デバイスファイルの場合、 O_TRUNC フラグは無視される。それ以外の場合、 O_TRUNC の効果は未定義である。
これらの選択フラグのいくつかはファイルをオープンした後でも fcntl(2) を使用して変更することができる。
creat() は flags に O_CREAT|O_WRONLY|O_TRUNC を指定して open() を行うのと等価である。
返り値
open() と creat() は新しいファイルディスクリプタを返す。エラーが発生した場合は-1 を返す (その場合は errno が適切に設定される)。エラー
- EACCES
- ファイルに対する要求されたアクセスが許されていないか、 pathname のディレクトリ部分の何れかのディレクトリに検索許可がなかった。またはファイルが存在せず、親ディレクトリへの書き込み許可がなかった。 ( path_resolution(7) も参照すること。)
- EDQUOT
- Where O_CREAT is specified, the file does not exist, and the user's quota of disk blocks or inodes on the file system has been exhausted.
- EEXIST
- pathname は既に存在し、 O_CREAT と O_EXCL が使用された。
- EFAULT
- pathname がアクセス可能なアドレス空間の外を指している。
- EFBIG
- EOVERFLOW 参照。
- EINTR
- 遅いデバイス (例えば FIFO、 fifo(7) 参照) のオープンが完了するのを待って停止している間にシステムコールがシグナルハンドラにより割り込まれた。 signal(7) 参照。
- EISDIR
- pathname はディレクトリを参照しており、書き込み要求が含まれていた (つまり O_WRONLY または O_RDWR が設定されている)。
- ELOOP
- pathname を解決する際に遭遇したシンボリックリンクが多過ぎる。または O_NOFOLLOW が指定されており、 pathname がシンボリックリンクだった。
- EMFILE
- プロセスがオープンしているファイル数がすでに最大数に達している。
- ENAMETOOLONG
- pathname が長過ぎる。
- ENFILE
- オープンされているファイルの総数がシステムの制限に達している。
- ENODEV
- pathname がデバイススペシャルファイルを参照しており、対応するデバイスが存在しない。 (これは Linux カーネルのバグであり、この場合には ENXIO が返されるべきである)
- ENOENT
- O_CREAT が設定されておらず、かつ指定されたファイルが存在しない。または、 pathname のディレクトリ部分が存在しないか壊れた (dangling) シンボリックリンクである。
- ENOMEM
- 十分なカーネルメモリーがない。
- ENOSPC
- pathname を作成する必要があるが、 pathname を含んでいるデバイスに新しいファイルのための空き容量がない。
- ENOTDIR
- pathname に含まれるディレクトリ部分のどれかが実際にはディレクトリでない。または O_DIRECTORY が指定されており、 pathname がディレクトリでない。
- ENXIO
- O_NONBLOCK | O_WRONLY が設定されており、指定したファイルが FIFO でそのファイルを読み込みのためにオープンしているプロセスが存在しない。または、ファイルがデバイススペシャルファイルで対応するデバイスが存在しない。
- EOVERFLOW
- pathname が参照しているのが、大き過ぎてオープンできない通常のファイルである。通常、このエラーが発生するは、32 ビットプラットフォーム上で -D_FILE_OFFSET_BITS=64 を指定せずにコンパイルされたアプリケーションが、ファイルサイズが (2<31)-1 ビットを超えるファイルを開こうとした場合である。上記の O_LARGEFILE も参照。これは POSIX.1-2001 で規定されているエラーである。 2.6.24 より前のカーネルでは、Linux はこの場合にエラー EFBIG を返していた。
- EPERM
- O_NOATIME フラグが指定されたが、呼び出し元の実効ユーザー ID がファイルの所有者と一致せず、かつ呼び出し元に特権 ( CAP_FOWNER) がない。
- EROFS
- pathname が読み込み専用のファイルシステム上のファイルを参照しており、書き込みアクセスが要求された。
- ETXTBSY
- pathname が現在実行中の実行イメージを参照しており、書き込みが要求された。
- EWOULDBLOCK
- O_NONBLOCK フラグが指定されたが、そのファイルには矛盾するリースが設定されていた ( fcntl(2) 参照)。
準拠
SVr4, 4.3BSD, POSIX.1-2001. フラグ O_DIRECTORY, O_NOATIME, O_NOFOLLOW は Linux 特有のものであり、これらのフラグの定義を得るためには、 (「どの」ヘッダファイルをインクルードするよりも前に) _GNU_SOURCE を定義する必要があるかもしれない。注意
Linux では、 O_NONBLOCK フラグは、 open を実行したいが read または write を実行する意図は必ずしもないことを意味する。これは ioctl(2) のためのファイルディスクリプタを取得するために、デバイスをオープンするときによく用いられる。O_RDONLY | O_TRUNC の影響は未定義であり、その動作は実装によって異なる。多くのシステムではファイルは実際に切り詰められる。
NFS を実現しているプロトコルには多くの不備があり、特に O_SYNC と O_NDELAY に影響する。
POSIX では、3 種類の同期 I/O が提供されており、 O_SYNC, O_DSYNC, O_RSYNC フラグがこれに対応するものである。今のところ (カーネル 2.6.31)、 Linux では O_SYNC だけが実装されているが、 glibc は O_DSYNC と O_RSYNC に O_SYNC と同じ数値を割り当てている。ほとんどの Linux のファイルシステムは、実際には POSIX の O_SYNC の動作ではなく O_DSYNC の動作だけを実装している。 POSIX の O_SYNC では、 open() がユーザ空間に返る際に、書き込みに関する全てのメタデータの更新がディスクに書き込まれている必要がある。一方、 O_DSYNC では、 open() が返るまでに、実際のファイルのデータとそのデータを取得するために必要なメタデータだけがディスクに書き込まれていればよい。
open() はスペシャルファイルをオープンすることができるが、 creat() でスペシャルファイルを作成できない点に注意すること。代わりに mknod(2) を使用する。
UID マッピングを使用している NFS ファイルシステムでは、 open() がファイルディスクリプタを返した場合でも read(2) が EACCES で拒否される場合がある。これはクライアントがアクセス許可のチェックを行って open() を実行するが、読み込みや書き込みの際にはサーバーで UID マッピングが行われるためである。
ファイルが新しく作成されると、ファイルの st_atime, st_ctime, st_mtime フィールド (それぞれ最終アクセス時刻、最終状態変更時刻、最終修正時刻である。 stat(2) 参照) が現在時刻に設定される。さらに親ディレクトリの st_ctime と st_mtime も現在時刻に設定される。それ以外の場合で、O_TRUNC フラグでファイルが修正されたときは、ファイルの st_ctime と st_mtime フィールドが現在時刻に設定される。
O_DIRECT
O_DIRECT フラグを使用する場合、ユーザ空間バッファの長さやアドレス、 I/O のファイルオフセットに関してアラインメントの制限が課されることがある。 Linux では、アラインメントの制限はファイルシステムやカーネルのバージョンによって異なり、全く制限が存在しない場合もある。しかしながら、現在のところ、指定されたファイルやファイルシステムに対してこうした制限があるかを見つけるための、アプリケーション向けのインタフェースでファイルシステム非依存のものは存在しない。いくつかのファイルシステムでは、制限を確認するための独自のインタフェースが提供されている。例えば、 xfsctl(3) の XFS_IOC_DIOINFO 命令である。Linux 2.4 では、転送サイズ、ユーザーバッファのアラインメント、ファイルオフセットは、ファイルシステムの論理ブロックサイズの倍数でなければならない。 Linux 2.6 では、512 バイトごとの境界に配置されていれば充分である。
メモリバッファがプライベートマッピング ( mmap(2) の MAP_PRIVATE フラグで作成されたマッピング) の場合には、 O_DIRECT I/O は fork(2) システムコールと同時に決して実行すべきではない (プライベートマッピングには、ヒープ領域に割り当てられたメモリや静的に割り当てたバッファも含まれる)。非同期 I/O インターフェース (AIO) 経由やプロセス内の他のスレッドから発行された、このような I/O は、 fork(2) が呼び出される前に完了されるべきである。そうしなかった場合、データ破壊や、親プロセスや子プロセスでの予期しない動作が起こる可能性がある。 O_DIRECT I/O 用のメモリバッファが shmat(2) や MAP_SHARED フラグ付きの mmap(2) で作成された場合には、この制限はあてはまらない。 madvise(2) でメモリバッファにアドバイス MADV_DONTFORK が設定されている場合にも、この制限はあてはまらない( MADV_DONTFORK はそのメモリバッファが fork(2) 後に子プロセスからは利用できないことを保証するものである)。
O_DIRECT フラグは SGI IRIX で導入された。SGI IRIX にも Linux 2.4 と同様の (ユーザーバッファの) アラインメントの制限がある。また、IRIX には適切な配置とサイズを取得するための fcntl(2) コールがある。 FreeBSD 4.x も同じ名前のフラグを導入したが、アラインメントの制限はない。
O_DIRECT が Linux でサポートされたのは、カーネルバージョン 2.4.10 である。古い Linux カーネルは、このフラグを単に無視する。 O_DIRECT フラグをサポートしていないファイルシステムもあり、その場合は、 O_DIRECT を使用すると open() は EINVAL で失敗する。
アプリケーションは、同じファイル、特に同じファイルの重複するバイト領域に対して、 O_DIRECT と通常の I/O を混ぜて使うのは避けるべきである。ファイルシステムがこのような状況において一貫性の問題を正しく扱うことができる場合であっても、全体の I/O スループットはどちらか一方を使用するときと比べて低速になるであろう。同様に、アプリケーションは、同じファイルに対して mmap(2) と直接 I/O ( O_DIRECT) を混ぜて使うのも避けるべきである。
NFS で O_DIRECT を使った場合の動作はローカルのファイルシステムの場合と違う。古いカーネルや、ある種の設定でコンパイルされたカーネルは、 O_DIRECT と NFS の組み合わせをサポートしていないかもしれない。 NFS プロトコル自体はサーバにフラグを渡す機能は持っていないので、 O_DIRECT I/O はクライアント上のページキャッシュをバイパスするだけになり、サーバは I/O をキャッシュしているかもしれない。クライアントは、 O_DIRECT の同期機構を保持するため、サーバに対して I/O を同期して行うように依頼する。サーバによっては、こうした状況下、特に I/O サイズが小さい場合に性能が大きく劣化する。また、サーバによっては、I/O が安定したストレージにまで行われたと、クライアントに対して嘘をつくものもある。これは、サーバの電源故障が起こった際にデータの完全性が保たれない危険は少しあるが、性能面での不利な条件を回避するために行われている。 Linux の NFS クライアントでは O_DIRECT I/O でのアラインメントの制限はない。
まとめると、 O_DIRECT は、注意して使うべきであるが、強力なツールとなる可能性を持っている。アプリケーションは O_DIRECT をデフォルトでは無効になっている性能向上のためのオプションと考えておくのがよいであろう。
バグ
現在のところ、 open() の呼び出し時に O_ASYNC を指定してシグナル駆動 I/O を有効にすることはできない。このフラグを有効にするには fcntl(2) を使用すること。関連項目
chmod(2), chown(2), close(2), dup(2), fcntl(2), link(2), lseek(2), mknod(2), mmap(2), mount(2), openat(2), read(2), socket(2), stat(2), umask(2), unlink(2), write(2), fopen(3), fifo(7), path_resolution(7), symlink(7)この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.51 の一部である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2013-02-18 | Linux |