3

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??) ?

1 Answers1

3

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.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
  • Your answer is really helpful! Because when I tried googling this problem I didn't find any answers (and thought of cache instead of buffer) Thank you very much! Thanks to you, now I can feed that face in an elegant way ;-) – Philip Brown Sep 06 '16 at 12:18
  • What if you simply set the buffer to the size of the previous message that went through it or the size of the next message, whichever is larger? A buffer being available usually speeds up processing, so I'm a bit hesitant with the idea of just getting rid of it, but also am not a fan of hard-coded limits unless they have a good reason. – kayleeFrye_onDeck Oct 01 '18 at 20:15
  • 1
    @kayleeFrye_onDeck I doubt that would help; you could still read a stale cached value. Buffering *is* useful; it's a fairly rare situation like this where you would want to disable it. If you have a different case where you want buffering but might read stale data, then perhaps you should ask a separate question for your own situation. – jamesdlin Oct 02 '18 at 04:22
  • @jamesdlin That makes sense. What if you disabled it, and then immediately re-enabled it? – kayleeFrye_onDeck Oct 02 '18 at 18:42