0

Buffered IO streams have a strange behavior on fork().

In the sample snippet shown below, the file being read is 252 bytes in size. After the fork(), the child is successfully reading a line and printing on the screen. however, when the control goes back to the parent, the file offset is set to the end of file for some reason and the parent process isn't able to read anything from the stream. If fork() creates a dup of the file descriptors ( which works fine with replicating the same program using system calls read() and write() ), one would expect the parent process to read the next line from the stream but that doesn't seem to happen here. File offset is set to the end of file when the control reaches parent. Can someone shed some light on this ?

int main(void)
{    
    char buffer[80];
    FILE *file;
    pid_t pid;
    int status;

    /* Open the file: */
    file = fopen(FILENAME, "r");

    if ((pid = fork()) == 0){
        fgets(buffer, sizeof(buffer), file);
        printf("%s", buffer);
    }
    else{
        waitpid(pid, &status, 0);
        printf("Offset [%d]\n", ftell(file));

        fgets(buffer, sizeof(buffer), file);
        printf("%s", buffer);
    }
}
Kamiccolo
  • 7,758
  • 3
  • 34
  • 47
user3012653
  • 85
  • 1
  • 13

1 Answers1

0

fgets() in the child process is fully buffered as it's reading data from file. On my system a fully buffered buffer is of size 1024..So a single read() has the entire contents of the file (252 bytes) in the fgets() buffer. So as the control gets back to the parent, from the child, the offset is set to the end of the file.

Doing a fflush() in the child process, before it returns, ensures the data in the fgets() buffer is discarded and therefore the file offest is properly set back when the control reaches the parent.

user3012653
  • 85
  • 1
  • 13