user2823499
user2823499

Reputation: 83

Communicating with child processes using pipes, redirection and filestreams

I'm having some difficulty implementing inter-process communication in C. I have simplified my problem to the following block of code, wherein I create pipes, fork the process, and redirect the IO for the child:

int main(void) {
    int parentToChild[2];
    int childToParent[2];
    pid_t pid = 1;
    char buffer[80];
    FILE *writeStream;
    FILE *readStream;

    pipe(parentToChild);
    pipe(childToParent);

    pid = fork();

    if(pid == 0) { // I'm the child. I read from stdin, and write to stdout.
        close(parentToChild[1]);
        close(childToParent[0]);
        dup2(parentToChild[0], 0);
        dup2(childToParent[1], 1);
        close(parentToChild[0]);
        close(childToParent[1]);
        fgets(buffer, 80, stdin); // wait for the parent to send something
        fprintf(stderr, "I got %s\n", buffer); // tell the world I got it
        fprintf(stdout, "Child message\n"); // send message back to the parent
    }

    if(pid != 0) { // I'm a parent
            close(parentToChild[0]);
            close(childToParent[1]);
            /* writeStream connected to stdin of child */
            writeStream = fdopen(parentToChild[1], "w");
            /* readStream connected to stdout of child. */
            readStream = fdopen(childToParent[0], "r");
            fprintf(writeStream, "Hello, World!\n");
            fgets(buffer, 80, readStream); // comment this out and the child will be able to read the "Hello World". Why is this?
            fprintf(stderr, "Parent just got %s", buffer);
    }



    return 0;

}                                           

If I execute this, the parent just seems to wait on the child forever. Is there anything obviously wrong with how my streams are configured? If I have it so the child is reading only and the parent is writing only (or the other way around), it works fine, but I can't manage having both processes read-and-write. The order seems fine, with the child expecting stdin first and the parent writing first.

Thanks.

Upvotes: 0

Views: 643

Answers (2)

krouis
krouis

Reputation: 129

When I fflush (writeStream) after the parent's fprintf(writeStream, "Hello, World!\n") everything works fine. I believe there is a problem with the buffering of the pipe.

Try to look at man 3 setvbuf

setvbuf() function may be used on any open stream to change its buffer. The mode argument must be one of the following three macros:

         _IONBF unbuffered
         _IOLBF line buffered
         _IOFBF fully buffered

so I guess that setting your writeStream to _IONBF (unbuffered) would solve the problem.

Upvotes: 2

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

From dup2 man page:

After a successful return from one of these system calls, the old and new file descriptors may be used interchangeably. They refer to the same open file description

Thus, closing one of the pipes closes one of the standard file descriptors. Don't do that.

Upvotes: 0

Related Questions