今回は、stat関数を使います。
まずは、man 2 statの冒頭です。
STAT(2) Linux Programmer's Manual STAT(2) 名前 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);
型が分かったので、statをコールするプログラムを作ります。
takk@deb9:~/tmp$ cat -n mystat.c 1 #include <sys/types.h> 2 #include <sys/stat.h> 3 #include <unistd.h> 4 5 int main(int argc, char* argv[]) 6 { 7 struct stat buf; 8 char* filename; 9 10 filename = argv[1]; 11 12 stat(filename, buf); 13 14 return 0; 15 } takk@deb9:~/tmp$
まあ、後はgdbで値を見ていけば、bufの使い方は分かってくるでしょう。ということで、-g付きでビルドします。
takk@deb9:~/tmp$ gcc -g mystat.c mystat.c: In function ‘main’: mystat.c:12:17: error: incompatible type for argument 2 of ‘stat’ stat(filename, buf); ^~~ In file included from mystat.c:2:0: /usr/include/x86_64-linux-gnu/sys/stat.h:208:12: note: expected ‘struct stat * restrict’ but argument is of type ‘struct stat’ extern int stat (const char *__restrict __file, ^~~~ takk@deb9:~/tmp$
エラーになりました。ポインタだといってるのに、ポインタにしてないからです。
struct stat bufがスカラーになってます。配列に変えます。
テキストエディタを開くのが面倒なので、sedで置換。
takk@deb9:~/tmp$ sed 's/buf;/buf[1];/' -i mystat.c takk@deb9:~/tmp$ cat -n mystat.c 1 #include <sys/types.h> 2 #include <sys/stat.h> 3 #include <unistd.h> 4 5 int main(int argc, char* argv[]) 6 { 7 struct stat buf[1]; 8 char* filename; 9 10 filename = argv[1]; 11 12 stat(filename, buf); 13 14 return 0; 15 } takk@deb9:~/tmp$
改めて、ビルドします。
takk@deb9:~/tmp$ !g gcc -g mystat.c takk@deb9:~/tmp$
gdbで動かす前に、statをかけるファイルを作成。
takk@deb9:~/tmp$ echo -n 123>test.bin takk@deb9:~/tmp$
gdbを起動します。set argsでtest.binも指定しておきます。
takk@deb9:~/tmp$ gdb a.out ~省略~ (gdb) b main Breakpoint 1 at 0x6c8: file mystat.c, line 10. (gdb) set args test.bin (gdb) r Starting program: /home/takk/tmp/a.out test.bin Breakpoint 1, main (argc=2, argv=0x7fffffffe5b8) at mystat.c:10 10 filename = argv[1]; (gdb) n 12 stat(filename, buf); (gdb) 14 return 0; (gdb)
statをコール後、bufの中身を表示してみました。
(gdb) p buf $1 = {{st_dev = 2049, st_ino = 1739370, st_nlink = 1, st_mode = 33188, st_uid = 1000, st_gid = 1000, __pad0 = 0, st_rdev = 0, st_size = 0, st_blksize = 4096, st_blocks = 0, st_atim = {tv_sec = 1523796082, tv_nsec = 116000000}, st_mtim = {tv_sec = 1523796082, tv_nsec = 116000000}, st_ctim = {tv_sec = 1523796082, tv_nsec = 116000000}, __glibc_reserved = {0, 0, 0}}} (gdb)
各メンバのことは、statコマンドを参考に見ていけば、分かりそうです。
takk@deb9:~/tmp$ stat test.bin File: test.bin Size: 0 Blocks: 0 IO Block: 4096 通常の空ファイル Device: 801h/2049d Inode: 1739370 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1000/ takk) Gid: ( 1000/ takk) Access: 2018-04-15 21:41:22.116000000 +0900 Modify: 2018-04-15 21:41:22.116000000 +0900 Change: 2018-04-15 21:41:22.116000000 +0900 Birth: - takk@deb9:~/tmp$
続く
コメント