I'm trying to simulate bash pipe like ls | grep ma | wc
but for some reason it seems like my third child process that executes wc
just hangs. I can't find the culprit, please help.
Here's my code:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define CMD_NUM 3
int main(void)
{
pid_t pids[CMD_NUM];
int *pipeFd;
int pipeFds[CMD_NUM - 1][2];
for (int i = 0; i < CMD_NUM - 1; i++)
if (pipe(pipeFds[i]) == -1)
perror("Error creating pipes");
pids[0] = fork();
if (pids[0] == 0)
{
printf("I'm in 1r if\n");
pipeFd = pipeFds[0];
close(pipeFd[0]);
close(1);
dup2(pipeFd[1], 1);
char* argv[] = {"ls", "-l", NULL};
execvp("ls", argv);
perror("Error ls execvp");
exit(1);
}
for (int i = 1; i < CMD_NUM - 1; i++)
{
printf("I'm in for\n");
pids[i] = fork();
if (pids[i] == 0)
{
close(0);
close(1);
pipeFd = pipeFds[i - 1];
close(pipeFd[1]);
dup2(pipeFd[0], 0);
pipeFd = pipeFds[i];
close(pipeFd[0]);
dup2(pipeFd[1], 1);
char* argv[] = {"grep", "ma", NULL};
execvp("grep", argv);
perror("Error in execvp");
exit(1);
}
}
pids[CMD_NUM - 1] = fork();
if (pids[CMD_NUM - 1] == 0)
{
printf("I'm in 2n if\n");
pipeFd = pipeFds[CMD_NUM - 2];
close(pipeFd[1]);
close(0);
dup2(pipeFd[0], 0);
char* argv[] = {"wc", NULL};
perror("hello");
execvp(argv[0], argv);
perror("Error en execvp");
exit(1);
}
for (int i = 0; i < CMD_NUM - 1; i++)
{
printf("I'm closing pipes\n");
pipeFd = pipeFds[i];
close(pipeFd[0]);
close(pipeFd[1]);
}
printf("I'm waiting for my last child\n");
waitpid(pids[CMD_NUM - 1], NULL, 0);
}
I'm only waiting for the last child because it's a requirement.