无法在C,Linux中重新打开文件

时间:2014-08-19 15:29:53

标签: 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;

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

打开,关闭,然后重新打开这样的文件只是不是一个选项?

编辑:这是错误的测试代码和输出

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

输出:

Permission denied

2 个答案:

答案 0 :(得分:1)

首先,man page link

当你这样做时

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

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

修复第一步,为程序定义行为。


此外,尽管对上述错误可能没什么帮助,但当C库函数返回错误时(通常为整数为-1,指针为NULL),它也会设置全局errno。使用perrorstrerror(errno)获取人为错误消息。始终在检测到错误时记录错误,它不仅可以帮助解决错误,还可以解决代码错误问题,还可以解决文件权限等外部问题,即使在程序“准备就绪”后也可能发生。

答案 1 :(得分:1)

这是文件创建模式的问题。创建的文件的默认权限不允许您重新打开它。只需在open()中添加第三个参数即可。 所以,你的解决方案将是:



        #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;
         /*ADD FILE PERMISSION HERE AS A THIRD PARAMETER. */
         fd = open("input.txt", flags, 0777);

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

或者您可以阅读 umask并查看 this 页面作为补充提示。