Hi guys,
I took it upon myself to learn the mysteries of linux.
I'm trying to write a shell that can handle more than one pipe.
Here's the code:
typedef struct command_link{
char *command;
char *argv[MAX_ARGS];
int argc;
struct command_link* next;
int isPiped;
}command_t;
int pipedCommand(command_t *command)
{
int fd[2];
int status;
int isFirstPipe = 1;
int pid = -1;
status = pipe(fd);
if (status < 0)
{
printf("\npipe error");
return -1;
}
while (1)
{
pid = fork();
if (pid < 0) /*handle fork error*/
{
printf("\nfork error");
return -1;
}
else if (pid == 0) /*handle son code*/
{
//while there are more commands close stdout and redirect output to pipe
if (command->next)
dup2(fd[1], 1);
//close stdin and redirect input from pipe
if (!isFirstPipe)
dup2(fd[0], 0);
//keep pipe opened while there are commands
if (!command->next)
{
close(fd[0]);
close(fd[1]);
}
execv(command->command, command->argv);
//if errors exist execv wouldn't have been invoked
printf("\nexecv error");
return -1;
}
else /*handle father code*/
{
isFirstPipe = 0;
//check for more commands and connect them to the opened pipe
if (command->next)
{
command = command->next;
continue;
}
//close pipe and wait for the last son to die - then finish
close(fd[0]);
close(fd[1]);
while(wait(&status) != pid);
break;
}
}
}
This works okay for one pipe.
When I use two pipes the shell hangs and ignores my inputs.
I'm guessing a leaky pipe somewhere. But I can't see the flaw in my logic:
The "father" process keeps forking out children while there are still commands in the linked list. Every child process gets the fathers file descriptors (where i/o is always stdin/stdout). The child process replaces the file i/o descriptors of the father process with the pipe file descriptors according to their place in the link :
head : in - stdin, out - fd[1]
middle link: in - fd[0], out - fd[1]
tail: in - fd[0], out - stdout
Where is the error?
Thank you