【问题标题】:Linux C, opening a file that exists, EEXIST error bugLinux C,打开一个存在的文件,EEXIST 错误错误
【发布时间】:2017-10-15 00:56:40
【问题描述】:

使用此代码,我不确定为什么在调用 open() 后出现错误(EEXIST 17 文件存在)。该文件确实存在。

int flags = O_WRONLY | O_CREAT | O_APPEND | S_IRWXU;
int fd = open("./atomic.txt", flags);

if(fd==-1)
{
    printf("error code: %d \n", errno);
    perror("open.. ");
    exit(0);
}

【问题讨论】:

    标签: c linux io errno


    【解决方案1】:

    S_IRWXUmode 的一部分,而不是 flags

    int flags = O_WRONLY | O_CREAT | O_APPEND;
    int mode = S_IRWXU;
    int fd = open("./atomic.txt", flags, mode);
    

    最有可能发生的事情是S_IRWXU 正在设置flagsO_EXCL 位,因此如果文件已经存在,open() 将失败。 确实是这样,至少在我的系统上是这样:

    /usr/include/fcntl.h:
        #define S_IRWXU (__S_IREAD|__S_IWRITE|__S_IEXEC)
    /usr/include/x86_64-linux-gnu/bits/stat.h:
        #define __S_IREAD  0400
        #define __S_IWRITE 0200
        #define __S_IEXEC  0100
    /usr/include/asm-generic/fcntl.h:
        #define O_EXCL 00000200
    

    可以看到__S_IWRITE模式和O_EXCL标志都是0200

    【讨论】:

    • 使用O_CREAT,你必须设置第三个参数。看man 2 open
    • @Gam 那么为什么EINVAL 不会失败呢?
    • @Joker_vD,如果你在谈论一个无效的标志,它只是一个位掩码,open() 不知道你是如何填充那个位掩码的。如果您正在谈论缺少的第三个参数,open() 在调用它之前也不知道您推送了多少东西(或您设置了哪些寄存器)。它只是假设你知道你在做什么:-)
    • @paxdiablo - open 应该很快就会失败;至少在使用 glibc 时。它涉及一些验证和EINVAL 返回。我想知道为什么他可以用不正确的参数数量调用 open 。另请参阅 Sourceware wiki 上的 Style and Conventions
    • @jww,你是正确的(假设错误 可以 实际被检测到)。如果您正在谈论该链接的9.2 部分(涵盖用户错误),那是针对未定义的行为。这里没有 UB,用户只是错误地设置了 flags 变量。鉴于正在使用的 API,我不确定 open() 检测到这个(或缺少的第三个参数)是否可能
    猜你喜欢
    • 2016-10-09
    • 2020-01-23
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 2013-09-10
    • 2011-05-29
    相关资源
    最近更新 更多