Unix文件系统 研究

用户权限

12345678910111213141516
ugsrwxrwxrwx
  • 第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,可以获取如下宏定义:
    #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、权限位组合算法
    又有 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 <sys/stat.h> #include <unistd.h>

定义函数:int stat(const char * file_name, struct stat *buf);

函数说明:stat()用来将参数file_name 所指的文件状态, 复制到参数buf 所指的结构中。

下面是struct stat 内各参数的说明:
struct stat
{
dev_t st_dev; //device 文件的设备编号
ino_t st_ino; //inode 文件的i-node
mode_t st_mode; //protection 文件的类型和存取的权限
nlink_t st_nlink; //number of hard links 连到该文件的硬连接数目, 刚建立的文件值为1.
uid_t st_uid; //user ID of owner 文件所有者的用户识别码
gid_t st_gid; //group ID of owner 文件所有者的组识别码
dev_t st_rdev; //device type 若此文件为装置设备文件, 则为其设备编号
off_t st_size; //total size, in bytes 文件大小, 以字节计算
unsigned long st_blksize; //blocksize for filesystem I/O 文件系统的I/O 缓冲区大小.
unsigned long st_blocks; //number of blocks allocated 占用文件区块的个数, 每一区块大小为512 个字节.
time_t st_atime; //time of lastaccess 文件最近一次被存取或被执行的时间, 一般只有在用mknod、utime、read、write 与tructate 时改变.
time_t st_mtime; //time of last modification 文件最后一次被修改的时间, 一般只有在用mknod、utime 和write 时才会改变
time_t st_ctime; //time of last change i-node 最近一次被更改的时间, 此参数会在文件所有者、组、权限被更改时更新
};

先前所描述的st_mode 则定义了下列数种情况:
1、S_IFMT 0170000 文件类型的位遮罩
2、S_IFSOCK 0140000 scoket
3、S_IFLNK 0120000 符号连接
4、S_IFREG 0100000 一般文件
5、S_IFBLK 0060000 区块装置
6、S_IFDIR 0040000 目录
7、S_IFCHR 0020000 字符装置
8、S_IFIFO 0010000 先进先出
9、S_ISUID 04000 文件的 (set user-id on execution)位
10、S_ISGID 02000 文件的 (set group-id on execution)位
11、S_ISVTX 01000 文件的sticky 位
12、S_IRUSR (S_IREAD) 00400 文件所有者具可读取权限
13、S_IWUSR (S_IWRITE)00200 文件所有者具可写入权限
14、S_IXUSR (S_IEXEC) 00100 文件所有者具可执行权限
15、S_IRGRP 00040 用户组具可读取权限
16、S_IWGRP 00020 用户组具可写入权限
17、S_IXGRP 00010 用户组具可执行权限
18、S_IROTH 00004 其他用户具可读取权限
19、S_IWOTH 00002 其他用户具可写入权限
20、S_IXOTH 00001 其他用户具可执行权限上述的文件类型在 POSIX 中定义了检查这些类型的宏定义
21、S_ISLNK (st_mode) 判断是否为符号连接
22、S_ISREG (st_mode) 是否为一般文件
23、S_ISDIR (st_mode) 是否为目录
24、S_ISCHR (st_mode) 是否为字符装置文件
25、S_ISBLK (s3e) 是否为先进先出
26、S_ISSOCK (st_mode) 是否为socket 若一目录具有sticky 位 (S_ISVTX), 则表示在此目录下的文件只能被该文件所有者、此目录所有者或root 来删除或改名.

返回值:执行成功则返回0,失败返回-1,错误代码存于errno。

错误代码:
1、ENOENT 参数file_name 指定的文件不存在
2、ENOTDIR 路径中的目录存在但却非真正的目录
3、ELOOP 欲打开的文件有过多符号连接问题, 上限为16 符号连接
4、EFAULT 参数buf 为无效指针, 指向无法存在的内存空间
5、EACCESS 存取文件时被拒绝
6、ENOMEM 核心内存不足

7、ENAMETOOLONG 参数file_name 的路径名称太长

stat()函数是将文件状态复制到buf中,可以利用其中的st_mode参数判断文件的状态:(举两个例子,在Tinyhttpd源码中看到的)

struct stat st;
stat(path, &st);
st.st_mode & S_IFMT == S_IFDIR; //可以判断st是否是一个目录
st.st_mode & S_IXUSR == 1;      //可以判断是否可执行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、UNIX文件系统的基本原理        UNIX采用树型目录结构,每个目录表称为一个目录文件。一个目录文件是由目录项组成的。每个目录项包含16B,一个辅存磁盘块(512B)包含32个目录项。在目录项中,第1、2字节为相应文件的外存i节点号,是该文件的内部标识;后14B为文件名,是该文件的外部标识。所以,文件目录项记录了文件内、外部标识的对照关系。根据文件名可以找到辅存i节点号,由此便得到该文件的所有者、存取权、文件数据的地址健在等信息。UNIX的存储介质以512B为单位划分为块,从0开始直到最大容量并顺序加以编号就成了一个文件卷,也叫文件系统。本次课程设计是要实现一个简单的模拟UNIX文件系统。我们在磁盘中申请一个二进制文件模拟UNIX内存,依次初始化建立位示图区,I节点区,数据块区。 二、基本要点思路         1、模拟磁盘块的实现:因为文件系统需要从磁盘中读取数据操作数据,在实现时是使用文件来模拟磁盘,一个文件是一块磁盘,在文件中以划分磁盘块那样划分不同的区域,主要有三个区域:位图区,inode索引节点区,磁盘块区。位图区我是使用一个512byte的数组存放,inode区和磁盘块区我采用一种自认为比较巧妙的方法,就是存放对象列表,之前说过,在本次实验的所有的结构都使用对象进行存储,而inode节点和磁盘块就是两个重要的数据结构,在初始化时我实例化32个inode对象和512个block对象(至于这些类的具体定义下面会提到),然后将这些对象加入各自对应的对象列表中,在存储时,使用java的对象序列化技术将这个对象数组存到磁盘中。当使用文件系统时,程序会先从磁盘文件中读取出位图数组,inode对象列表,block对象列表,之后的操作就是通过对这些列表进行修改来实现。使用这种方法可以减小存储的空间(对象序列话技术)而且不需要在使用时进行无用的查找,只要第一次初始化中将这些对象都读取出来。        2、界面的实现:在实现这个文件系统时使用了两种方案,一种是直接在java控制台来进行输入输出,因为原本想着UNIX文件系统原本也是使用的命令行语句,所以在控制台上实现也很接近。后来在老师的建议下又将整个程序重新修改,改成在UI界面上进行输入输出,这样确实界面美观舒服了不少,只不过两者用的技术很不一样,前者主要使用的是系统的输入输出流,后者使用java监听器。        3、权限的实现:在实现多用户的权限方面,我给文件和文件夹各定义了三级权限1、访问:在文件中是可以查看文件的内容,在文件夹中是可以进入该文件夹。2、修改:文件中是可以对文件进行编辑,文件夹中是可以在该文件夹中创建新的文件或目录。3、删除:顾名思义。文件或文件夹的创建者拥有最高级别的权限,只有拥有最高级权限的用户才可以给其他用户针对该文件或文件夹进行授权和授权操作。在每次对文件或文件夹进行访问修改删除操作时都会检查当前用户在该文件或文件夹所拥有的权限,只有拥有的权限大于想要实现的权限时才可以进行该操作

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值