stat構造体は何処

7-1.ファイル・アーカイブ

stat関数を使う(その2)
stat関数を使う

で見てきたstat構造体は、実際どのような構造になってるのでしょう。
man 2 statで確認。

      これらのシステムコールはいずれも、結果を 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;  /* 割り当てられた 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
           };

まあこれで十分なんですが、ヘッダがどこにあるか知りたいです。
カーネルのソースなので、そちらから探します。

takk@deb9:~$ cd /usr/src/linux
takk@deb9:/usr/src/linux$ 

メンバであるst_devでひっかけます。

takk@deb9:/usr/src/linux$ grep -rl 'st_dev;' *
arch/alpha/kernel/osf_sys.c
arch/alpha/include/uapi/asm/stat.h
arch/sparc/include/uapi/asm/stat.h
arch/sparc/include/asm/compat.h
arch/arm/kernel/sys_oabi-compat.c
arch/arm/include/uapi/asm/stat.h
arch/arm64/include/asm/compat.h
arch/arm64/include/asm/stat.h
arch/m68k/include/uapi/asm/stat.h
arch/um/include/shared/os.h
arch/ia64/include/uapi/asm/stat.h
arch/cris/include/uapi/asm/stat.h
arch/mips/include/uapi/asm/stat.h
arch/mips/include/asm/compat.h
arch/sh/include/uapi/asm/stat.h
arch/parisc/include/uapi/asm/stat.h
arch/parisc/include/asm/compat.h
arch/powerpc/include/uapi/asm/stat.h
arch/powerpc/include/asm/compat.h
arch/avr32/include/uapi/asm/stat.h
arch/m32r/include/uapi/asm/stat.h
arch/x86/include/uapi/asm/stat.h
arch/x86/include/asm/compat.h
arch/x86/include/asm/ia32.h
arch/frv/include/uapi/asm/stat.h
arch/blackfin/include/uapi/asm/stat.h
arch/s390/kernel/compat_linux.c
arch/s390/include/uapi/asm/stat.h
arch/s390/include/asm/compat.h
arch/xtensa/include/uapi/asm/stat.h
arch/mn10300/include/uapi/asm/stat.h
drivers/crypto/caam/jr.c
drivers/misc/vmw_vmci/vmci_host.c
drivers/scsi/storvsc_drv.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/scsi_lib.c
drivers/ata/ahci.h
drivers/media/dvb-frontends/stv090x.c
drivers/media/platform/vsp1/vsp1_entity.h
drivers/target/target_core_xcopy.c
drivers/target/target_core_xcopy.h
drivers/net/arcnet/com20020.h
drivers/staging/most/hdm-usb/hdm_usb.c
drivers/ide/ide.c
fs/nfsd/vfs.c
fs/exofs/ore.c
fs/exofs/ore_raid.c
fs/exofs/exofs.h
include/uapi/asm-generic/stat.h
include/scsi/osd_ore.h
include/scsi/scsi_host.h
include/linux/nubus.h
include/net/dsa.h
net/ipv4/ipconfig.c
sound/soc/intel/skylake/skl-sst-dsp.c
sound/soc/intel/common/sst-firmware.c
sound/soc/intel/common/sst-dsp-priv.h
takk@deb9:/usr/src/linux$ 

結果からなんとなく、stat.hが怪しいです。各プロセッサ別にヘッダが存在してるっぽく、かつ一番分かりやすい名前といえば、stat.hってことで。

findでstat.hの一覧を取得。

takk@deb9:/usr/src/linux$ find -name stat.h
./arch/alpha/include/uapi/asm/stat.h
./arch/sparc/include/uapi/asm/stat.h
./arch/arm/include/uapi/asm/stat.h
./arch/arm64/include/uapi/asm/stat.h
./arch/arm64/include/asm/stat.h
./arch/m68k/include/uapi/asm/stat.h
./arch/score/include/uapi/asm/stat.h
./arch/ia64/include/uapi/asm/stat.h
./arch/cris/include/uapi/asm/stat.h
./arch/mips/include/uapi/asm/stat.h
./arch/sh/include/uapi/asm/stat.h
./arch/parisc/include/uapi/asm/stat.h
./arch/tile/include/uapi/asm/stat.h
./arch/powerpc/include/uapi/asm/stat.h
./arch/avr32/include/uapi/asm/stat.h
./arch/m32r/include/uapi/asm/stat.h
./arch/x86/include/uapi/asm/stat.h
./arch/frv/include/uapi/asm/stat.h
./arch/blackfin/include/uapi/asm/stat.h
./arch/microblaze/include/uapi/asm/stat.h
./arch/s390/include/uapi/asm/stat.h
./arch/xtensa/include/uapi/asm/stat.h
./arch/mn10300/include/uapi/asm/stat.h
./tools/perf/util/stat.h
./include/uapi/asm-generic/stat.h
./include/uapi/linux/stat.h
./include/linux/stat.h
takk@deb9:/usr/src/linux$ 

間違いないですね。プロセッサ別にあるので、stat.hにstat構造体が書かれてる推測が有力です。
私のPCはx86なので、以下のヘッダから構造体を抽出します。

./arch/x86/include/uapi/asm/stat.h

struct statはこのようになってました。

struct stat {
        __kernel_ulong_t        st_dev;
        __kernel_ulong_t        st_ino;
        __kernel_ulong_t        st_nlink;

        unsigned int            st_mode;
        unsigned int            st_uid;
        unsigned int            st_gid;
        unsigned int            __pad0;
        __kernel_ulong_t        st_rdev;
        __kernel_long_t         st_size;
        __kernel_long_t         st_blksize;
        __kernel_long_t         st_blocks;      /* Number 512-byte blocks alloca

        __kernel_ulong_t        st_atime;
        __kernel_ulong_t        st_atime_nsec;
        __kernel_ulong_t        st_mtime;
        __kernel_ulong_t        st_mtime_nsec;
        __kernel_ulong_t        st_ctime;
        __kernel_ulong_t        st_ctime_nsec;
        __kernel_long_t         __unused[3];
};

なんだか、man 2 statで書いてあることと違う気がするので、合ってるか分かりません。
前回gdbで確認した構造体の表示を照らし合わせてみます。

(gdb) p buf
$1 = {{st_dev = 0, st_ino = 0, st_nlink = 0, st_mode = 0, st_uid = 0, 
    st_gid = 0, __pad0 = 0, st_rdev = 0, st_size = 0, st_blksize = 15775487, 
    st_blocks = 194, st_atim = {tv_sec = 140737488347039, 
      tv_nsec = 140737488347038}, st_mtim = {tv_sec = 140737348710373, 
      tv_nsec = 1}, st_ctim = {tv_sec = 93824992233293, tv_nsec = 0}, 
    __glibc_reserved = {0, 93824992233216, 93824992232832}}}
(gdb) 

微妙に時間の構造体が違ってる気がします。

続く

コメント

タイトルとURLをコピーしました