UNIX编程学习日记

OS version:Linux version 2.6.18-194.11.3.el5

     菜鸟一枚,记自己学习linux的一些收获,写的不好莫喷哈,今天在看文件系统,对于stat这个结构体很好奇,于是写了些小程序显示stat结构体中某些成员变量发现显示的结果半对半错。

     感觉自己没有写错,于是先查询了sys/stat.h,没有找到stat结构体!但其开头包含了bits/stat.h文件,于是在此文件中找到了stat的定义如下:

 1 struct stat
 2    {
 3      __dev_t st_dev;            /* Device.  */
 4      unsigned short int __pad1;
 5  #ifndef __USE_FILE_OFFSET64
 6      __ino_t st_ino;            /* File serial number.    */
 7  #else
 8      __ino_t __st_ino;            /* 32bit file serial number.    */
 9  #endif
10      __mode_t st_mode;            /* File mode.  */
11      __nlink_t st_nlink;            /* Link count.  */
12      __uid_t st_uid;            /* User ID of the file's owner.    */
13      __gid_t st_gid;            /* Group ID of the file's group.*/
14      __dev_t st_rdev;            /* Device number, if device.  */
15      unsigned short int __pad2;
16  #ifndef __USE_FILE_OFFSET64
17      __off_t st_size;            /* Size of file, in bytes.  */
18  #else
19      __off64_t st_size;            /* Size of file, in bytes.  */
20  #endif
21      __blksize_t st_blksize;        /* Optimal block size for I/O.  */
22  
23  #ifndef __USE_FILE_OFFSET64
24      __blkcnt_t st_blocks;        /* Number 512-byte blocks allocated. */
25  #else
26      __blkcnt64_t st_blocks;        /* Number 512-byte blocks allocated. */
27  #endif
28  #ifdef __USE_MISC
29      /* Nanosecond resolution timestamps are stored in a format
30         equivalent to 'struct timespec'.  This is the type used
31         whenever possible but the Unix namespace rules do not allow the
32         identifier 'timespec' to appear in the <sys/stat.h> header.
33         Therefore we have to handle the use of this header in strictly
34         standard-compliant sources special.  */
35      struct timespec st_atim;        /* Time of last access.  */
36      struct timespec st_mtim;        /* Time of last modification.  */
37      struct timespec st_ctim;        /* Time of last status change.  */
38  # define st_atime st_atim.tv_sec    /* Backward compatibility.  */
39  # define st_mtime st_mtim.tv_sec
40  # define st_ctime st_ctim.tv_sec
41  #else
42      __time_t st_atime;            /* Time of last access.  */
43      unsigned long int st_atimensec;    /* Nscecs of last access.  */
44      __time_t st_mtime;            /* Time of last modification.  */
45      unsigned long int st_mtimensec;    /* Nsecs of last modification.  */
46      __time_t st_ctime;            /* Time of last status change.  */
47      unsigned long int st_ctimensec;    /* Nsecs of last status change.  */
48  #endif
49  #ifndef __USE_FILE_OFFSET64
50      unsigned long int __unused4;
51      unsigned long int __unused5;
52  #else
53      __ino64_t st_ino;            /* File serial number.    */
54  #endif
55    };

     stat结构体用于存放文件有关信息结构,这里我想把一个文件的一些信息输出,看看到底是什么,比如st_mode,所以自己写个程序输出信息。

     其中apue.h相信大家都不陌生,errlib.h是我自己建的一个头文件,存放一些错误处理函数。mystat.c代码如下:

 1 #include "apue.h"
 2  #include "errlib.h"
 3  #include <sys/stat.h>
 4  #include <fcntl.h>
 5  
 6  int main(int argc,char* argv[])
 7  {
 8      if(argc<2)
 9          err_sys("Too few arguments!");
10      int res,n;
11      struct stat buf;
12  
13      if((res= open(argv[1],O_RDONLY))==-1)
14          err_sys("file open error!");
15  
16      if((n=fstat(res,&buf))==-1)
17          err_sys("fstat error!");
18      
19      printf("st_mode:%d\n",buf.st_mode);
20      
21      printf("user id:%d\n",buf.st_uid);
22  
23      printf("st_dev:%d\n",buf.st_dev);
24  
25      close(res);
26      return 0;
27  }

执行./mystat,结果如下:

输出结果中对于普通文件,st_mode:33188,对于目录文件testdir,st_mode为16877,这是为神马呢??

XiaoH将这两个数划为2进制,33188->1000 0001 1010 0100;16877->0100 0001 1110 1101

对于UNIX系统定义了一系列文件相关的宏,用于表示文件的类型,拥有者、组、其他的权限,即目录中的RWX的信息等:

S_IFMT     0170000   bitmask for the file type bitfields
S_IFSOCK   0140000   socket
S_IFLNK    0120000   symbolic link
S_IFREG    0100000   regular file
S_IFBLK    0060000   block device
S_IFDIR    0040000   directory
S_IFCHR    0020000   character device
S_IFIFO    0010000   fifo
S_ISUID    0004000   set UID bit
S_ISGID    0002000   set GID bit (see below)
S_ISVTX    0001000   sticky bit (see below)
S_IRWXU    00700     mask for file owner permissions
S_IRUSR    00400     owner has read permission
S_IWUSR    00200     owner has write permission
S_IXUSR    00100     owner has execute permission
S_IRWXG    00070     mask for group permissions
S_IRGRP    00040     group has read permission
S_IWGRP    00020     group has write permission
S_IXGRP    00010     group has execute permission
S_IRWXO    00007     mask for permissions for others (not in group)
S_IROTH    00004     others have read permission
S_IWOTH    00002     others have write permisson
S_IXOTH    00001     others have execute permission

    可XiaoH怎么也看不明白33188和16877的二进制表示和这些宏的数字是怎么关联起来的......7位16进制数???这是神马???

  好吧于是查书,发现很多chmod命令中使用的是2777,4777这种类似的参数,然后一查就跪了...原来上面的数都不是16进制,而是8进制!!!

  在文件权限方面的参数竟然设置的是3位8进制,当时我就吐血了,大叹自己2B.....

    好了,现在就可以解释了,33188按3位8进制,应写成:000 001 000 000 110 100 100 ,这个结果就是文件类型,属主与3类权限的相或所得到。

    即:regularfile root rw-r--r--

    类似16877->000 000 100 000 111 101 101,即 dirfile root rwxr-xr-x 大功告成~~~!汗,算搞清楚了一点东西吧~~~

原文地址:https://www.cnblogs.com/XiaoHDeBlog/p/2804796.html