0

I'm experimenting-learning and have written a small program that should periodically write text into a file.

$ cat test.c

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

int main() {
    printf("First\n");
    errno = 0; 

    FILE *f = fopen("test.file", "a");
    int c = 0;
    //int fd = 0;

    if (f == NULL) {
        printf("Something went wrong %d\n", errno);
        return 1;
    }

    //fd = fileno(f);

    printf("Starting loop\n");

    while(1) {
        c = fprintf(f, "12345\n");
        //syncfs(fd);
        printf("print %d, %d\n", c, errno);
        sleep(10);
    }
    return 0;
}

The file test.file already exists and is not empty. I compile test.c with

$ gcc -Wall test.c

The problem is that the test.file is not updated, although there does not seem to be any errors. Sample output

$ ./a.out
First
Starting loop
print 6, 0
print 6, 0

so it says that fprintf() has written 6 bytes and errno is zero which is correct.

I though it might be connected with filesystem cache (I'm actually trying to learn about filesystems, so this idea is probably completely insane), so I've added a call to syncfs() to force writing data on disk. This part is commented out in the source code above. Still it doesn't work.

If I change the mode in fopen() from a to w and rerun the program then test.file is cleared, so I'm looking at the right file.

Why it doesn't get appended though?

I have gcc 5.4.0 on Ubuntu 16.04

xaxa
  • 1,057
  • 1
  • 24
  • 53
  • 6
    `fflush` would be the appropriate function to call, not `syncfs`. – Cody Gray - on strike Aug 14 '16 at 17:21
  • `FILE` s (includes stdout) are buffered wrappers around raw file handles. When you `printf`, you only append to a buffer (the one pointed to by the `stdout` `FILE*`) and only when the buffer gets full is an actual system called issued. You can use `fflush` to flush the buffer before it gets full. – Petr Skocik Aug 14 '16 at 17:26
  • 2
    Possible duplicate of [The fprintf() function can't persist the data to the file; must be followed by fflush() function?](http://stackoverflow.com/questions/36073886/the-fprintf-function-cant-persist-the-data-to-the-file-must-be-followed-by-f), http://stackoverflow.com/questions/20267244/why-fprintf-doesnt-write-directly-into-the-file-unless-fflush-is-used, http://stackoverflow.com/questions/24101566/write-to-file-not-visible-before-close-fflushstdout-ineffective, http://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-newline-is-in-the-format-strin – Cody Gray - on strike Aug 14 '16 at 17:29
  • And more (related but not actual duplicates): http://stackoverflow.com/questions/2340610/difference-between-fflush-and-fsync, http://stackoverflow.com/questions/214271/c-equivalent-of-autoflush-flush-stdout-after-each-write, http://stackoverflow.com/questions/21306369/eclipse-make-the-fflushstdout-as-default-after-printf-calling, http://stackoverflow.com/questions/31072636/while-writing-into-a-file-where-intermediate-data-stored-in-between-fopen-an – Cody Gray - on strike Aug 14 '16 at 17:30
  • One option would be to set line buffering on the output file: `char buffer[BUFSIZ]; …fopen…; setvbuf(buffer, sizeof(buffer), _IOLBF, f);` (which returns zero on success — you could check that). This will give you output to the file each time a newline is written to the standard I/O stream. – Jonathan Leffler Aug 14 '16 at 17:55

0 Answers0