名前


stat, fstat, lstat - ファイルの状態を取得する

書式


#include <sys/types.h> #include <sys/stat.h> #include <unistd.h>

int stat(const char *path, struct stat *buf); int fstat(int filedes, struct stat *buf); int lstat(const char *path, struct stat *buf);

説明


これらの関数はファイルについての情報を返す。 ファイルそのものに対するアクセス許可は必要としないが、 — 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 フィールド で使用されるファイル種別のチェックのために定義されている :

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 にはない)

以下のフラグが st_mode フィールド用に定義されている:
S_IFMT0170000ファイル種別を示すビット領域を表すビットマスク
S_IFSOCK0140000ソケット
S_IFLNK0120000シンボリック・リンク
S_IFREG0100000通常のファイル
S_IFBLK0060000ブロック・デバイス
S_IFDIR0040000ディレクトリ
S_IFCHR0020000キャラクター・デバイス
S_IFIFO0010000FIFO
S_ISUID0004000set-user-ID bit
S_ISGID0002000set-group-ID bit (下記参照)
S_ISVTX0001000スティッキー・ビット (下記参照)
S_IRWXU00700ファイル所有者のアクセス許可用のビットマスク
S_IRUSR00400所有者の読み込み許可
S_IWUSR00200所有者の書き込み許可
S_IXUSR00100所有者の実行許可
S_IRWXG00070グループのアクセス許可用のビットマスク
S_IRGRP00040グループの読み込み許可
S_IWGRP00020グループの書き込み許可
S_IXGRP00010グループの実行許可
S_IRWXO00007他人 (others) のアクセス許可用のビットマスク
S_IROTH00004他人の読み込み許可
S_IWOTH00002他人の書き込み許可
S_IXOTH00001他人の実行許可

set-group-ID bit (S_ISGID) にはいくつかの特殊な使用法がある: ディレクトリに設定した場合には、そのディレクトリが BSD 方式で使用される ことを示す。つまり、そのディレクトリに作成されたファイルのグループID は 作成したプロセスの実効 (effective) グループID ではなく、ディレクトリの グループID を継承する。また、そのディレクトリに作成されたディレクトリにも S_ISGID ビットが設定される。グループ実行ビット (S_IXGRP) が設定されていない ファイルに設定された場合は、set-group-ID ビットはファイル/レコードの 強制的な (mandatory) ロックを表す。

ディレクトリに「スティッキー」ビット (S_ISVTX) が設定された場合は、 そのディレクトリのファイルの名前を変更したり、削除したりできるのは、 そのファイルの所有者か、そのディレクトリの所有者か、特権プロセス だけとなる。

返り値


成功した場合は 0 を返す。エラーの場合は -1 を返し、 errno に適切な値が設定される。

エラー


EACCES path が所属するディレクトリとその上位のディレクトリのいずれかに 対する検索許可がなかった (path_resolution(7) も参照のこと)。
EBADF filedes が不正である。
EFAULT アドレスが間違っている。
ELOOP パスを辿る際に解決すべきシンボリック・リンクが多過ぎた。
ENAMETOOLONG
 ファイル名が長過ぎる。
ENOENT パス path の構成要素が存在しないか、パスが空文字列である。
ENOMEM カーネルのメモリが足りない。
ENOTDIR
 パスの構成要素がディレクトリではない。

準拠


これらのシステムコールは SVr4, 4.3BSD, POSIX.1-2001 に準拠している。 stat() と fstat() コールは SVr4, SVID, POSIX, X/OPEN, 4.3BSD に準拠している。 lstat() コールは 4.3BSD と SVr4 に準拠している。

st_blocksst_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進名前ls8進数説明
f000S_IFMT 170000ファイル種別フィールドのビットマスク
0000  000000SCO では 使用不能 inode
    BSD では未知のファイル種別
    SVID-v2 と XPG2 では 0 と 0100000 の
    両方が普通のファイル
1000S_IFIFOp|010000FIFO (名前付きパイプ)
2000S_IFCHRc020000キャラクタ特殊ファイル (V7)
3000S_IFMPC 030000多重化されたキャラクタ特殊ファイル (V7)
4000S_IFDIRd/040000ディレクトリ (V7)
5000S_IFNAM 050000XENIX 二つの副型を持つ名前付きの
    特殊ファイル
    副型は st_rdev の値 1,2 で区別される:
0001S_INSEMs000001XENIX IFNAMのセマフォー副型
0002S_INSHDm000002XENIX IFNAMの共有データ副型
6000S_IFBLKb060000ブロック特殊ファイル (V7)
7000S_IFMPB 070000多重化されたブロック特殊ファイル (V7)
8000S_IFREG-100000通常ファイル (V7)
9000S_IFCMP 110000VxFS 圧縮ファイル
9000S_IFNWKn110000ネットワーク特殊ファイル (HP-UX)
a000S_IFLNKl@120000シンボリック・リンク (BSD)
b000S_IFSHAD 130000Solaris ACL のための隠された inode
    (ユーザ空間からは見えない)
c000S_IFSOCKs=140000ソケット (BSD; VxFS の "S_IFSOC")
d000S_IFDOORD>150000Solaris ドア・ファイル
e000S_IFWHTw%160000BSD 空白ファイル (inode を使用しない)
0200S_ISVTX 001000‘スティッキー・ビット’:使用後も
    スワップに残す (V7)
    予約 (SVID-v2)
    ディレクトリ以外: ファイルをキャッシュ
    しない (SunOS)
    ディレクトリ: 削除制限フラグ (SVID-v4.2)
0400S_ISGID 002000実行時の set-group-ID (V7)
    ディレクトリに対しては GID の伝達に
    BSD 方式を使用する
0400S_ENFMT 002000SysV ファイル・ロックを強制する
    (S_ISGID と共有)
0800S_ISUID 004000実行時の set-user-ID (V7)
0800S_CDF 004000ディレクトリが状況依存ファイル (HP-UX)

スティッキー コマンドは Version 32V AT&T UNIX で登場した。

注意


Linux での注意

カーネル 2.5.48 以降では、 stat 構造体は 3つのファイルのタイムスタンプ関連のフィールドで ナノ秒単位の精度に対応している。 glibc では、各フィールドのナノ秒の情報を st_atim.tv_nsecst_atimensec といった形で参照できる。 機能検査マクロ _BSD_SOURCE か _SVID_SOURCE が定義されている場合には st_atim.tv_nsec の形式で、それ以外の場合には st_atimensec の形式となる。 秒より細かいタイムスタンプをサポートしていないファイルシステムでは、 これらのナノ秒のフィールドは 0 に設定される。

/proc ディレクトリ以下にあるファイルのほとんどでは、 stat() を呼び出した際に、 st_size フィールドにファイルサイズが返されない。 代わりに st_size フィールドには 0 が返される。


以下のプログラムは stat(2) を呼び出し、返ってきた 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_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 i-node 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); }

関連項目


access(2), chmod(2), chown(2), fstatat(2), readlink(2), utime(2), capabilities(7)

openSUSE Logo

コンテンツ