I'm trying to make a program that forks once and while the parent waits for the child terminates, this child forks again and then executes two execs. There is a Pipe on the program and I've checked the return values of every dup2() and pipe() on the program -just omitted them here to make it looks more concise-. The problem is that I only get the result of ls -a | sort -r AFTER the program finishes. The code is:
#include <cstdio>
#include <cstring>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc, char *argv[]) {
printf("Shell> \n"); fflush(stdout);
pid_t pid1;
pid_t pid2;
int status = 0;
int fd[2];
if(pipe(fd) < 0) {
printf("FATAL ERROR.\n");
}
pid1 = fork();
if(pid1 > 0) { // Parent
waitpid(pid1, &status, 0);
printf("\t\t------PID1 Complete-------\n\n");
}
else { // Child
if(pid1 == 0) {
printf("ON CHILD\n");
pid2 = fork();
if(pid2 > 0) { // Child -> Parent
printf("ON CHILD-Parent\n");
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
waitpid(pid2, &status, 0);
printf("ON CHILD-Parent after wait\n");
execlp("sort", "sort", "-r", NULL);
perror("Problem with execlp\n");
exit(1);
}
else { // Child -> Child
printf("ON CHILD->Child\n");
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
execlp("ls", "ls", "-a", NULL);
perror("Problem with execvp\n");
exit(1);
}
} // End of if(pid1 == 0)
} // End of Child
printf("\nEnd of program.\n");
return 0;
}
My current output is:
Shell>
ON CHILD
ON CHILD-Parent
ON CHILD->Child
ON CHILD-Parent after wait
I think the problem is on the waits, but I just can't figure out how to make this work. Any ideas? Thanks!
fd
are assigned when the pointer tofd
is passed topipe(fd)
. – nategoosewaitpid(pid2, &status, 0);
? That could cause the program pid2, which is ls, to go to sleep because it is trying to write to a full buffer, which won't get read because pid1 is asleep waiting on pid2. This is a deadlock situation, but I don't think that is your problem. – nategoose