C 系统调用 open/read/write/close 和 O_CREAT|O_EXCL

发布于 2024-08-27 06:01:18 字数 1153 浏览 5 评论 0原文

给出以下代码(应该在“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 不应该被忽略吗?

Given the following code (it's supposed to write "helloworld" in a "helloworld" file, and then read the text):

#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);
}

The first time I run the program, the output is:

helloworld

After that every time I to run the program, the output is:

Error1
Error2
helloworld

I don't understand why the text isn't appended, as I've specified the O_APPEND file.
Is it because I've included O_CREAT?
It the file is already created, shouldn't O_CREAT be ignored?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怎言笑 2024-09-03 06:01:18

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

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

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

更多信息来自手册页

O_EXCL

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

O_EXCL forces the file to be created. If the file already exists, the call fails.

It is used to ensure that the file has to be created, with the given permissions passed in the third parameter. In short, you have these options:

  • O_CREAT: Create the file with the given permissions if the file doesn't already exist. If the file exists, it is opened and permissions are ignored.
  • O_CREAT | O_EXCL: Create the file with the given permissions if the file doesn't already exist. If the file exists, it fails. This is useful in order to create lockfiles and guarantee exclusive access to the file (as long as all programs which use that file follow the same protocol).
  • O_CREAT | O_TRUNC: Create the file with the given permissions if the file doesn't already exist. Otherwise, truncate the file to zero bytes. This has more of the effect we expect when we think "create a new blank file". Still, it keeps the permissions already present in the existing file.

More information from the manual page:

O_EXCL

When used with O_CREAT, if the file
already exists it is an error and
the open() will fail. In this context,
a symbolic link exists, regardless of
where it points to. O_EXCL is broken
on NFS file systems; programs which
rely on it for performing locking
tasks will contain a race condition.
The solution for performing atomic
file locking using a lockfile is to
create a unique file on the same file
system (e.g., incorporating hostname
and pid), use link(2) to make a link
to the lockfile. If link() returns 0,
the lock is successful. Otherwise, use
stat(2) on the unique file to check if
its link count has increased to 2, in
which case the lock is also
successful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文