int stat(const char *path, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *path, struct stat *buf);
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
lstat(): _BSD_SOURCE || _XOPEN_SOURCE >= 500
これらの関数はファイルについての情報を返す。 ファイルそのものに対するアクセス許可は必要としないが、 --- stat() と lstat() の場合には --- そのファイルへ至る path を構成する全てのディレクトリに対する実行 (検索) 許可が必要である。
stat() は path で指定されたファイルの状態を取得して buf へ格納する。
lstat() は stat() と同じであるが、 path がシンボリックリンクの場合、リンクが参照しているファイルではなく、 リンク自身の状態を取得する点が異なる。
fstat() は stat() と同じだが、 状態を取得するファイルをファイル・ディスクリプタ filedes で指定する。
これらのシステムコールはいずれも、結果を 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; /* 割り当てられたブロック数 */ time_t st_atime; /* 最終アクセス時刻 */ time_t st_mtime; /* 最終修正時刻 */ time_t st_ctime; /* 最終状態変更時刻 */ };
st_dev フィールドは、このファイルが存在するデバイスを示す。
st_rdev フィールドは、このファイル (inode) が表すデバイスを示す。
st_size フィールドは、(通常のファイルかシンボリックリンクの場合に) ファイルの大きさをバイト単位で示す。 シンボリックリンクの大きさは、シンボリックリンクに含まれている パス名の長さ (最後の NULL バイトは含まない) である。
st_blocks フィールドは、ファイルの大きさを 512 バイトのブロックサイズ単位で示す フィールドは、ファイルに割り当てされたブロック数を 512 バイト単位で示す。 (ファイルに穴があるような場合、この値は st_size/512 より小さくなることもある)。
st_blksize フィールドは、効率的にファイル・システム I/O ができる「好ましい」 ブロックサイズを示す (もっと小さい単位でファイルに書き込みを行うと、 読み出し--修正--再書き込みといった非効率な動作になってしまうかもしれない)。
全ての Linux のファイル・システムが全ての時間フィールドを 実装しているわけではない。 ファイルアクセスが st_atime フィールドを更新しないようなかたちでマウントできるファイルシステムもある。 (mount(8) の `noatime' オプションを参照)
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 情報 (所有者、グループ、リンク数、モードなど) の 設定によって変更される。
以下の POSIX マクロは、 st_mode フィールド で使用されるファイル種別のチェックのために定義されている :
以下のフラグが 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 |
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 | 他人の実行許可 |
st_blocks と st_blksize フィールドの使用はあまり移植性がない。 (これらのフィールドは BSD によって導入された。 システムごとに解釈が異なっており、 NFS マウントの場合には同じシステムでも異なる可能性がある)
POSIX には S_IFMT, S_IFSOCK, S_IFLNK, S_IFREG, S_IFBLK, S_IFDIR, S_IFCHR, S_IFIFO, S_ISVTX ビットについての記述はない。かわりに S_ISDIR() のようなマクロを使用するように要求している。 マクロ 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 ドア・ファイル |
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 | SysV ファイル・ロックを強制する | |
(S_ISGID と共有) | ||||
0800 | S_ISUID | 004000 | 実行時の set-user-ID (V7) | |
0800 | S_CDF | 004000 | ディレクトリが状況依存ファイル (HP-UX) |
スティッキー コマンドは Version 32V AT&T UNIX で登場した。
/proc ディレクトリ以下にあるファイルのほとんどでは、 stat() を呼び出した際に、 st_size フィールドにファイルサイズが返されない。 代わりに st_size フィールドには 0 が返される。
#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_SUCCESS); } 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 inode 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); }