stat関数とstat構造体
stat関数は、ファイルやディレクトリについての情報を返す。
デバイスとかを触るには知っておかないといけませんね。
といっても、stat()で得られるstat構造体は、中身を見てみないと何かよくわかりません。
(manを読めば何の意味を持つのか、はある程度わかるけど)
なので、とりあえず、statで情報を出力するプログラムを作ってみました。
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> void print_stat(struct stat *st) { printf("st_dev: %10d\n", (int)st->st_dev); printf("st_ino: %10d\n", (int)st->st_ino); printf("st_mode: %10d\n", (int)st->st_mode); printf("st_nlink: %10d\n", (int)st->st_nlink); printf("st_uid: %10d\n", (int)st->st_uid); printf("st_gid: %10d\n", (int)st->st_gid); printf("st_rdev: %10d\n", (int)st->st_rdev); printf("st_size: %10d\n", (int)st->st_size); printf("st_blksize: %10d\n", (int)st->st_blksize); printf("st_blocks: %10d\n", (int)st->st_blocks); printf("st_atime: %10d\n", (int)st->st_atime); printf("st_mtime: %10d\n", (int)st->st_mtime); printf("st_ctime: %10d\n", (int)st->st_ctime); } void check_stat(struct stat *st) { mode_t m = st->st_mode; if (S_ISREG(m)) { printf("this is a regular file\n"); } if (S_ISDIR(m)) { printf("this is a directory\n"); } if (S_ISCHR(m)) { printf("this is a character device\n"); } if (S_ISBLK(m)) { printf("this is a block device\n"); } if (S_ISFIFO(m)) { printf("this is a FIFO\n"); } if (S_ISLNK(m)) { printf("this is a symbolic link\n"); } if (S_ISSOCK(m)) { printf("this is a socket\n"); } } int main(int argc, char *argv[]) { struct stat st; if (argc != 2) { return -1; } if (stat(argv[1], &st) == -1) { return -1; } print_stat(&st); check_stat(&st); return 0; }
これで、実行してみる。
普通のファイルの場合
$ ./check_stat check_stat.c st_dev: 2049 st_ino: 12225749 st_mode: 33188 st_nlink: 1 st_uid: 1000 st_gid: 1000 st_rdev: 0 st_size: 1514 st_blksize: 4096 st_blocks: 8 st_atime: 1208023991 st_mtime: 1208023985 st_ctime: 1208023985 this is a regular file
ほうほう。
INODE番号やモードは数字をそのまま見てもわかりませんな。
ディレクトリ
$ ./check_stat /etc st_dev: 2049 st_ino: 8585217 st_mode: 16877 st_nlink: 147 st_uid: 0 st_gid: 0 st_rdev: 0 st_size: 12288 st_blksize: 4096 st_blocks: 24 st_atime: 1207954697 st_mtime: 1207839560 st_ctime: 1207839560 this is a directory
UID、GIDは0になるのね。
シンボリックリンク
stat()そのままだと、リンク先のファイルまたはディレクトリの情報が出力されるので、シンボリックリンクそのものの情報を出力させたい場合は、以下のようにlstat()を使う。
if (lstat(argv[1], &st) == -1) {
で、出力。
$ ./check_stat vd st_dev: 2049 st_ino: 12225746 st_mode: 41471 st_nlink: 1 st_uid: 1000 st_gid: 1000 st_rdev: 0 st_size: 5 st_blksize: 4096 st_blocks: 0 st_atime: 1208024315 st_mtime: 1208023949 st_ctime: 1208023949 this is a symbolic link
おおお、ちゃんとシンボリックリンクだと解釈してくれましたね。