Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fgetc blocking : problem with reading from a pipe

Tags:

c

fork

pipe

ipc

I want to be able to fork a process and have the child and parent have a bi-directional link using pipes. I create 2 pipes and make parent read from the end of 1st pipe and write to the beginning of the second and vice versa but I'm running into some issues.

A short version of the code is here (error checking omitted)

void PlayGame(int in, int out, int first, int id){  
    FILE *inStream = fdopen(in, "r");
    FILE *outStream = fdopen(out, "w");

    if (first) fputc( id, outStream);
    while(1){
        int c = fgetc(inStream);
        printf("process %d has read %d\n", id, c);
        fputc( id, outStream);
    }
}


int main (void){
    int fd[2];
    int fd1[2];
    pipe(fd);
    pipe(fd1);

    pid_t pid = fork();

    if (pid == 0){
        PlayGame(fd[0], fd1[1], 0, 1);
        exit(0);
    }
    PlayGame(fd1[0], fd[1], 1, 2);
    exit(0);
}

What I want to achieve is that a parent writes a character to the pipe and the child waits until it receives a char and then writes its response and waits again for the parent. What am I doing wrong here?

Both the parent and the child get stuck at the first call to

int c = fgetc(inStream);
like image 271
randomThought Avatar asked Dec 05 '25 23:12

randomThought


1 Answers

stdio (fputc and friends) are buffered by default, meaning that the fputc() doesn't actually write the byte to the pipe, but stores it in-memory to be written out when the buffer is later flushed.

You can either do an fflush(outStream) after the fputc, or do a setvbuf(outStream, NULL, _IONBF, 0); after the fdopen in order to turn off buffering on that file.

like image 125
nelhage Avatar answered Dec 08 '25 15:12

nelhage



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!