umask 怎样影响新建文件的权限?

1. umask 设置的不是默认权限,而是针对新建文件的一种权限限制。

2. 应用程序在创建文件时,会指定文件的权限 (mode)。而最终这个新建的文件的权限会是 (mode & ~umask).

# man 2 open

O_CREAT
    If  the  file does not exist it will be created.  The owner (user ID) of the file is set to the effective user ID of the process.  The group
    ownership (group ID) is set either to the effective group ID of the process or to the group ID of the parent directory  (depending  on  file
    system  type and mount options, and the mode of the parent directory, see the mount options bsdgroups and sysvgroups described in mount(8)).

    mode specifies the permissions to use in case a new file is created.  This argument must be supplied when O_CREAT is specified in flags;  if
    O_CREAT is not specified, then mode is ignored.  The effective permissions are modified by the process’s umask in the usual way: The permis-
    sions of the created file are (mode & ~umask).  Note that this mode only applies to future accesses of the newly created  file;  the  open()
    call that creates a read-only file may well return a read/write file descriptor.

3. 以 touch 为例,对于不存在的文件,touch 会新建这个文件,并把权限指定为 0666.

# strace -Tttfv -s 8192 -o /tmp/touch.out touch umask-test
~~~
920   13:39:10.511535 open("umask-test", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3 <0.000124>
~~~
coreutils-8.4/src/touch.c 
~~~
123 static bool
124 touch (const char *file)
125 {
<......>
133   else if (! (no_create || no_dereference))
134     {
135       /* Try to open FILE, creating it if necessary.  */
136       fd = fd_reopen (STDIN_FILENO, file,
137                       O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY,
138                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
<......>
205 }
~~~

4. 在我们编写程序的时候,可以用以下方法指定新建文件权限。这个程序指定新建文件的权限为0777。如果 umask 设定为 0022,创建出来的文件权限将会是 0755.

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>

int main()
{
        int fd1 = open("umask-test-1", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
        if (fd1 != -1) {
                close(fd1);
        }
        return 0;

}

5. gcc 也遵循 umask 的值。不过从 strace 的结果来看,它是读取 umask 值后,自行通过 chmod 来赋予文件相应权限的。

# strace -Tttfv -s 8192 -o /tmp/gcc.out gcc -o umask.out umask.c
~~~
996   13:51:44.564672 stat("umask.out", {st_dev=makedev(253, 0), st_ino=35019, st_mode=S_IFREG|0666, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=16, st_size=6465, st_atime=2016/05/13-13:51:44, st_mtime=2016/05/13-13:51:44, st_ctime=2016/05/13-13:51:44}) = 0 <0.000014>
996   13:51:44.564725 umask(0)          = 0 <0.000007>
996   13:51:44.564752 umask(0)          = 0 <0.000007>
996   13:51:44.564778 chmod("umask.out", 0777) = 0 <0.000012>
~~~