在《文件系统研究、一 i节点》中提到了i节点的结构,如下
struct dinode
{
ushort di_mode; /*文件类型+用户权限*/
……
time_t di_ctime; /*创建时间*/
};
ushort di_mode是16位2进制数,保存的就是文件类型及用户权限信息,具体结构如下:
4 8 12 16
第1-4 位 -- 文件类型位
第5位 -- suid位
第6位 -- sgid位
第7位 -- sticky位
第8-10位 -- 文件属主权限位
第11-13 -- 文件属组权限位
第14-16 -- 其他用户权限位
1、文件类型分类
d -- 目录文件 f -- 普通文件 b -- 块设备文件 c -- 字符设备文件 l -- 链接文件
用l -l命令可以看到,红色字符部分就是文件类型:
例如:
576# l -lWv /tmp
total 22
-rw-r--r-- 1 root sys 6 Jul 5 05:39 abcnew
drwxr-xr-x 2 root sys 512 Jul 5 07:38 test
2、文件类型位算法
从系统头文件/usr/include/sys/stat.h,可以获取如下宏定义:
/*
* st_mode flags
*/
#define S_IFMT 0170000 /* type of file ,文件类型掩码*/
#define S_IFREG 0100000 /* regular 普通文件*/
#define S_IFBLK 0060000 /* block special 块设备文件*/
#define S_IFDIR 0040000 /* directory 目录文件*/
#define S_IFCHR 0020000 /* character special 字符设备文件*/
#define S_IFIFO 0010000 /* fifo */
#define S_IFNAM 0050000 /* special named file */
#if !defined(_M_XOUT)
#define S_IFLNK 0120000 /* symbolic link 链接文件*/
#endif /* !defined(_M_XOUT) */
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
#if !defined(_M_XOUT)
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif /* !defined(_M_XOUT) */
下面予以解释:
a、#define S_IFMT 0170000 -- 文件类型掩码宏,0170000以0开头,表示这是一个8进制数,转换成2进制,正好是 1 111 000 000 000 000 ,高4位全置1;
b、#define S_IFREG 0100000 -- 普通文件类型掩码,0100000,转换成2进制,1 000 000 000 000 000,最高位置1;
c、#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -- 判断文件是否普通文件的宏函数
举例说明:m值即为我们取到ushort di_mode,假设其2进制值为 0 011 000 000 000 000,对应的8进制为 060000 。
S_ISREG(0060000) 即 (((0060000) & 0170000 ) == 0100000) ,该值返回False,则代表该文件不是普通文件。
注意:这里用到的就是掩码算法,这种算法在C、C++里比比皆是,下次具文讨论其优劣。
3、文件权限:
文件权限分 属主权限、属主组权限、其他用户权限三种;
修改权限使用chmod命令,例如chmod 666 * ,或者chmod 777 * ;
问题:大家都知道666代表给所有用户赋予读写权限,777给所有用户赋予读写执行权限,但是知道为什么是666 ,而不是555呢?
举例说明:
584# chmod 666 abcnew
585# l abcnew
-rw-rw-rw- 1 root sys 6 Jul 5 05:39 abcnew
586# chmod 222 abcnew
587# l abcnew
--w--w--w- 1 root sys 6 Jul 5 05:39 abcnew
588# chmod 444 abcnew
589# l abcnew
-r--r--r-- 1 root sys 6 Jul 5 05:39 abcnew
590# chmod 777 abcnew
591# l abcnew
-rwxrwxrwx 1 root sys 6 Jul 5 05:39 abcnew
注意红色字体部分权限变化。
4、权限位组合算法
前面提到,属主权限位占3位,如下图。
又有 2^0 = 1,执行权限 x ;
2^1 = 2 ,写权限 w;
2^2 = 4 ,读权限 r。
2^1 + 2^2 = 6 ,读写权限 rw;
2^0 + 2^1 + 2^2 = 7 ,执行 写 读权限 rwx ;
属主用户组权限,其他用户权限采用的是同样的算法,所以就有666,777之类;
到此,有关文件类型及权限的讨论结束,贴上一个小程序,检验下:
#include
#include
#include
#include
main()
{
DIR * dir;
struct dirent * ptr;
int i;
char type,sFileName[50];
struct stat stbuf;
dir =opendir("/tmp");
while((ptr = readdir(dir))!=NULL)
{
snprintf(sFileName,sizeof(sFileName), "/%s/%s", "tmp", ptr->d_name);
lstat(sFileName, &stbuf);
/*
d -- 目录文件 f -- 普通文件
b -- 块设备文件 c -- 字符设备文件
l -- 链接文件
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
#if !defined(_M_XOUT)
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
*/
if ( S_ISREG(stbuf.st_mode) )
type = '-';
else if (S_ISBLK(stbuf.st_mode))
type = 'b' ;
else if (S_ISDIR(stbuf.st_mode))
type = 'd' ;
else if (S_ISCHR(stbuf.st_mode))
type = 'c' ;
else if (S_ISFIFO(stbuf.st_mode))
type = 'f' ;
else if (S_ISNAM(stbuf.st_mode))
type = 'n';
else if (S_ISLNK(stbuf.st_mode))
type = 'n';
printf("[type:%c][d_name:%12s] [d_ino:%8ld] [off_t:%4ld] [d_reclen:%4ld]\n",type,ptr->d_name,ptr->d_ino,ptr->d_off,ptr->d_reclen);
}
}
-----------End------------------------
阅读(8808) | 评论(0) | 转发(0) |