OPENAT(2)

名前
openat - ディレクトリファイルディスクリプタから相対的な位置にあるファイルをオープンする

書式
#include <fcntl.h>

int openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);

glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):

openat():
    glibc 2.10 以降:
        _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
    glibc 2.10 より前:
        _ATFILE_SOURCE

説明
openat() システムコールは、この man ページで説明している違いがある以外は、 open(2) と全く同じように動作する。 pathname で指定されるパス名が相対パスである場合、 ファイルディスクリプタ dirfd で参照されるディレクトリからの相対パス名として解釈される (open(2) では、相対パスは呼び出し元プロセスのカレントワーキングディレクトリからの 相対パスとなる)。 pathname が相対パスであり、かつ dirfd が特別な値 AT_FDCWD である場合、 pathname は (open(2) と同じように) 呼び出し元プロセスの カレントワーキングディレクトリからの相対パス名として解釈される。 pathname が絶対パスである場合、 dirfd は無視される。

返り値
成功した場合、 openat() は新しいファイルディスクリプタを返す。 エラーの場合、-1 が返されて、 errno にはエラーを示す値が設定される。

エラー
open(2) と同じエラーが openat() でも起こる。 openat() では、その他に以下のエラーが起こる:

EBADF
    dirfd が有効なファイルディスクリプタでない。

ENOTDIR
    pathname が相対パスで、かつ dirfd がディレクトリ以外のファイルを参照するファイルディスクリプタである。

バージョン
openat() は Linux カーネル 2.6.16 で追加された。 ライブラリによるサポートは glibc バージョン 2.4 で追加された。

準拠
POSIX.1-2008. Solaris には、これと同じようなシステムコールが存在する。

注意
openat() や "at" が後ろに付いたその他の同様のシステムコールは、 2 つの理由により提供されている。 1 つ目の理由は、 カレントワーキングディレクトリ以外のディレクトリにあるファイル群を open(2) でオープンするときに起こる可能性がある競合状態 (race condition) を、 openat() によってアプリケーションが回避できるためである。 これらの競合状態は、 open(2) に指定されたパスのディレクトリ部分の (/ で区切られた) いくつかの構成要素 (をオープンする処理) が、 open(2) を並列に呼び出す処理に変換された場合に起こる。 このような競合は、対象ディレクトリのファイルディスクリプタをオープンし、 そのファイルディスクリプタを openat() の dirfd 引き数に指定することで回避できる。 2 つ目の理由は、 アプリケーションによって管理されるファイルディスクリプタ (群) を使うことで、 openat() がスレッド毎のいわゆる「カレントワーキングディレクトリ」を実装できるためである。 (この機能は /proc/self/fd/dirfd を使った裏技でも実現できるが、あまり効率的ではない)。

関連項目
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), futimesat(2), linkat(2), mkdirat(2), mknodat(2), open(2), readlinkat(2), renameat(2), symlinkat(2), unlinkat(2), utimensat(2), mkfifoat(3), path_resolution(7)

この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.51 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。