c - 为什么我的程序不能使用 mkdir 系统调用设置 0777 模式?

标签 c linux

我写了下面的代码来尝试在 Linux 上创建一个 0777 模式的目录:

#include <sys/stat.h>
#include <sys/types.h>

int main () {

    mkdir("/tmp/mkdir-test", 0777);
    return 0;

}

但实际上,新目录有 0755 模式。

# stat /tmp/mkdir-test
  File: `/tmp/mkdir-test'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 802h/2050d  Inode: 1772304     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-09-27 20:23:54.000000000 -0700
Modify: 2016-09-27 20:23:54.000000000 -0700
Change: 2016-09-27 20:23:54.000000000 -0700

谁能解释一下?程序如何创建真正的 0777 模式目录?

最佳答案

运行 umask 在外壳中;它会报告022 . umask 中设置的位创建文件或目录时从权限中删除值。

在单线程程序中,一种真正设置0777的方法权限是丁克 umask() :

mode_t old_mask = umask(0);
mkdir("/tmp/mkdir-test", 0777);
umask(old_mask);

这将保留当前设置,除非您确定需要覆盖它。然而,这在多线程程序中是危险的,因为 umask值是每个进程的全局值,而不是每个线程(感谢 Peter Cordespointing this out )。

设置权限的另一个选项是使用 chmod() ,这样做对于多线程程序也是安全的:

const char *dirname = "/tmp/mkdir-test";
mode_t target_mode = 0777;
if (mkdir(dirname, 0) == 0)
    chmod(dirname, target_mode);

chmod() 设置的权限功能不受 umask 影响值(value)观。

调用 mkdir() 的权限最好设置为 0如图所示;它将始终可靠地工作,并且不会通过修改 umask 来影响其他线程。值(value)。或者,您可以在对 mkdir() 的调用中使用所需的目标权限。如果您愿意(此答案的先前版本建议这样做,使用 0777 作为硬编码目标权限)。

const char *dirname = "/tmp/mkdir-test";
mode_t target_mode = 0777;
if (mkdir(dirname, target_mode) == 0)
    chmod(dirname, target_mode);

如果你使用这个习语,传递给 mkdir() 的模式很重要与传递给 chmod() 的模式相同或更宽松— 和 0比任何其他模式都宽松(并且总是有效)。 如果您在调用 mkdir() 时使用更轻松的模式,mkdir() 之间存在 TOCTOU(检查时间,使用时间)类型的漏洞和 chmod()调用期间某人(某些进程)可以以宽松的权限进入目录并造成严重破坏;这可能存在安全风险。

请注意 umask()是一个非常简单的系统调用,因此也非常快(随着系统调用的进行,与 open()mkdir()chmod() 等重量级相比)。

关于c - 为什么我的程序不能使用 mkdir 系统调用设置 0777 模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39737609/

相关文章:

c - 为什么浮点值条件在 'if' 条件下失败?

c - 使我的递归代码不那么复杂

c - 函数结构 - 差异

linux - 如何编写脚本以使用我的凭据连接到 ssh 服务器?

php - 线上服务器的/usr/local/lib在哪里

c - 如何在 C 中手动迭代堆栈帧?

linux - 在 Ubuntu x64 12.04 上将 wkhtmltopdf 0.11rc-1 替换为 0.12

c - 如何设置特定 pthread 的 CPU 关联性?

linux - 对 TXT 文件进行分组

c++ - 在 AVR 的程序内存中构建编译时任意长度数组