next up previous
Next: Comunicação entre pais e Up: Exemplos globais Previous: Exemplos globais

Implementação de um comando com tubos

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



Celso Alberto Saibel Santos 2000-11-14