Prueba esto:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char** argv)
{
int pipefd[2];
int childpid,childpid2;
char* cmd[3]={"ls",NULL,NULL};
char* cmd2[3]={"grep",".c",NULL};
pipe(pipefd);
if(childpid=fork()){
//parent
close(pipefd[1]);
dup2(pipefd[0],STDIN_FILENO);
execvp("grep",cmd2);
}else{
//child
//write
close(pipefd[0]);
dup2(pipefd[1],STDOUT_FILENO);
execvp("ls", cmd);
}
return 0;
}
En realidad, el programa sale de inmediato; de hecho, el proceso principal sale antes los niños se ejecutan, razón por la cual hay un indicador de shell antes de "test.c".
Puedes mejorar un poco las cosas agregando esto en tu padre:
wait(childpid);
wait(childpid2);
lo que hará que el padre salga después de ambos hijos.