Reputation: 3722
I have written the below method to fork and execute commands separated by multiple pipes( test with : ls -lrt | grep "check" | wc -l . However it is not resulting in any output, could any one please spot my mistake. Thanks.
void execCmd (pInfo *info)
{
int i, j, k, m;
struct comType *comm, *comm1, *comm2;
if(info->noOfPipes > 2)
{
// DOES NOT WORK
printf("Start\n");
comm=&(info->cArr[0]);
comm2=&(info->cArr[(info->ppNum)-1]);
int fds[2];
pipe(fds);
pid_t pid = fork();
if(pid == -1)
{
perror("fork failed");
exit(1);
}
if(pid == 0)
{
printf("1st child execution here\n");
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
close(fds[1]);
execvp(comm->cmd,comm->parms);
}
for (k=1;k<=((info->ppNum)-1);k++)
{
printf("For loop executionn number %d",k);
comm1=&(info->cArr[k]);
printf ("comm 1 : %s\n",comm1->cmd);
pid = fork();
if(pid == -1)
{
perror("fork failed");
exit(1);
}
if(pid == 0)
{
//2nd to n-1 child process
dup2(fds[0], STDIN_FILENO);
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
close(fds[1]);
execvp(comm1->cmd,comm1->parms);
}
wait(NULL);
}
pid = fork();
if(pid == -1)
{
perror("fork failed");
exit(1);
}
if(pid == 0)
{
//nth child process
printf("Last child execution\n");
close(fds[1]);
dup2(fds[0], STDIN_FILENO);
close(fds[0]);
execvp(comm2->cmd,comm2->parms);
}
close(fds[0]);
close(fds[1]);
wait(NULL);
wait(NULL);
}
}
Upvotes: 2
Views: 6995
Reputation: 738
This following code should give you an idea how to implement the pipelining:
#define STDIN 0
#define STDOUT 1
void exec_cmd(struct comType cmd) {
execvp(cmd->cmd, cmd->params);
}
void pipeCmds(struct comType* cmds) {
int fd[cmds_length * 2] = {0};
pid_t pid = 0;
for (int i = 0; i < cmds_length; i++) {
if (pid = fork() == 0) {
//child: make this cmd's output the other cmd's input
pipe(fd + (2*i) );
close(STDOUT);
dup(fd[i]);
if(i > 0) {
close(STDIN);
dup(fd[i-1]);
}
exec_cmd(cmds[i]);
close(fd[i]);
}
}
}
Note that the main idea is that each command is executed in a separate process (via fork
) and the output goes to the next command's input rather than to the default stdout
(with file descriptor 1), and the same for the input - stdin
(file descriptor 0).
Upvotes: 2