Hey i have been trying to implement multiple piping in a shell but it is not working. Can anyone help me in finding out the problems.
It is working properly if there is no pipe in the input command.
here is the code that i have written so far:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int status, k = 0, count = 0;
char input[512], *cmd, *sepcmd[256], *cm;
pid_t pid;
while (1)
{
printf("\nshell:");
cmd = fgets (input, 512, stdin);
char *p = cmd;
if (strchr(cmd, '|')) { //pipe present in input command
strsep(&p,"|");
char ** arg;
int fd[256][2];
pipe(fd[k]);
if (pipe(fd[k]) == -1)
{
perror("pipe");
}
switch (fork()) //executing first command
{
case -1:
perror("fork"); exit(1);
case 0:
close(fd[k][0]);
dup2(fd[k][1],1);
close(fd[k][1]);
parseline(cmd, argv);
execvp(argv[0], argv);
perror("error");
exit(1);
}
for(k=1; k<=count-2;k++) //executing all commands except first and last
{
close(fd[k-1][1]);
pipe(fd[k]);
if (pipe(fd[k]) == -1)
{
perror("pipe");
}
switch (fork())
{
case -1:
perror("fork"); exit(1);
case 0:
close(fd[k][0]);
dup2(fd[k-1][0],0);
close(fd[k-1][0]);
dup2(fd[k][1],1);
close(fd[k][1]);
parseline(cmd, argv);
execvp(argv[0], argv);
perror("error");
exit(1);
}
}
k = count - 1;
close(fd[k-1][1]);
switch (fork())
{
case -1:
perror("fork"); exit(1);
case 0:
close(fd[k][1]);
dup2(fd[k-1][0],0);
close(fd[k-1][0]);
parseline(cmd, argv);
execvp(argv[0], argv);
perror("error");
exit(0);
}
}
else { //no pipe in input command
parseline(cmd, argv);
printf("%s\n", argv[0]);
if(strcmp(argv[0], "exit") == 0)
{
exit(0);
}
pid = fork();
if(pid == -1)
{
perror("child process creation failed");
exit(1);
}
else if(pid == 0)
{
if(execvp(argv[0], argv)<0)
{
printf("command not found");
}
}
else
{
wait(&status);
}
}
}
}
int parseline(char *cmd, char**argv) {
int argc =0; char *cmdprsr = " \n\t\r";
for (argc = 0; argc < 100; argc++)
{
if ((argv[argc] = strtok(cmd, cmdprsr)) == NULL)
break;
cmd = NULL;
}
}