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 大功告成~~~!汗,算搞清楚了一点东西吧~~~