Reputation: 83
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
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
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