c - 无法在 C、Linux 中重新打开文件

标签 c linux file file-io

所以我正在做一些非常基本的工作,用 C 语言打开和关闭文件。

我注意到当我运行下面的代码时,我得到了奇怪的输出:

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

main()
{
   // first get rid of existing input.txt, which is guaranteed to exist
   pid_t pid = fork();

   //child code
   if (pid == 0) {
       char* command[4] = {"rm", "-f", "input.txt", NULL};
       execvp(command[0], command);
   }


   // parent code
   else {
       int status;
       wait(&status);
   }

   // initialize file descriptor
   int fd;

   // open input.txt with given flags
   int flags = O_RDWR | O_CREAT;
   fd = open("input.txt", flags);

   // debug
   fprintf(stderr,"The openval is %d\n", fd);

   // now close it
   int closeval = close(fd);

   // debug
   fprintf(stderr,"The closeval is %d\n", closeval);

   // try to re-open-it with different flags
   flags = O_RDONLY;
   fd = open("input.txt", flags);

   // debug
   fprintf(stderr,"The new openval is %d\n", fd);
}

输出:

The openval is 3
The closeval is 0
The new openval is -1

第一行和第二行输出对我来说很有意义。我的大问题是,为什么我不能再次打开该文件?

起初我认为这可能是因为我请求使用以下标志第二次打开它:

flags = O_RDWR;

我的想法是请求写入权限会以某种方式被之前的打开弄乱(尽管情况不应该是这样,因为我关闭了它,对吧?)。所以我尝试了上面的版本,它只要求读取文件,但仍然没有成功。

像这样打开、关闭然后重新打开文件不是一种选择吗?

编辑:这里是errno测试代码和输出

if(fd == -1) {
       char* error = strerror(errno);
       fprintf(stderr,"%s\n",error);
}

输出:

Permission denied

最佳答案

首先,man page link .

当你做的时候

int flags = O_RDWR | O_CREAT;
fd = open("input.txt", flags);

您缺少 open 的第三个参数,文件创建 mode。对于 O_CREAT,它是必需的。没有它,函数将为参数采用任何“随机”值,并且文件可能会以某种未定义的模式创建(或者实际上任何 UB 都可能发生,理论上)。

作为第一步解决这个问题,为您的程序定义行为。


此外,虽然可能对上述错误没有太大帮助,但当 C 库函数返回错误时(对于整数通常为 -1,对于指针通常为 NULL),它还会设置全局 errno。使用 perrorstrerror(errno) 获取人为错误消息。始终在检测到错误时将其记录下来,这不仅有助于解决代码错误,还有助于解决外部问题,例如即使在程序“就绪”后也可能发生的文件权限问题。

关于c - 无法在 C、Linux 中重新打开文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25387364/

相关文章:

linux - 如何让VIM在写信的时候播放打字机的声音?

file - 写入文件然后立即读回

file - 是否可以在内存中将 []byte 转换为 os.File,反之亦然,或者以任何方式将文件作为 os.File 导出/导入数据库?

C - Linux - 自定义内核模块来迭代进程的子进程会破坏内核日志和计算机

c - 滑动算法

c - 如何使用指向结构指针的指针?

c - Linux C USB 写入速度

linux - 如何在 Red Hat Enterprise Linux 中安装 Net::SFTP perl 模块

c - 流和文件有什么区别?

c - 程序打印的坐标与我为其生成的坐标不同