Search code examples
cfilegccfwritefread

fread isnt reading an updated value despite the file has been changed by another program


There are two programs that are working with my special file at the same time. They have a common beginning:

    #define TASK_POSITION 0x0100

    #include <stdio.h>
    #include <stdlib.h>
    #include <inttypes.h>

    int main() {

        FILE * control_file;
        unsigned int task_code;
        fpos_t task_position;

        control_file = fopen("/home/anonymous/.control", "r+");
        fseek(control_file, TASK_POSITION, SEEK_SET);
        fgetpos(control_file, &task_position);

But later they have a very different code

  • 1st program could change a value at TASK_POSITION offset of this file:

        /* ... lots of code there ... */
    
        task_code = 0xFEEDFACE;
    
        fsetpos(control_file, &task_position);
        fwrite(&task_code, 4, 1, control_file);
          fflush(control_file);
            sleep(1);
    
        fclose(control_file);
        return 0;
    }
    
  • 2nd program is repeatedly freading a value at the same offset of this file:

        for (;;) {
            fsetpos(control_file, &task_position);
            fread(&task_code, 4, 1, control_file);
            if (task_code == 0xFEEDFACE) {
                /* ... Do something awesome! ... */
            }
            else { // remove after debugging
              fprintf(stdout, "not hungry yet :P 0x%08x value has been read... \n"); 
              fflush(stdout);
            }
            sleep(60);
        }
    
        // just in case
        fclose(control_file);
        return 0; 
    }
    

By default, there is 0x12345678 value stored at TASK_POSITION offset.

Here is a problem:

after the 1st program has been launched and completed its' work, I could see in a hex editor that a special file has been changed successfully. However: for some unknown to me reason, fread of 2nd program keeps reading the same old value - 0x12345678 !

Although I found a temporary workaround by fclosing/fopening this file during the each iteration of 2nd program's infinite cycle (between the fread checks) it does not look like the best possible solution! Please tell: how to force fread to actually re-read a new value from a file, instead of just returning a previously read value (from its' cache??) ?


Solution

  • C's standard I/O functions are typically buffered. To disable buffering, you can do:

    setvbuf(control_file, NULL, _IONBUF, 0);
    

    immediately after you open the file, before you perform any I/O on it.