0

I am repeatedly reading a previously-opened file using fscanf and rewind:

#include <stdio.h>
#include <errno.h>
#include <unistd.h>

void read_opened_file(FILE *file, int *value)
{
   errno = 0;
   fscanf(file, "%d", value);
   if (errno != 0) perror("fscanf error");
   
   errno = 0;
   rewind(file);
   if (errno != 0) perror("rewind error");
}

int main(int argc, char* argv[])
{
   int value = 0;
   FILE *file = fopen(argv[1], "r");
   
   errno = 0;
   if (setvbuf(file, NULL, _IONBF, 0) != 0) perror("setvbuf error");
   
   for (int i = 0; i < 10; ++i)
   {
      read_opened_file(file, &value);
      printf("value = %d\n", value); fflush(stdout);
      sleep(1);
   }

   fclose(file);
   return 0;
}

However, any changes made to the file on disk behind the scenes by gedit, echo >, cp are not reflected: the function keeps reporting the first (cached?) value read (and errno is not set).

  • When I setvbuf(file, NULL, _IONBUF, 0); as suggested here, changes made by cp and echo > are reflected, but changes made by gedit are still not reflected.
  • When I use fopen and fclose every loop iteration everything is as expected.

How do I fix the above code without fopen and fclose every time?

Sparkler
  • 2,581
  • 1
  • 22
  • 41

1 Answers1

3

You can't. The gedit program does not change the file. That's simply not how it works. So you will not see any change to the file.

The changes gedit makes are done by replacing the old file with a new file. You must close the old file and open the new file to see the changes that gedit made.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Any idea why the "cached" value keeps showing up if the file is replaced by `gedit`? – Sparkler Nov 09 '20 at 18:29
  • 2
    @Sparkler The old file is replaced with the new file in the directory. But if you have the old file open, that has no effect on you. You won't somehow close the old file and open the new file automatically. It is perfectly legal and well-defined to keep a file open after it has been replaced with a different file in one or more directories. – David Schwartz Nov 09 '20 at 18:39
  • I think OP's claim that the same happened with `echo >` or `cp` is false, too. These do not create new files but overwrite the existing file. – R.. GitHub STOP HELPING ICE Nov 09 '20 at 19:32
  • @R..GitHubSTOPHELPINGICE At least on my machine, `echo > foo` opens and truncates `foo` rather than replacing it. – David Schwartz Nov 09 '20 at 19:39
  • @David: Yes, this is a hard requirement of the shell command language. – R.. GitHub STOP HELPING ICE Nov 09 '20 at 20:01