2

I'm writing a file using a c code on a unix system . I open it , write a few lines and close it. Then i call a shell script, say code B where this file is to be used and then return back to main program. However, when code B tries to read the file, the file is empty.

I checked the file on the file system, its size is shown as 0 and no data is present in file. However after killing the running c code process, file has data present in it.

Here is the piece of code -

void writefile(){
  FILE *fp;
  fp = fopen("ABC.txt","w");
  fputs("Some lines...\n",fp);
  fclose(fp);

  system("code_B ABC.txt");
}

Please advise how can I read the file in the shell script without stopping the c code process.

Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
abhisahay
  • 65
  • 5

3 Answers3

3

If there's some time between the fputs and fclose, add

fflush(fp);

This will cause the contents of the disk file to be written.

Mark Harrison
  • 297,451
  • 125
  • 333
  • 465
3

You should do fsync() after the fclose(), to guarantee the writing of the file to the disk.

Take a look at this question:

Does Linux guarantee the contents of a file is flushed to disc after close()?

Community
  • 1
  • 1
miluz
  • 1,353
  • 3
  • 14
  • 22
  • 1
    Still, the contents should also be `read` from the buffers afterwards, even if the content is not **physically** written to disc yet - the kernel / file system should ensure that – Andreas Fester Sep 09 '14 at 05:31
3

The kernel ensures that data which is written to a file can be read back afterwards from a different process, even if it is not physically written to the disc yet. So, in usual scenarios, there is no need to call fsync() - still, even with fsync(), the filesystem could decide to further delay physical writes.

One common problem is that the C library has not flushed its buffers yet, in which case you would need to call fflush() - however, you are calling fclose() before launching your sub process, and fclose() internally calls fflush().

Actually, since system() is using a shell to launch the command passed as parameter, you can use the following simple SSCCE to verify that it works:

#include <stdio.h>

void writefile(){
  FILE *fp;

  fp = fopen("ABC.txt","w");
  fputs("Some lines...\n",fp);
  fclose(fp);

  system("cat ABC.txt");
}

int main() {
  writefile();
  return 0;
}

Here, system() simply calls the cat command to print the file contents. The output is:

$ ./writefile
Some lines...
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
  • I tried the same , but it doesn't work. I called fsync() after fcolse() but to no avail. The files content are still not reflected till the process ends. – abhisahay Sep 09 '14 at 18:16
  • Finally issue is resolved. Calling `fflush()` before `fclose()` did the trick. – abhisahay Sep 10 '14 at 18:40
  • That is interesting. Which compiler version and which C runtime library version are you using, and on which platform/operating system version? Btw, you should accept the answer from @MarkHarrison - obviously he was on the right track... – Andreas Fester Sep 10 '14 at 18:48