Reputation: 41
when I execute this function with ls | head
, it hangs in the second child process after printing out the files and directories. Could someone tell me what I miss here? Thanks in advance
int unipipe(char* lhs[], char* rhs[])
{
int pfd[2];
int status, cid;
pid_t pid;
char buf;
if((lhs != NULL) && (rhs != NULL))
{
if(pipe(pfd) != 0)
{
perror("pipe");
return -1;
}
if((pid = fork()) < 0)
{
perror("fork");
return -1;
}
else if(pid == 0)
{
close(1); //close the unused read end
dup2(pfd[1], STDOUT_FILENO);
//execute the left-hand side command
close(pfd[0]);
execvp(lhs[0], lhs);
_exit(EXIT_SUCCESS);
}
if(setpgid(pid, 0) < 0)
{
perror("setpgid");
return -1;
};
cid = waitpid(pid, &status, 0);
if((pid = fork()) == 0)
{
close(0);
dup2(pfd[0], STDIN_FILENO);
close(pfd[1]); //close the unused write end
execvp(rhs[0], rhs);
_exit(EXIT_SUCCESS);
}
else
{
waitpid(pid, &status, 0);
}
}
Upvotes: 0
Views: 2016
Reputation: 5221
to make your program running, you delete the first:
cid = waitpid(pid, &status, 0);
at:
else
{
waitpid(pid, &status, 0);
}
you replace it with :
wait(); // for the fist child
wait(); // for the second child
your program will be running.
Upvotes: 0
Reputation: 2381
You wait for the first process to exit before starting the second one. Each pipe has a buffer, and once this buffer is full, the I/O functions block, waiting for a few bytes to be read from the pipe so that more can "flow in". Chances are your first process is blocking on the pipe and therefore never exits.
I'd declare two variables of type pid_t, one for each child, and only wait for them both once both have been successfully started.
Upvotes: 2