获取文件信息: 大小, 文件类型等.

  1. stat

    • 说明

      • 主要是文件信息.即关于文件本身的信息.
    • 来源

      • 从文件系统中获取.bits/stat.h + sys/stat.h
  2. 解析

    • struct stat

      struct stat
       {
         __dev_t st_dev;     /* Device.  */
      #ifndef __x86_64__
         unsigned short int __pad1;
      #endif
      #if defined __x86_64__ || !defined __USE_FILE_OFFSET64
         __ino_t st_ino;     /* File serial number.  */
      #else
         __ino_t __st_ino;           /* 32bit file serial number.    */
      #endif
      #ifndef __x86_64__
         __mode_t st_mode;           /* File mode.  */
         __nlink_t st_nlink;         /* Link count.  */
      #else
         __nlink_t st_nlink;     /* Link count.  */
         __mode_t st_mode;       /* File mode.  */
      #endif
         __uid_t st_uid;     /* User ID of the file's owner. */
         __gid_t st_gid;     /* Group ID of the file's group.*/
      #ifdef __x86_64__
         int __pad0;
      #endif
         __dev_t st_rdev;        /* Device number, if device.  */
      #ifndef __x86_64__
         unsigned short int __pad2;
      #endif
      #if defined __x86_64__ || !defined __USE_FILE_OFFSET64
         __off_t st_size;            /* Size of file, in bytes.  */
      #else
         __off64_t st_size;          /* Size of file, in bytes.  */
      #endif
         __blksize_t st_blksize; /* Optimal block size for I/O.  */
      #if defined __x86_64__  || !defined __USE_FILE_OFFSET64
         __blkcnt_t st_blocks;       /* Number 512-byte blocks allocated. */
      #else
         __blkcnt64_t st_blocks;     /* Number 512-byte blocks allocated. */
      #endif
      #ifdef __USE_XOPEN2K8
         /* Nanosecond resolution timestamps are stored in a format
            equivalent to 'struct timespec'.  This is the type used
            whenever possible but the Unix namespace rules do not allow the
            identifier 'timespec' to appear in the <sys/stat.h> header.
            Therefore we have to handle the use of this header in strictly
            standard-compliant sources special.  */
         struct timespec st_atim;        /* Time of last access.  */
         struct timespec st_mtim;        /* Time of last modification.  */
         struct timespec st_ctim;        /* Time of last status change.  */
      # define st_atime st_atim.tv_sec    /* Backward compatibility.  */
      # define st_mtime st_mtim.tv_sec
      # define st_ctime st_ctim.tv_sec
      #else
         __time_t st_atime;          /* Time of last access.  */
         __syscall_ulong_t st_atimensec; /* Nscecs of last access.  */
         __time_t st_mtime;          /* Time of last modification.  */
         __syscall_ulong_t st_mtimensec; /* Nsecs of last modification.  */
         __time_t st_ctime;          /* Time of last status change.  */
         __syscall_ulong_t st_ctimensec; /* Nsecs of last status change.  */
      #endif
      #ifdef __x86_64__
         __syscall_slong_t __glibc_reserved[3];
      #else
      # ifndef __USE_FILE_OFFSET64
         unsigned long int __glibc_reserved4;
         unsigned long int __glibc_reserved5;
      # else
         __ino64_t st_ino;           /* File serial number.  */
      # endif
      #endif
       };
      
      • st_dev 设备号,即硬盘设备.

      • st_ino 文件在文件系统中的inode, 即文件系统中的文件编号.

      • st_mode 底下详解.

      • st_nlink 同一个文件系统下的硬链接数量.

      • st_uid 文件所属用户id

      • st_gid 文件所属组id

      • st_rdev 字符设备或者块设备才有.

      • st_size 普通文件则是文件大小; 符号链接则是符号链接保存的路径长度; 共享内存文件则是共享内存大小, 字节; typed memory同样是内存大小,字节; 其他文件类型则无内容.

      • st_atim 最后一次被访问(读)时间, 精确到微秒.

      • st_mtim 最后一次被修改(写)时间, 精确到微秒.

      • st_ctim 最后一次被修改文件属性(chmod)时间, 精确到微秒.

      • st_blksize 当前文件系统最优文件块大小.不同系统大小可能不同.

      • st_blocks 当前文件占用文件块.

    • st_mode

      • 首先是位运算进行组合.

      #define __S_IFDIR   0040000 /* Directory.  */
      #define __S_IFCHR   0020000 /* Character device.  */
      #define __S_IFBLK   0060000 /* Block device.  */
      #define __S_IFREG   0100000 /* Regular file.  */
      #define __S_IFIFO   0010000 /* FIFO.  */
      #define __S_IFLNK   0120000 /* Symbolic link.  */
      #define __S_IFSOCK  0140000 /* Socket.  */
      #define    __S_IFMT    0170000 /* These bits determine file type.  */
      
      • 八进制. 表示文件类型.

      • 通过和S_FIMT进行位于,然后switch获取对应类型.

            S_IFMT      Type of file.
                        S_IFBLK     Block special.
                        S_IFCHR     Character special.
                        S_IFIFO     FIFO special.
                        S_IFREG     Regular.
                        S_IFDIR     Directory.
                        S_IFLNK     Symbolic link.
                        S_IFSOCK    Socket.
      
      • 其他信息
      #define __S_ISUID   04000   /* Set user ID on execution.  */
      #define __S_ISGID   02000   /* Set group ID on execution.  */
      #define __S_ISVTX   01000   /* Save swapped text after use (sticky).  */
      #define __S_IREAD   0400    /* Read by owner.  */
      #define __S_IWRITE  0200    /* Write by owner.  */
      #define __S_IEXEC   0100    /* Execute by owner.  */
      
      
      • 文件所有者的权限,组权限,其他人的权限. 权限则有: 读写执行任意组合.八进制.
    • 外部使用

      #if defined __USE_MISC || defined __USE_XOPEN
      # define S_IFMT     __S_IFMT
      # define S_IFDIR    __S_IFDIR
      # define S_IFCHR    __S_IFCHR
      # define S_IFBLK    __S_IFBLK
      # define S_IFREG    __S_IFREG
      # ifdef __S_IFIFO
      #  define S_IFIFO   __S_IFIFO
      # endif
      # ifdef __S_IFLNK
      #  define S_IFLNK   __S_IFLNK
      # endif
      # if (defined __USE_MISC || defined __USE_XOPEN_EXTENDED) \
          && defined __S_IFSOCK
      #  define S_IFSOCK  __S_IFSOCK
      # endif
      #endif
      
      /* Test macros for file types.  */
      
      #define __S_ISTYPE(mode, mask)  (((mode) & __S_IFMT) == (mask))
      
      #define S_ISDIR(mode)    __S_ISTYPE((mode), __S_IFDIR)
      #define S_ISCHR(mode)    __S_ISTYPE((mode), __S_IFCHR)
      #define S_ISBLK(mode)    __S_ISTYPE((mode), __S_IFBLK)
      #define S_ISREG(mode)    __S_ISTYPE((mode), __S_IFREG)
      #ifdef __S_IFIFO
      # define S_ISFIFO(mode)  __S_ISTYPE((mode), __S_IFIFO)
      #endif
      #ifdef __S_IFLNK
      # define S_ISLNK(mode)   __S_ISTYPE((mode), __S_IFLNK)
      #endif
      
      #if defined __USE_MISC && !defined __S_IFLNK
      # define S_ISLNK(mode)  0
      #endif
      
      #if (defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K) \
         && defined __S_IFSOCK
      # define S_ISSOCK(mode) __S_ISTYPE((mode), __S_IFSOCK)
      #elif defined __USE_XOPEN2K
      # define S_ISSOCK(mode) 0
      #endif
      
      /* These are from POSIX.1b.  If the objects are not implemented using separate
        distinct file types, the macros always will evaluate to zero.  Unlike the
        other S_* macros the following three take a pointer to a `struct stat'
        object as the argument.  */
      #ifdef  __USE_POSIX199309
      # define S_TYPEISMQ(buf) __S_TYPEISMQ(buf)
      # define S_TYPEISSEM(buf) __S_TYPEISSEM(buf)
      # define S_TYPEISSHM(buf) __S_TYPEISSHM(buf)
      #endif
      
      
      /* Protection bits.  */
      
      #define S_ISUID __S_ISUID   /* Set user ID on execution.  */
      #define S_ISGID __S_ISGID   /* Set group ID on execution.  */
      
      #if defined __USE_MISC || defined __USE_XOPEN
      /* Save swapped text after use (sticky bit).  This is pretty well obsolete.  */
      # define S_ISVTX    __S_ISVTX
      #endif
      
      #define S_IRUSR __S_IREAD   /* Read by owner.  */
      #define S_IWUSR __S_IWRITE  /* Write by owner.  */
      #define S_IXUSR __S_IEXEC   /* Execute by owner.  */
      /* Read, write, and execute by owner.  */
      #define S_IRWXU (__S_IREAD|__S_IWRITE|__S_IEXEC)
      
      #ifdef __USE_MISC
      # define S_IREAD    S_IRUSR
      # define S_IWRITE   S_IWUSR
      # define S_IEXEC    S_IXUSR
      #endif
      
      #define S_IRGRP (S_IRUSR >> 3)  /* Read by group.  */
      #define S_IWGRP (S_IWUSR >> 3)  /* Write by group.  */
      #define S_IXGRP (S_IXUSR >> 3)  /* Execute by group.  */
      /* Read, write, and execute by group.  */
      #define S_IRWXG (S_IRWXU >> 3)
      
      #define S_IROTH (S_IRGRP >> 3)  /* Read by others.  */
      #define S_IWOTH (S_IWGRP >> 3)  /* Write by others.  */
      #define S_IXOTH (S_IXGRP >> 3)  /* Execute by others.  */
      /* Read, write, and execute by others.  */
      #define S_IRWXO (S_IRWXG >> 3)
      
      
      #ifdef  __USE_MISC
      /* Macros for common mode bit masks.  */
      # define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) /* 0777 */
      # define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)/* 07777 */
      # define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)/* 0666*/
      
      # define S_BLKSIZE  512 /* Block size for `st_blocks'.  */
      #endif
      
      • 定义了一些宏定义和一些简便使用方式.

  3. 案例

    • 执行

      ch@chvm:~/ch/cppfile/test$ gdb -q ./a.out
      Reading symbols from ./a.out...done.
      (gdb) b main
      Breakpoint 1 at 0x705: file test.cpp, line 5.
      (gdb) r
      Starting program: /home/ch/ch/cppfile/test/a.out
      
      Breakpoint 1, main () at test.cpp:5
      5       int main() {
      (gdb) n
      6         const char* pathname = "/root";
      (gdb)
      9         if( stat( pathname, &info ) != 0 )
      (gdb)
      11        else if( info.st_mode & S_IFDIR )
      (gdb) p info
      $1 = {st_dev = 2049, st_ino = 6029313, st_nlink = 5, st_mode = 16832, st_uid = 0, st_gid = 0, __pad0 = 0, st_rdev = 0,
       st_size = 4096, st_blksize = 4096, st_blocks = 8, st_atim = {tv_sec = 1596753951, tv_nsec = 0}, st_mtim = {tv_sec = 1629703454,
         tv_nsec = 266149333}, st_ctim = {tv_sec = 1629703454, tv_nsec = 266149333}, __glibc_reserved = {0, 0, 0}}
      (gdb) !stat /root
       File: /root
       Size: 4096            Blocks: 8          IO Block: 4096   directory
      Device: 801h/2049d      Inode: 6029313     Links: 5
      Access: (0700/drwx------)  Uid: (    0/    root)   Gid: (    0/    root)
      Access: 2020-08-07 06:45:51.000000000 +0800
      Modify: 2021-08-23 15:24:14.266149333 +0800
      Change: 2021-08-23 15:24:14.266149333 +0800
      Birth: -
      (gdb) !cat test.cpp
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <stdio.h>
      
      int main() {
       const char* pathname = "/root";
       struct stat info;
      
       if( stat( pathname, &info ) != 0 )
           printf( "cannot access %s\n", pathname );
       else if( info.st_mode & S_IFDIR )
           printf( "%s is a directory\n", pathname );
       else if( info.st_mode & S_IFREG )
           printf( "%s is a file\n", pathname );
       else
           printf( "%s is no directory\n", pathname );
      }
      
      • 首先是编译.

      • 设置断点.

      • 执行获取信息.

      • 这里的st_mode值为16832,应该使用宏定义S_ISDIR(info.st_mode).

      • 然后通过指令获取,和程序执行进行对比.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值