Reputation: 27
I'm relatively new to piping and forking in C,
I have a parent and a child process and try to communication between them.
I created a pipe such that: stdout of parent will connect to stdin of child, and stdout of child will connect to stdin of parent.
I test this by trying to make parent sent out "A" through its stdout and then child will receive "A" from its stdin, after that it should send back "B" from its stdout to parent's stdin.
Here is my code,
bool pget_input(void){
char buffer[80];
fprintf(stdout,"A");
fprintf(stderr,"Parent sent out 'A' to child \n");
do{
if (!fgets(buffer, 20, stdin)) {
fprintf(stderr,"Parent failed to recieve from child\n");
return false;
}
fprintf(stderr,"Parent receiving from child\n");
if(strcmp(buffer, "B")==0){
fprintf(stderr,"Parent success recieve child's reply");
}
continue;
}while(true);
}
int main(int argc, char** argv){
pid_t pid = fork();
int pipe1[2];
int pipe2[2];
if (pipe(pipe1)==-1 || pipe(pipe2)==-1){
fprintf(stderr,"pipe failed\n");
exit(1);
}
if(pid > 0){
//parent
close(STDIN_FILENO); //close stdin
dup(pipe1[0]); //replace stdin with pipe1 read
close(STDOUT_FILENO); //close stdout
dup(pipe2[1]); //replace stdout with pipe2 write
//close pipe1 and pipe2 read write
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
pget_input();
wait(0);
}else if(pid ==0){
//child
close(STDOUT_FILENO); //close stdout
dup(pipe1[1]); //replace stdout with pipe1 write
close(STDIN_FILENO); //close stdin
dup(pipe2[0]); //replace stdin with pipe2 read
//close pipe1 and pipe2 read write
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execl("./child", "not matter", NULL);
perror("execvp failed");
exit(1);
}else{
fprintf(stderr,"fork failed\n");
exit(1);
}
fprintf(stderr,"Exiting\n");
exit(1);
}
where ./child:
bool cget_input(void){
char buffer[80], command[80];
fprintf(stderr,"Child trying receive from parent\n");
do{
if (!fgets(buffer, 20, stdin)) {
fprintf(stderr,"child failed to receive from parent\n");
return false;
}
sscanf(buffer, "%s", command);
if(strcmp(buffer, "A") == 0){
fprintf(stderr,"Child received 'A' from Parent and sending out 'B'\n");
fprintf(stdout, "B");
}
continue;
}while(true);
}
int main ()
{
if(!cget_input()){
return 0;
}
return 1;
}
As result, both parent and child's stdin didn't receive anything, didn't go pass
if (!fgets(buffer, 20, stdin))
Can someone point out what went wrong in my code? Thank you,
Upvotes: 1
Views: 2601
Reputation: 6752
You must set up the pipes before you fork.
Here is an outline of the order things need to be done:
After a fork, the parent and child are two different processes and the parent has no power to modify the file descriptors of child at that point. Any shared file descriptors must be set up before a fork.
Upvotes: 2