【问题标题】:C system calls open / read / write / close and O_CREAT|O_EXCLC系统调用open/read/write/close和O_CREAT|O_EXCL
【发布时间】:2011-02-04 01:47:36
【问题描述】:

给定以下代码(它应该在“helloworld”文件中写入“helloworld”,然后读取文本):

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

#define FNAME "helloworld"

int main(){ 
    int filedes, nbytes;
    char buf[128];

    /* Creates a file */
    if((filedes=open(FNAME, O_CREAT | O_EXCL | O_WRONLY | O_APPEND, 
        S_IRUSR | S_IWUSR)) == -1){
            write(2, "Error1\n", 7);
    }

    /* Writes hello world to file */
    if(write(filedes, FNAME, 10) != 10)
        write(2, "Error2\n", 7);

    /* Close file */
    close(filedes);

    if((filedes = open(FNAME, O_RDONLY))==-1)
        write(2, "Error3\n", 7);

    /* Prints file contents on screen */    
    if((nbytes=read(filedes, buf, 128)) == -1)
        write(2, "Error4\n", 7);

    if(write(1, buf, nbytes) != nbytes)
        write(2, "Error5\n", 7);

    /* Close file after read */
    close(filedes); 

    return (0);
}

我第一次运行程序,输出是:

helloworld

之后我每次运行程序,输出都是:

Error1
Error2
helloworld

我不明白为什么没有附加文本,因为我指定了 O_APPEND 文件。 是因为我包含了 O_CREAT 吗? 如果文件已经创建,不应该忽略 O_CREAT 吗?

【问题讨论】:

    标签: c system-calls


    【解决方案1】:

    O_EXCL 强制创建文件。如果文件已经存在,则调用失败。

    它用于确保必须创建文件,并在第三个参数中传递给定的权限。简而言之,您有以下选择:

    • O_CREAT:如果文件不存在,则创建具有给定权限的文件。如果文件存在,则将其打开并忽略权限。
    • O_CREAT | O_EXCL:如果文件不存在,则创建具有给定权限的文件。如果文件存在,则失败。这对于创建锁定文件并保证对文件的独占访问非常有用(只要使用该文件的所有程序都遵循相同的协议)。
    • O_CREAT | O_TRUNC:如果文件不存在,则创建具有给定权限的文件。否则,将文件截断为零字节。当我们认为“创建一个新的空白文件”时,这具有我们所期望的更多效果。尽管如此,它仍保留现有文件中已存在的权限。

    更多信息来自the manual page

    O_EXCL

    当与 O_CREAT 一起使用时,如果文件 已经存在,这是一个错误,并且 open() 将失败。在这种情况下, 存在符号链接,无论 它指向的地方。 O_EXCL 坏了 在 NFS 文件系统上;程序,其中 依靠它来执行锁定 任务将包含竞争条件。 执行原子的解决方案 使用 lockfile 锁定文件是为了 在同一个文件上创建一个唯一的文件 系统(例如,合并主机名 和 pid),使用 link(2) 建立链接 到锁文件。如果 link() 返回 0, 锁定成功。否则,使用 stat(2) 在唯一文件上检查是否 它的链接数已增加到 2,在 在这种情况下,锁也是 成功。

    【讨论】:

    • 谢谢,通过删除 O_EXCL 代码可以正常工作。你能解释一下O_EXCL的用法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 2013-11-27
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    相关资源
    最近更新 更多