Basicaly, im writing a shell in C.. Im trying to implement the pipe feature, which is almost done:
> ls | cat -e | wc | wc -l
> 1
But i have a problem when trying to pipe a more slower/longer execution.
Indeed, when i try to pipe the result of 'cat /dev/urandom', it basicly waits...
> cat /dev/urandom | cat
>
But, when i send a SIGINT (with ctrl + c) to stop it, then it prints on STDOUT the resulted buffer..
when i ctrl + c , cat /dev/urandom
So my question is: where should i be looking at to try fix this ?
PARTS OF MY PIPE EXECUTION:
int exec_apipe(t_me *me, t_node *curs, int is_last)
{
int pfd[2];
int pid;
if (pipe(pfd) == -1 || !curs)
return (0);
if (!(curs->pid = fork()))
{
dup2(me->fd_in, 0);
me->fd_in > 0 ? close(me->fd_in) : 0;
if (!is_last)
dup2(pfd[1], 1);
else if (curs->parent->parent && curs->parent->parent->fd_out >= 0)
dup2(curs->parent->parent->fd_out, 1);
close(pfd[0]);
exec_mpipe(me, curs);
exit(-1);
}
else if (curs->pid > 0)
{
waitpid(curs->pid, &(curs->ret), WUNTRACED);
handle_pid(me, curs->ret);
close(pfd[1]);
me->fd_in = pfd[0];
}
return (pid >= 0 ? 1 : -1);
}
I hope someone will understand what im saying, and maybe can help.. Thanks
You need to start all the programs in your pipeline before you wait for any of them to complete.
Your shell implementation is waiting for each pipeline element to finish before it starts the next one. But /dev/urandom
is an endless stream; cat /dev/urandom
will run until killed. So the second cat
never gets started until you control-C the first one.