gpt4 book ai didi

c - 同时指定 O_APPEND 和 O_TRUNC 时,它不会截断吗?

转载 作者:行者123 更新时间:2023-12-04 10:12:55 24 4
gpt4 key购买 nike

如题,当同时指定O_APPENDO_TRUNC时,文件打开时不会先被截断。

那么,当指定O_APPEND时,我如何仍然先截断文件?


@更新:

O_APPENDO_TRUNC 可以完美地协同工作,这是我之前代码中的错误。


关于原子

以下代码证明 O_APPEND 将确保每个 write() 中的追加操作是原子的,方法是将偏移量设置为在原子系统调用中自动结束。

// atomic append
// TLPI exercise 5.3

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

int atomic_append(int argc, char *argv[]) {
char *buf = "a";
int opt;
if(argc < 3) {
printf("command format: %s\n", "atomic_append <filename> <byte-count> [x]");
return -1;
}
char *fp = argv[1];
int bc = atoi(argv[2]);
int flag_append = 1;

if(argc >=4 && strcmp(argv[3], "x")==0) {
flag_append = 0;
}

int fd = open(fp, O_RDWR | O_CREAT | O_TRUNC | (flag_append?O_APPEND:0), 0644);
int i=0;
while(i++ < bc) {
if(!flag_append) {
lseek(fd, 0, SEEK_END);
}
write(fd, buf, 1);
}
close(fd);

return 0;
}

int main(int argc, char *argv[]) {
atomic_append(argc, argv);
return 0;
}

编译运行步骤:

  • 编译成a.out
  • ./a.out a1 100000 & ./a.out a1 100000
  • ./a.out a2 100000 x & ./a.out a2 100000 x
  • ll -h a*

然后你可以看到a1和a2有不同的大小。
这是 TLPI 练习 5.3 中的一个练习。

最佳答案

O_APPENDO_TRUNC 可以很好地协同工作。如果他们不这样做,我会怀疑您的操作系统中存在错误(或者更可能是您的代码中)。

这是一个简单的测试程序,它在 MacOS、OpenBSD 和两个不同版本的 Linux 上都运行良好:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>

#define FN "truncateme"

int
main(int argc, char **argv)
{
char buf[16];
ssize_t r;
int fd;

if ((fd = open(FN, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1)
err(1, "open 1 ");

if (write(fd, "foo", 3) != 3)
err(1, "write 1");

close(fd);

if ((fd = open(FN, O_RDWR|O_TRUNC|O_APPEND, 0600)) == -1)
err(1, "open 2");

if (write(fd, "1", 1) != 1)
err(1, "write 2");

close(fd);

if ((fd = open(FN, O_RDONLY)) == -1)
err(1, "open 3");

if ((r = read(fd, buf, 16)) != 1)
errx(1, "read %d != 1", (int)r);

return 0;
}

Here is the POSIX description of open请注意它是如何表示“可以使用以下各项的任意组合”并且该列表包括 O_APPENDO_TRUNC

我真的不知道 O_TRUNC 会如何与 O_APPEND 交互,因为第一个只是告诉操作系统当时如何处理文件O_APPEND 告诉操作系统在调用 writewritev 函数时要做什么。

此外,为了消除其他答案给您带来的困惑。 O_APPEND does guarantee atomicity of the write : "如果设置了文件状态标志的 O_APPEND 标志,则在每次写入之前,文件偏移量应设置为文件末尾,并且在更改文件偏移量和写入操作之间不应发生任何干预文件修改操作。"

为了消除进一步的混淆,我在关于 POSIX 下文件操作原子性的评论中看到,this part of the standard is relevant.

关于c - 同时指定 O_APPEND 和 O_TRUNC 时,它不会截断吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30022127/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com