- 論壇徽章:
- 1
|
Unix文件系統(tǒng)研究、四 文件類型 用戶權(quán)限
關(guān)鍵詞: ScoUnix 文件系統(tǒng) 文件類型 用戶權(quán)限
在《文件系統(tǒng)研究、一 i節(jié)點(diǎn)》中提到了i節(jié)點(diǎn)的結(jié)構(gòu),如下
struct dinode
{
ushort di_mode; /*文件類型+用戶權(quán)限*/
……
time_t di_ctime; /*創(chuàng)建時(shí)間*/
};
ushort di_mode是16位2進(jìn)制數(shù),保存的就是文件類型及用戶權(quán)限信息,具體結(jié)構(gòu)如下:
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位 -- 文件屬主權(quán)限位
第11-13 -- 文件屬組權(quán)限位
第14-16 -- 其他用戶權(quán)限位
1、文件類型分類
d -- 目錄文件 f -- 普通文件 b -- 塊設(shè)備文件 c -- 字符設(shè)備文件 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、文件類型位算法
從系統(tǒng)頭文件/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 塊設(shè)備文件*/
#define S_IFDIR 0040000 /* directory 目錄文件*/
#define S_IFCHR 0020000 /* character special 字符設(shè)備文件*/
#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開頭,表示這是一個(gè)8進(jìn)制數(shù),轉(zhuǎn)換成2進(jìn)制,正好是 1 111 000 000 000 000 ,高4位全置1;
b、#define S_IFREG 0100000 -- 普通文件類型掩碼,0100000,轉(zhuǎn)換成2進(jìn)制,1 000 000 000 000 000,最高位置1;
c、#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -- 判斷文件是否普通文件的宏函數(shù)
舉例說明:m值即為我們?nèi)〉絬short di_mode,假設(shè)其2進(jìn)制值為 0 011 000 000 000 000,對(duì)應(yīng)的8進(jìn)制為 060000 。
S_ISREG(0060000) 即 (((0060000) & 0170000 ) == 0100000) ,該值返回False,則代表該文件不是普通文件。
注意:這里用到的就是掩碼算法,這種算法在C、C++里比比皆是,下次具文討論其優(yōu)劣。
3、文件權(quán)限:
文件權(quán)限分 屬主權(quán)限、屬主組權(quán)限、其他用戶權(quán)限三種;
修改權(quán)限使用chmod命令,例如chmod 666 * ,或者chmod 777 * ;
問題:大家都知道666代表給所有用戶賦予讀寫權(quán)限,777給所有用戶賦予讀寫執(zhí)行權(quán)限,但是知道為什么是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
注意紅色字體部分權(quán)限變化。
4、權(quán)限位組合算法
前面提到,屬主權(quán)限位占3位,如下圖。
r
w
x
又有 2^0 = 1,執(zhí)行權(quán)限 x ;
2^1 = 2 ,寫權(quán)限 w;
2^2 = 4 ,讀權(quán)限 r。
2^1 + 2^2 = 6 ,讀寫權(quán)限 rw;
2^0 + 2^1 + 2^2 = 7 ,執(zhí)行 寫 讀權(quán)限 rwx ;
屬主用戶組權(quán)限,其他用戶權(quán)限采用的是同樣的算法,所以就有666,777之類;
到此,有關(guān)文件類型及權(quán)限的討論結(jié)束,貼上一個(gè)小程序,檢驗(yàn)下:
#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 -- 塊設(shè)備文件 c -- 字符設(shè)備文件
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博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/31/showart_511183.html |
|