名前
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) 参照):
/* 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
- glibc 2.10 以降:
- _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
- glibc 2.10 より前:
- _ATFILE_SOURCE
説明
これらの関数は、ファイルについての情報を stat が指すバッファーに格納して返す。 ファイルそのものに対するアクセス許可は必要としないが、 — stat(), fstatat(), lstat() の場合には —そのファイルへ至る pathname を構成する全てのディレクトリに対する実行 (検索) 許可が必要である。 stat() と fstatat() は pathname が指すファイルに関する情報を取得する。 fstatat() の違いについては後で説明する。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 };
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 |
したがって、(例えば) 通常のファイルかどうかを検査するには、以下のようにすればよい。
上記の形の検査はよくあるので、 POSIX では以下のマクロが定義されており、 st_mode のファイル種別の検査をより簡単に書けるようになっている。
stat(pathname, &sb); if ((sb.st_mode & S_IFMT) == S_IFREG) { /* Handle regular file */ }
- 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 にはない)
上記のほとんどのファイル種別検査マクロの定義は、 機能検査マクロ _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 以上で定義された場合にも公開される。
stat(pathname, &sb); if (S_ISREG(sb.st_mode)) { /* Handle regular file */ }
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() と全く同様に動作するが、以下で説明する点が異なる。- 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() と同様に、シンボリックリンクの展開を行う)。
返り値
成功した場合、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() を呼び出した場合である。
- 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.他のシステム
各種システムで使用されていた(いる)値: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) |
注意
Linux では、 lstat() は一般には自動マウント動作 (automounter action) の きっかけとならないが、 stat() はきっかけとなる ( を参照)。タイムスタンプフィールド
古いカーネルや古い標準では、ナノ秒精度のタイムスタンプフィールドはサポートされていなかった。 代わりに 3 つの time_t 型のタイムスタンプフィールド st_atime, st_mtime, and st_ctime があった。これらのフィールドには 1 秒単位のタイムスタンプが記録されていた。背後のカーネルインターフェース
時間の経過とともに、 stat 構造体のサイズが大きくなり、この影響で stat() には 3つのバージョンが存在する: sys_stat() (スロットは __NR_oldstat)、 sys_newstat() (スロットは __NR_stat)、 sys_stat64() (カーネル 2.4 で導入; スロットは __NR_stat64). glibc の stat() ラッパー関数はこれらの詳細をアプリケーションから隠蔽してくれる。 具体的には、カーネルが提供しているシステムコールのうち最新のバージョンを 起動し、古いバイナリの場合には必要に応じて返された情報を再構成 (repack) する。 fstat() と lstat() についても同様である。例
以下のプログラムは 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/ に書かれている。2014-08-19 | Linux |