如何匹配 open 和 stat mode_t?

Posted

技术标签:

【中文标题】如何匹配 open 和 stat mode_t?【英文标题】:How to match open and stat mode_t? 【发布时间】:2014-08-10 10:50:33 【问题描述】:

我正在使用open 创建一个文件并设置其权限,然后我使用stat 获取文件权限......权限不匹配。 下面程序的结果是:

open (600) 和 stat (100600) 的模式不同

如何比较open(2)设置并检索到的模式(权限)与stat(2)

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

#include <fcntl.h>
#include <stdio.h>


int
main(int argc, char **argv, char **env) 
        
        const char *path = "/tmp/test";
        const mode_t mode = S_IRUSR | S_IWUSR;
        
        if (open(path, O_RDWR |  O_CREAT | O_EXCL, mode) == -1)
                err(1, "open for '%s' failed", path);
        
        struct stat sb;
        if (stat(path, &sb) != 0)
                err(2, "stat failed");
        
        if (mode != sb.st_mode)
                printf("mode from open (%o) and stat (%o) are different\n", 
                        mode, sb.st_mode);

        return 0;

谢谢

【问题讨论】:

【参考方案1】:

在 user3477950's answer 和 comment 投票后,我得到了答案;我正在用代码回答我自己的问题。

关键部分是sb.st_mode &amp; RWX_UGO

所以,我最终得到了类似的东西:

#define RWX_UGO (S_IRWXU | S_IRWXG | S_IRWXO)
//....
const mode_t file_mode = sb.st_mode & RWX_UGO;
if (mode == file_mode)
        printf("file_mode (%o) & RWX_UGO(%o) equals to(%o) which is "
                    "equal to mode(%o)\n", sb.st_mode, RWX_UGO, 
                    file_mode, file_mode);
else
        printf("mode from open (%o) and stat (%o) are different\n", 
                    mode, file_mode);

现在打印

file_mode (100600) & RWX_UGO(777) 等于(600) 等于 模式(600)

【讨论】:

【参考方案2】:

这是因为st_mode 成员不仅包含访问权限,还包含许多其他标志(例如,您可以检查文件是否为符号链接)。 Docs here.

【讨论】:

感谢您的回答。我已经阅读了文档,是的,st_mode 有更多信息,但是......问题是如何将st_modeopen 中使用的 t_mode 进行比较。一个代码示例将非常有用 @user454322 你用0777 掩盖了噪音。顺便说一句,不确定为什么要测试模式是否相等。使用提供的宏测试单个标志几乎肯定会更好。 虽然数字编码的权限掩码经常出现在遗留代码中,但您应该避免在程序中使用数值 -Robbins & Robbins 的 UNIX 系统编程 - 使用 0777 安全? @user454322 没错,严格来说它不是绝对可移植的,尽管我不知道0777 并不意味着rwx 的Unix 系统。出于可移植性的原因,您可以将其替换为所有S_I* 宏按位或在一起。 @user454322 #define RWX &lt;all 9 macros bitwise OR'd&gt;,然后是if ((mode &amp; RWX) == (st.st_mode &amp; RWX)) ...

以上是关于如何匹配 open 和 stat mode_t?的主要内容,如果未能解决你的问题,请参考以下文章

学习手记-如何找到man手册中函数参数的类型定义

mode_t 0644 是啥意思?

c 和 LD_PRELOAD。 open 和 open64 调用被拦截,但不是 stat64

使用 open 系统调用未正确设置文件权限

如何在 open-ssh 和 dropbear 之间匹配 ECDSA 指纹

fopen() 创建权限模式