Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all
名前
stat, fstat, lstat, fstatat - ファイルの状態を取得する
書式
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(const char *pathname, struct stat *buf); int fstat(int fd, struct stat *buf); int lstat(const char *pathname, struct stat *buf); #include <fcntl.h> /* AT_* 定数の定義 */ #include <sys/stat.h> int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags); glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照): lstat(): /* glibc 2.19 以前 */ _BSD_SOURCE || /* glibc 2.20 以降 */_DEFAULT_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || /* glibc 2.10 以降: */ _POSIX_C_SOURCE >= 200112L fstatat(): glibc 2.10 以降: _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L glibc 2.10 より前: _ATFILE_SOURCE
説明
これらの関数は、ファイルについての情報を stat が指すバッファーに格納して返す。 ファイルそ のものに対するアクセス許可は必要としないが、 —stat(), fstatat(), lstat() の場合には —その ファイルへ至る pathname を構成する全てのディレクトリに対する実行 (検索) 許可が必要である。 stat() と fstatat() は pathname が指すファイルに関する情報を取得する。 fstatat() の違いに ついては後で説明する。 lstat() は stat() と同じであるが、 pathnames がシンボリックリンクの場合、リンクが参照し ているファイルではなく、 リンク自身の状態を返す点が異なる。 fstat() は stat() と同じだが、 状態を取得するファイルをファイルディスクリプター fd で指 定する点が異なる。 これらのシステムコールはいずれも、結果を stat 構造体に入れて返す。 stat 構造体には以下の フィールドが含まれている: struct stat { dev_t st_dev; /* ファイルがあるデバイスの ID */ ino_t st_ino; /* inode 番号 */ mode_t st_mode; /* アクセス保護 */ nlink_t st_nlink; /* ハードリンクの数 */ uid_t st_uid; /* 所有者のユーザー ID */ gid_t st_gid; /* 所有者のグループ ID */ dev_t st_rdev; /* デバイス ID (特殊ファイルの場合) */ off_t st_size; /* 全体のサイズ (バイト単位) */ blksize_t st_blksize; /* ファイルシステム I/O での ブロックサイズ */ blkcnt_t st_blocks; /* 割り当てられた 512B のブロック数 */ }; /* Linux 2.6 以降では、カーネルは以下のタイムスタンプ フィールドでナノ秒の精度をサポートしている。 Linux 2.6 より前のバージョンでの詳細は 下記の「注意」を参照。 */ struct timespec st_atim; /* 最終アクセス時刻 */ struct timespec st_mtim; /* 最終修正時刻 */ struct timespec st_ctim; /* 最終状態変更時刻 */ #define st_atime st_atim.tv_sec /* 後方互換性 */ #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec }; 注意: stat 構造体のフィールドの順序はアーキテクチャーにより様々である。 また、上記の定義で は、フィールド間に存在することがあるパディングバイトは書かれていない。このパディングバイト はアーキテクチャーによっても異なる。詳細を知る必要がある場合は glibc とカーネルのソースを 調べてほしい。 st_dev フィールドは、このファイルが存在するデバイスを示す (マクロ major(3), minor(3) は、このフィールドのデバイス ID を分解するのに役立つだろう)。 st_rdev フィールドは、このファイル (inode) が表すデバイスを示す。 st_size フィールドは、(通常のファイルかシンボリックリンクの場合に) ファイルの大きさをバイ ト単位で示す。 シンボリックリンクの大きさは、 シンボリックリンクに含まれている パス名の長 さ (終端のヌルバイトは含まない) である。 st_blocks フィールドは、ファイルの大きさを 512 バイトのブロックサイズ単位で示す フィールド は、ファイルに割り当てされたブロック数を 512 バイト単位で示す。 (ファイルに穴があるような 場合、この値は st_size/512 より小さくなることもある)。 st_blksize フィールドは、効率的にファイルシステム I/O ができる「好ましい」 ブロックサイズ を示す (もっと小さい単位でファイルに書き込みを行うと、 読み出し--修正--再書き込みといった 非効率な動作になってしまうかもしれない)。 全ての Linux のファイルシステムが全ての時間フィールドを 実装しているわけではない。 ファイ ルやディレクトリのアクセスが st_atime フィールドを更新しないようなかたちでマウントできる ファイルシステムもある。 (mount(8) の noatime, nodiratime, relatime や mount(2) の関連す る情報を参照)。 また、ファイルが O_NOATIME 付きでオープンされている場合には st_atime は更 新されない。 open(2) 参照。 st_atime フィールドはファイルアクセスがあった場合に変更される (例えば、 execve(2), mknod(2), pipe(2), utime(2) を使用した場合や read(2) で 1 バイト以上読み込んだ場合な ど)。 mmap(2) などの他のルーチンでは、 st_atime は更新されることもあれば、そうでない場合 もある。 st_mtime フィールドは、ファイルが修正された場合に変更される (例えば、 mknod(2), truncate(2), utime(2) を使用した場合や write(2) で 1 バイト以上書き込みをした場合など)。 さらに、ディレクトリの st_mtime は、そのディレクトリで ファイルが作成されたり削除されたり すると変更される。 st_mtime フィールドは 所有者やグループやハードリンク数やモードの変更で は変更 されない。 st_ctime フィールドは書き込みや inode 情報 (所有者、グループ、リンク数、モードなど) の 設 定によって変更される。 以下のマスク値が st_mode フィールドのファイル種別の検査用に定義されている。 S_IFMT 0170000 ファイル種別を示すビット領域を表すビットマスク S_IFSOCK 0140000 ソケット S_IFLNK 0120000 シンボリックリンク S_IFREG 0100000 通常のファイル S_IFBLK 0060000 ブロックデバイス S_IFDIR 0040000 ディレクトリ S_IFCHR 0020000 キャラクターデバイス S_IFIFO 0010000 FIFO したがって、(例えば) 通常のファイルかどうかを検査するには、以下のようにすればよい。 stat(pathname, &sb); if ((sb.st_mode & S_IFMT) == S_IFREG) { /* Handle regular file */ } 上記の形の検査はよくあるので、 POSIX では以下のマクロが定義されており、 st_mode のファイル 種別の検査をより簡単に書けるようになっている。 S_ISREG(m) 通常のファイルか? S_ISDIR(m) ディレクトリか? S_ISCHR(m) キャラクターデバイスか? S_ISBLK(m) ブロックデバイスか? S_ISFIFO(m) FIFO (名前付きパイプ) か? S_ISLNK(m) シンボリックリンクか? (POSIX.1-1996 にはない) S_ISSOCK(m) ソケットか? (POSIX.1-1996 にはない) 上で挙げたコードは以下のように書き換えることができる。 stat(pathname, &sb); if (S_ISREG(sb.st_mode)) { /* Handle regular file */ } 上記のほとんどのファイル種別検査マクロの定義は、 機能検査マクロ _BSD_SOURCE (glibc 2.19 以 前の場合)、 _SVID_SOURCE (glibc 2.19 以前の場合)、 _DEFAULT_SOURCE (glibc 2.20 以降の場合) のいずれかが定義されている場合に公開される。 さらに、 S_IFSOCK と S_ISSOCK 以外の上記のす べてのマクロの定義は _XOPEN_SOURCE が定義されている場合にも公開される。 S_IFSOCK の定義は _XOPEN_SOURCE が値 500 以上で定義された場合にも公開される。 S_ISSOCK() の定義が公開されるのは以下の機能検査マクロが定義されている場合である: _BSD_SOURCE (glibc 2.19 以前の場合)、 _DEFAULT_SOURCE (glibc 2.20 以降の場合)、 値 500 以 上の _XOPEN_SOURCE、 値が 200112L 以上の _POSIX_C_SOURCE。 以下のマスク値が st_mode フィールドのファイルのアクセス許可の検査用に定義されている。 S_ISUID 0004000 set-user-ID bit S_ISGID 0002000 set-group-ID bit (下記参照) S_ISVTX 0001000 スティッキービット (下記参照) 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 他人の実行許可 set-group-ID bit (S_ISGID) にはいくつかの特殊な使用法がある: ディレクトリに設定した場合に は、そのディレクトリが BSD 方式で使用される ことを示す。つまり、そのディレクトリに作成され たファイルのグループID は 作成したプロセスの実効 (effective) グループID ではなく、ディレク トリの グループID を継承する。また、そのディレクトリに作成されたディレクトリにも S_ISGID ビットが設定される。グループ実行ビット (S_IXGRP) が設定されていないファイルに設定された場 合は、 set-group-ID ビットはファイル/レコードの 強制的な (mandatory) ロックを表す。 ディレクトリにスティッキービット (S_ISVTX) が設定された場合は、 そのディレクトリのファイル の名前を変更したり、削除したりできるのは、 そのファイルの所有者か、そのディレクトリの所有 者か、特権プロセス だけとなる。 fstatat() fstatat() システムコールは stat() と全く同様に動作するが、以下で説明する点が異なる。 指定された pathname が相対パスの場合、 ファイルディスクリプター dirfd が参照するディレクト リに対する相対パスと解釈される (stat() に相対パスを渡した場合のように、呼び出したプロセス のカレントワーキングディレクトリに対する相対パスではない)。 pathname が相対パスで、 dirfd が特別な値 AT_FDCWD の場合、 (stat(2) と同様に) pathname は 呼び出したプロセスのカレントワーキングディレクトリに対する相対パスと解釈される。 pathname で指定されたパス名が絶対パスの場合、 dirfd は無視される。 この flags 引き数は下記のフラグの 0 個以上の論理和を取ったものである: AT_EMPTY_PATH (Linux 2.6.39 以降) pathname が空文字列の場合、 dirfd が参照するファイルに対して操作を行う (dirfd は open(2) の O_PATH フラグを使って取得できる)。 dirfd が AT_FDCWD の場合、呼び出しは カレントワーキングディレクトリに対して操作を行う。 この場合、 dirfd は、ディレクト リだけでなく、任意のタイプのファイルを参照することができる。 このフラグは Linux 固 有であり、その定義を得るには _GNU_SOURCE を定義すること。 AT_NO_AUTOMOUNT (Linux 2.6.38 以降) pathname がオートマウントポイントとなっているディレクトリの場合、 pathname の最終 ("basename") 要素のオートマウントを行わない。 これにより (マウントされるはずの場所 ではなく) オートマウントポイントの属性を取得することができる。 このフラグを使うと、 ディレクトリをスキャンするツールがオートマウントポイントのディレクトリを大量にオー トマウントしてしまうのを防ぐことができる。 マウントポイントがすでにマウントされてい る場合 AT_NO_AUTOMOUNT フラグは何の効果もない。 このフラグは Linux 固有であり、その 定義を得るには _GNU_SOURCE を定義すること。 AT_SYMLINK_NOFOLLOW (lstat() 同様) pathname がシンボリックリンクの場合リンクの展開を行わず、 リンク自身 の情報を返す (デフォルトでは、 fstatat() は、 stat() と同様に、シンボリックリンクの 展開を行う)。 fstatat() の必要性についての説明については openat(2) を参照。
返り値
成功した場合、0 が返される。 失敗した場合、 -1 が返され、 errno に適切な値がセットされる。
エラー
EACCES pathname が所属するディレクトリとその上位のディレクトリのいずれかに 対する検索許可 がなかった (path_resolution(7) も参照のこと)。 EBADF fd が不正である。 EFAULT アドレスが間違っている。 ELOOP パスを辿る際に解決すべきシンボリックリンクが多過ぎた。 ENAMETOOLONG pathname が長過ぎる。 ENOENT pathname の構成要素が存在しないか、 pathname が空文字列である。 ENOMEM カーネルのメモリーが足りない。 ENOTDIR pathname の前半部分 (prefix) の構成要素がディレクトリではない。 EOVERFLOW pathname または fd が、ファイルサイズ、inode 番号、ブロック数が それぞれ off_t 型、 ino_t 型、 blkcnt_t 型で表現できないファイルを 参照している。このエラーが起こるの は、例えば、32 ビットプラットフォーム上で -D_FILE_OFFSET_BITS=64 を指定せずにコンパ イルされたアプリケーションが、 ファイルサイズが (1<<31)-1 バイトを超えるファイルに 対して stat() を呼び出した場合である。 fstatat() では以下のエラーも発生することがある。 EBADF dirfd が有効なファイルディスクリプターでない。 EINVAL flags に無効なフラグが指定された。 ENOTDIR pathname が相対パスで、 dirfd がディレクトリ以外のファイルを参照しているファイル ディスクリプターである。
バージョン
fstatat() はカーネル 2.6.16 で Linux に追加された。 ライブラリによるサポートはバージョン 2.4 で glibc に追加された。
準拠
stat(), fstat(), lstat(): SVr4, 4.3BSD, POSIX.1-2001, POSIX.1.2008. fstatat(): POSIX.1-2008. POSIX.1-2001 では、シンボリックリンクに対する lstat() で 有効な情報を返すように求められて いたのは、 stat 構造体の st_size と st_mode のファイル種別要素だけであった。 POSIX.1-2008 では規定が厳しくなり、 lstat() は st_mode の アクセス許可ビット以外の全てのフィールドに有 効な情報を返すことが 求められるようになっている。 st_blocks と st_blksize フィールドの使用はあまり移植性がない (これらのフィールドは BSD に よって導入された。 システムごとに解釈が 異なっており、 NFS マウントの場合には同じシステム でも異なる可能性がある)。 <sys/stat.h> から blkcnt_t の blksize_t 型定義を 読み込みたい場 合は、(どのヘッダーファイルをインクルードするよりも前に) _XOPEN_SOURCE を 500 以上の値で定 義すること。 POSIX.1-1990 には S_IFMT, S_IFSOCK, S_IFLNK, S_IFREG, S_IFBLK, S_IFDIR, S_IFCHR, S_IFIFO, S_ISVTX 定数に関する 記述はなかったが、代わりに S_ISDIR() のようなマクロを使用するように 要求していた。 S_IF* 定数は POSIX.1-2001 以降には存在する。 マクロ S_ISLNK() と S_ISSOCK() は POSIX.1-1996 にはないが、 POSIX.1-2001 には両方とも存在 する。 前者は SVID 4 に、後者は SUSv2 に 由来している。 UNIX V7 (とその後のシステム) は S_IREAD, S_IWRITE, S_IEXEC を持っており、 POSIX はその同義 語として S_IRUSR, S_IWUSR, S_IXUSR を規定している。 他のシステム 各種システムで使用されていた(いる)値: 16進 名前 ls 8進数 説明 f000 S_IFMT 170000 ファイル種別フィールドのビットマスク 0000 000000 SCO では 使用不能 inode; BSD では不明な ファイル種別; SVID-v2 と XPG2 では 0 と 0100000 の両方が通常のファイル 1000 S_IFIFO p| 010000 FIFO (名前付きパイプ) 2000 S_IFCHR c 020000 キャラクター特殊ファイル (V7) 3000 S_IFMPC 030000 多重化されたキャラクター特殊ファイル (V7) 4000 S_IFDIR d/ 040000 ディレクトリ (V7) 5000 S_IFNAM 050000 XENIX の二つの副型を持つ名前付きの特殊 ファイル 副型は st_rdev の値 1, 2 で区別 される 0001 S_INSEM s 000001 XENIX の IFNAM セマフォ副型 0002 S_INSHD m 000002 XENIX の IFNAM 共有データ副型 6000 S_IFBLK b 060000 ブロック特殊ファイル (V7) 7000 S_IFMPB 070000 多重化されたブロック特殊ファイル (V7) 8000 S_IFREG - 100000 通常ファイル (V7) 9000 S_IFCMP 110000 VxFS 圧縮ファイル 9000 S_IFNWK n 110000 ネットワーク特殊ファイル (HP-UX) a000 S_IFLNK l@ 120000 シンボリックリンク (BSD) b000 S_IFSHAD 130000 Solaris の ACL 用の隠し inode (ユーザー空 間からは見えない) c000 S_IFSOCK s= 140000 ソケット (BSD; VxFS の "S_IFSOC") d000 S_IFDOOR D> 150000 Solaris の door ファイル e000 S_IFWHT w% 160000 BSD の空白ファイル (inode を使用しない) 0200 S_ISVTX 001000 スティッキービット: 使用後もスワップに残 す (V7) 予約 (SVID-v2) ディレクトリ以外: ファイルをキャッシュし ない (SunOS) ディレクトリの場合: 削除制限フラグ (SVID-v4.2) 0400 S_ISGID 002000 実行時の set-group-ID (V7) ディレクトリの場合: GID の伝搬に BSD 方式 を使用する 0400 S_ENFMT 002000 System V ファイルロックを強制する (S_ISGID と共有) 0800 S_ISUID 004000 実行時の set-user-ID (V7) 0800 S_CDF 004000 ディレクトリがコンテキスト依存ファイル (HP-UX) スティッキー コマンドは Version 32V AT&T UNIX で登場した。
注意
Linux では、 lstat() は一般には自動マウント動作 (automounter action) の きっかけとならない が、 stat() はきっかけとなる (fstatat(2) を参照)。 /proc ディレクトリ以下にあるファイルのほとんどでは、 stat() を呼び出した際に、 st_size フィールドにファイルサイズが返されない。 代わりに st_size フィールドには 0 が返される。 タイムスタンプフィールド 古いカーネルや古い標準では、ナノ秒精度のタイムスタンプフィールドはサポートされていなかっ た。 代わりに 3 つの time_t 型のタイムスタンプフィールド st_atime, st_mtime, and st_ctime があった。これらのフィールドには 1 秒単位のタイムスタンプが記録されていた。 カーネル 2.5.48 以降では、 stat 構造体は 3 つのファイルのタイムスタンプ関連のフィールドで ナノ秒単位の精度に対応している。 機能検査マクロ _BSD_SOURCE か _SVID_SOURCE が定義された場 合に、各タイムスタンプのナノ秒の情報は st_atim.tv_nsec という形式の名前で参照できる。 ナノ 秒のタイムスタンプは現在では標準化されており、 POSIX.1-2008 からである。 バージョン 2.12 以降の glibc では、 _POSIX_C_SOURCE が 200809L 以上の値で定義されるか、 _XOPEN_SOURCE が 700 以上の値で定義された場合にも、 このナノ秒のタイムスタンプが公開される。 上記のマクロの いずれも定義されていない場合、ナノ秒の値は st_atimensec という形式の名前で公開される。 ナノ秒のタイムスタンプは XFS, JFS, Btrfs, ext4 でサポートされている (Linux 2.6.23 以降)。 ナノ秒のタイムスタンプは ext2, ext3, Reiserfs ではサポートされていない。 サブ秒のタイムス タンプをサポートしていないファイルシステムでは、 ナノ秒のフィールドには値 0 が入る。 背後のカーネルインターフェース 時間の経過とともに、 stat 構造体のサイズが大きくなり、この影響で stat() には 3つのバー ジョンが存在する: sys_stat() (スロットは __NR_oldstat)、 sys_newstat() (スロットは __NR_stat)、 sys_stat64() (カーネル 2.4 で導入; スロットは __NR_stat64). glibc の stat() ラッパー関数はこれらの詳細をアプリケーションから隠蔽してくれる。 具体的には、カーネルが提 供しているシステムコールのうち最新のバージョンを 起動し、古いバイナリの場合には必要に応じ て返された情報を再構成 (repack) する。 fstat() と lstat() についても同様である。 glibc の fstatat() ラッパー関数が内部で利用するシステムコールは、実際には fstatat64() であ る。
例
以下のプログラムは stat() を呼び出し、返ってきた stat 構造体のフィールドのいくつかを表示 する。 #include <sys/types.h> #include <sys/stat.h> #include <time.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { struct stat sb; if (argc != 2) { fprintf(stderr, "Usage: %s <pathname>\n", argv[0]); exit(EXIT_FAILURE); } if (stat(argv[1], &sb) == -1) { perror("stat"); exit(EXIT_FAILURE); } printf("File type: "); switch (sb.st_mode & S_IFMT) { case S_IFBLK: printf("block device\n"); break; case S_IFCHR: printf("character device\n"); break; case S_IFDIR: printf("directory\n"); break; case S_IFIFO: printf("FIFO/pipe\n"); break; case S_IFLNK: printf("symlink\n"); break; case S_IFREG: printf("regular file\n"); break; case S_IFSOCK: printf("socket\n"); break; default: printf("unknown?\n"); break; } printf("I-node number: %ld\n", (long) sb.st_ino); printf("Mode: %lo (octal)\n", (unsigned long) sb.st_mode); printf("Link count: %ld\n", (long) sb.st_nlink); printf("Ownership: UID=%ld GID=%ld\n", (long) sb.st_uid, (long) sb.st_gid); printf("Preferred I/O block size: %ld bytes\n", (long) sb.st_blksize); printf("File size: %lld bytes\n", (long long) sb.st_size); printf("Blocks allocated: %lld\n", (long long) sb.st_blocks); printf("Last status change: %s", ctime(&sb.st_ctime)); printf("Last file access: %s", ctime(&sb.st_atime)); printf("Last file modification: %s", ctime(&sb.st_mtime)); exit(EXIT_SUCCESS); }
関連項目
ls(1), stat(1), access(2), chmod(2), chown(2), readlink(2), utime(2), capabilities(7), symlink(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。