linux s类型文件夹,Unix文件系统研究、四 文件类型 用户权限 S_IFREG S_IFMT

在《文件系统研究、一 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#includemain()

{

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------------------------

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值