Este exemplo permite observar como as primitivas pipe() e dup() podem ser combinadas com o objetivo de produzir comandos shell do tipo ls|wc|wc. Note que é necessário fechar os descritores não utilizados pelos processos que executam a rotina.
/* arquivo test_pipe.c */
/* este programa é equivalente ao comando shell ls|wc|wc */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
int p_desc1[2] ;
int p_desc2[2] ;
void faire_ls()
{
/* saida padrao redirecionada para o 1o. tubo */
close (1) ;
dup(p_desc1[1]) ;
close(p_desc1[1]) ;
/* fechamento dos descritores nao-utilizados */
close(p_desc1[0]) ;
close(p_desc2[1]) ;
close(p_desc2[0]) ;
/* executa o comando */
execlp("ls","ls",0) ;
perror("impossivel executar ls ") ;
}
void faire_wc1()
{
/* redirecionamento da entrada padrao para o 1o. tubo*/
close(0) ;
dup(p_desc1[0]) ;
close(p_desc1[0]) ;
close(p_desc1[1]) ;
/* redirecionamento da saida padrao para o 2o. tubo*/
close(1) ;
dup(p_desc2[1]) ;
close(p_desc2[1]) ;
close(p_desc2[0]) ;
/* executa o comando */
execlp("wc","wc",0) ;
perror("impossivel executar o 1o. wc") ;
}
void faire_wc2()
{
/* redirecionamento da entrada padrao para o 2o. tubo*/
close (0) ;
dup(p_desc2[0]) ;
close(p_desc2[0]) ;
/* fechamento dos descritores nao-utilizados */
close(p_desc2[1]) ;
close(p_desc1[1]) ;
close(p_desc1[0]) ;
/* executa o comando */
execlp("wc","wc",0) ;
perror("impossivel executar o 2o. wc") ;
}
int main()
{
/* criacao do primeiro tubo*/
if (pipe(p_desc1) == -1)
perror("Impossivel criar o 1o. tubo") ;
/* criacao do segundo tubo */
if (pipe(p_desc2) == -1)
perror("impossivel criar o 1o. tubo") ;
/* lancamento dos filhos */
if (fork() == 0) faire_ls() ;
if (fork() == 0) faire_wc1() ;
if (fork() == 0) faire_wc2() ;
exit(0);
}
Resultado da execução:
euler:~/> ls|wc|wc euler:~/> 1 3 24 euler:~/> test_pipe euler:~/> 1 3 24