免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2792 | 回复: 0
打印 上一主题 下一主题

Unix文件系统研究、四 文件类型 用户权限 [复制链接]

论坛徽章:
1
15-16赛季CBA联赛之北控
日期:2022-03-04 22:35:50
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-03-29 10:43 |只看该作者 |倒序浏览

Unix文件系统研究、四 文件类型 用户权限

关键词: ScoUnix 文件系统 文件类型 用户权限

在《文件系统研究、一 i节点》中提到了i节点的结构,如下
struct dinode
{
ushort di_mode;  /*文件类型+用户权限*/
……
time_t di_ctime; /*创建时间*/
};

ushort di_mode是16位2进制数,保存的就是文件类型及用户权限信息,具体结构如下:
            4             8             12            16




u
g
s
r
w
x
r
w
x
r
w
x

第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) */
下面予以解释:
文件类型占4位




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位,如下图。
r
w
x
又有 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------------------------

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/31/showart_511183.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP