So I have been trying to implement piping in my own shell program so that I can actually understand what UNIX is doing. I'm very very close at the moment, but for some reason my program is going into an infinite loop when I pipe. I'm pretty sure my problem is stemming from my waitpid arguments not ever letting the last pipe close, because if I make the final loop in the code below be i is less than count-1 instead of i is less than count it will run the command on the left of the pipe. But once I put it back to i is less than count it just loops forever.
For example ls | grep -i cpp would just loop the normal ls command infinitely. I assume this means I'm not closing the pipes correctly, but as far as I can tell I am doing so in both the parent and child just like I am supposed to.
if(pipes)
for (i=1;i<count;i++){
if( pipe(fd) ==-1)
{perror("Pipe failure");
return;}
read[i+1] = fd[0];//fd=file descriptor
write[i] = fd[1];
}
}
for(i=0;i<count;i++){
pid = fork();
if(pid < 0)
{printf("fork failed");}
else if(pid>0)
{pids[i] = pid;}
else
{ if(write[i] != -1)
{if(dup2(write[i],STDOUT_FILENO) ==-1){
perror("dup2 failure");
exit(1);
}
}
if(read[i] !=-1)
{if (dup2(read[i], STDIN_FILENO)==-1)
{perror("dup2 failure");
exit(1);}
}
for (j=0; j<count; j++)//close copies
{close(write[j]);
close(read[j]);}
execvp(input[i], input);
exit(1);
}// end else
}//end for
for(i=0; i < count; i++){//deal with children
waitpid(pids[i], &status,0);
if(write[i] != -1)
close(write[i]);
if( read[i] != -1)
close (read [i]);
}
return (status);}
I think I'm really really close to the solution but for the time being I'm stuck. I've researched piping a ton, but I guess I'm just not quite getting it. Thanks for any help.