04.09.2 验证文件粘着位的作用

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

void
perror_and_exit (const char *msg)
{
    int err = errno;
    fflush (stdout);
    fprintf (stderr, "%s: %s\n", msg, strerror (err));
    exit (errno);
}

int
main (int argc, char **argv)
{
    if (argc != 2)
        {
            fprintf (stderr, "Usage: %s <path>\n", argv[0]);
            exit (1);
        }
    struct stat buf;
    if (stat (argv[1], &buf) == -1)
        perror_and_exit ("stat");
    if (buf.st_mode & S_ISVTX)
        printf ("S_ISVTX is set\n");
    else
        printf ("The bit is not set\n");
}

编译运行:

⇨ /data/apue $ /data/apue/build/apue build/
The bit is not set
⇨ /data/apue $ /data/apue/build/apue /tmp/
S_ISVTX is set
⇨ /data/apue $ /data/apue/build/apue /var/
The bit is not set
⇨ /data/apue $ /data/apue/build/apue /var/tmp/
S_ISVTX is set

验证一下没有粘着位的影响:

⇨ /data/apue $ sudo touch build/rootfile.txt
[sudo] password for <USER>: 
⇨ /data/apue $ ls -lAh build/rootfile.txt 
-rw-r--r-- 1 root root 0 May 12 22:18 build/rootfile.txt
⇨ /data/apue $ mv build/rootfile.txt build/userfile.txt
⇨ /data/apue $ 

build/rootfile.txt 文件之前不存在,现在是 root 创建的,但是普通用户居然也能将文件改名!我们在设置了粘着位的 /tmp 目录看看这个情况:

⇨ /data/apue $ sudo touch /tmp/rootfile.txt
[sudo] password for <USER>: 
⇨ /data/apue $ ls -lAh /tmp/rootfile.txt 
-rw-r--r-- 1 root root 0 May 12 22:25 /tmp/rootfile.txt
⇨ /data/apue $ mv /tmp/rootfile.txt /tmp/userfile.txt
mv: cannot move '/tmp/rootfile.txt' to '/tmp/userfile.txt': Operation not permitted

这就比较符合预期了。之前很多次遇到权限不够的情况,我还以为不能删除其他用户的文件是通过文件读写执行的权限检查的,现在看来还是粘着位的作用。