一.设置用户ID和设置组ID
1.实际用户ID和实际组ID标识当前登录的用户。
2.有效用户ID,有效组ID以及附加组ID决定了我们的文件访问权限。
3.通常,有效用户ID等于实际用户ID,有效组ID等于实际组ID。但是可以在文件模式模式字中设置一个特殊标志,
将进程的有效用户ID设置为文件所有者的用户ID。分别设置用户ID位和设置组ID位即可。方法如下:
chmod u+s filename 与 chmod g+s filename
二.文件的访问权限
1.每个文件有9个访问权限,可分为三类,u(所有者),g(组),o(其它),得到的方法,可以直接使用宏与st_mode得到,
也可以通过位运算获得。
2.三类权限:(读,写,执行)
a.用名字打开任一类型文件时,隐含对当前目录及其上级目录都应具有执行权限,否则不能打开。
b.当一个目录是我们要访问文件的路径名的一个组成部分时,对该目录的执行权限使我们可通过该目录,
也就是搜索该目录,寻找一个特定的文件名。如果PATH环境变量指定了一个我们不具有执行权限的目录,
那么shell决不会在该目录找到可执行文件。
c.为了在一个目录中创建一个新文件,必须对该目录具有写权限和执行权限。
d.为了删除一个现有文件,必须对包含该文件的目录具有写权限和执行权限。对该文件本身不需要有读,写权限。
e.进程每次打开,创建或删除一个文件时,内核就进行文件访问权限测试:
1.若进程的有效用户ID是0(超级用户),则允许访问,给予超级用户对整个文件系统进行处理的最充分的自由。
2.若进程的有效用户ID等于文件的所有者ID(即该进程拥有此文件),那么,若所有者适当的访问权限位被设置,则允许访问。
3.若进程的有效组ID或进程的附加组ID之一等于文件的组ID,那么,若组适当的访问权限位被设置,则允许访问,否则拒绝。
4.若其他用户适当的访问权限位被设置,则允许访问,否则拒绝。
按顺序执行以上四步。若进程拥有此文件,则按用户访问权限批准或拒绝该进程对文件的访问——不查看组访问权限。类似地,若进程
并不拥有该文件,单进程属于某个适当的组,则按组访问权限批准或拒绝该进程对文件的访问——不查看其他用户的访问权限。
三.新文件和新目录
1.权限问题:如果是文件,默认是以0666和umask按位相减得到文件各用户的权限。如果是目录,默认是0777和umask
按位相减得到。
2.所有权问题:新文件的用户ID设置为进程的有效用户ID。关于组ID,有两种选择:
a.新文件的组ID可以是进程的有效组ID。
b.新文件的组ID可以是它所在目录的组ID。
四.access函数
作用:按实际用户ID和实际组ID进行访问权限测试。
头文件:include
用法:int access(const char *pathname,int mode)
返回值:若成功则返回0,若出错则返回-1。
mode:R_OK 测试读权限;W_OK 测试写权限;X_OK 测试执行权限;F_OK 测试文件是否存在。
五.chmod与fchmod函数
作用:更改现有文件的权限
头文件:#include
用法:int chmod(const char *pathname,mode_t mode);
int fchmod(int filedes,mode_t mode);
返回值:若成功返回0,若出错返回-1。
注意:为改变一个文件的权限位,进程的有效用户ID必须等于文件的所有者ID,或者该进程必须具有超级用
户权限。
六.文件截短函数truncate与ftruncate
作用:在文件尾端处截去一些数据以缩短文件。
头文件:#include
用法:int truncate(const char *pathname,off_t length);
int ftruncate(int filedes,off_t length);
返回值:若成功返回0,否则返回-1。
注意:如果length 大于文件长度,则在文件末尾加'\0',并改变文件大小;若length 小于文件长度,
则在文件末尾截掉多出的部分。
七.文件系统(补充)
1.每个文件系统各自对它们的i节点编号,因此目录项中的i节点编号数指向同一文件系统中相应的i节点,不能使
一个目录项指向另一个文件系统的i节点。
2.当在不更换文件系统情况下为一个文件更名时,该文件的实际内容并未移动,只需构造一个指向现有i节点新目录项
并解除与旧目录项的链接。
八.link,unlink,remove函数
1.link:相当与创建一个现有文件的硬链接
头文件:#include
用法:int link(const char *existingpath,const char *newpath)
返回值:如果newpath 存在则返回出错-1,成功则为0。
注意:如果实现支持创建指向一个目录的硬链接,那么也仅限于超级用户才可以这样做,
理由是这样做可能在文件系统中形成循环,因此很多文件系统实现不允许对目录的硬链接。
2.unlink:删除一个现有的目录项
头文件:#include
用法:int unlink(const char *pathname);
返回值:成功返回0,否则-1。
注意:为了解除对文件的链接,必须对包含该目录项的目录具有写和执行的权限。且必须具备
三个条件之一:拥有该文件;拥有该目录;具有超级用户特权。如果pathname是符号链接,
那么unlink删除该符号链接,而不会删除由该链接所引用的文件。给出符号链接名情况下,
没有一个函数能删除由该链接所引用的文件。
3.remove:解除对一个文件或目录的链接。
头文件:#include
用法:int remove(const char *pathname);
返回值:成功返回0,否则返回-1.
注意:对于文件,remove的功能与unlink相同。对于目录,remove的功能与rmdir相同。