函数 umask
umask 函数为进程设置文件模式创建屏蔽字,并返回之前的值。这个函数没有出错返回,它不会出错.
#include <sys/stat.h>
mode_t umask(mode_t cmask);
// 返回值:为文件模式创建屏蔽字
其中,参数 cmask 是由 文件模式(mode)的九个权限按位或构成的。
例如:
#include <stdio.h>
#include <sys/stat.h>
#include <fcnt1.h>#define RWRWRW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)int main ()
{umask(0);if(creat("foo", RWRWRW) < 0)perror("creat error for foo");umask (S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);if(creat("bar", RWRWRW) < 0)perror("creat error for bar");return 0;
}
上述代码创建了两个文件,创建第一个文件时,umask 值为0,创建第二个时,umask 值禁止所有组和其他用户的访问权限。
运行结果如下:
ls -l foo bar
-rw------- 1 sar bar
-rw-rw-rw- 1 sar foo
应用中常常使用设置 umask 值以控制他们所创建文件的默认权限。
函数 chmod、fchmod 和 fchmodat
这三个函数可以更改现有文件的访问权限
#include <sys/stat.h>int chmod(const char *pathname, mode_t mode);int fchmod(int fd, mod_t mode);int fchmodat(int fd, const char *pathname, mode_t mode,int flag);//3个函数返回值:若成功,返回 0;若出错,返回 -1.
chmod 函数在指定的文件上进行操作,而 fchmod 函数则对已打开的文件进行操作。
fchmodat 函数与 chmod 函数在下面两种情况下是相同的:一种是 pathname 参数为绝对路径,另一种是 fd 参数取值为 AT_FDCWD 而 pathname 参数为相对路径。flag 参数可以改变 fchmodat 的行为,当设置看 AT_STMLINK_NOFOLLOW 标志位时,fchmodat 并不会跟随符号链接。
参数 mode 是下图中所示常量的按位或
注:chmod 函数在下列条件下自动清除两个权限位:
1. Solaris 等系统对用于普通文件的粘着位赋予了特殊含义,在这些系统上如果我们试图设置普通文件的粘着位(S_ISVTX),而且又没有超级用户权限,那么 mode 中的粘着位自动被关闭。这是做的理由是防止恶意用户设置粘着位,由此影响性能。
2. 新创建文件的组 ID 可能不是调用进程所属的组。
函数 chown、fchown、fchownat 和 lchown
下面几个 chown 函数可用于更改文件的用户 ID 和组 ID。如果两个参数 owner 或 group 中任意一个是 -1,则对应的 ID 不变。
#include <unistd.h>int chown(const char *pathname, uid_t owner, gid_t group);int fchown(int fd, uid_t owner, gid_t group);int fchownat(int fd, const char *pathname, uid_t owner, gid_group, int flag);int lchown(const char *pathname, uid_t owner, gid_t group);// 4个函数的返回值;若成功,返回0;若出错,返回-1
除了所引用的文件是符号链接以外,着4个函数的操作类似。在符号链接情况下,lchown 和 fchownat(设置了 AT_SYMLINK_NOFOLLOW 标志)更改符号链接本身的所有者,而不是该符号链接所指向的文件的所有者。
基于 BSD 的系统一直规定只有超级用户才能更改一个文件的所有者。这样做的原因是防止用户改变其他文件的所有者从而摆脱磁盘空间限额对他们的限制。
当_POSIX_CHOWN_RESTRICTED 对指定的文件生效时,满足:
1. 只有超级用户进程能更改该文件的用户 ID;
2. 如果进程拥有此文件,参数 owner 等于 -1 或文件的用户 ID,并且参数 group 等于进程的有效组 ID 或进程的附属组 ID 之一,那么一个非超级用户进程可以更改该文件的组 ID。