Jump to content

comunicação entre processos (pipes)


NameException

Recommended Posts

Boas,

Estou a fazer um programa, em C, em que algures é preciso criar novos processos, fork(), para executar comandos: execvp(). O meu problema está em guardar o output da system call execvp(), que deverá ser feito numa pipe(), mas nao sei como fazer isso... Ou seja, suponho que o problema esteja em que ainda nao percebi bem o modo de funcionamento das pipes...

Eis o código que ja desenvolvi, mas que apenas imprime na shell o output do comando, sem o guardar, pelo que nao tenho como o retornar para outro programa ou aplicação, que é basicamente a funcionalidade da aplicação.

(...)
(processo de sessao)
(...)

//criar processo do comando
int pid_comando;
if((pid_comando = fork())==-1)	{
  perror("fork pid_comando");
  exit(1);
}
//Este é o processo do comando
else{
   printf("Processo do comando arrancou...\n");
     	 	 	     	 	 	
   close(pipes_out[1]); 
     	 	 	   	 	 	     	 	
printf("Flag A\n");
    int exe = execvp(bytescpy, NULL);
    printf("Flag B\n");
     	 	 	   	 	 	
    if(exe==-1){
     perror("execv: ");
     exit(3);
    }
     	 		
    dup2(0, pipes_out[1]);
     	 		
    printf("Processo do comando terminou...\n");
}

(...)

Exemplo: Para o comando "/bin/date" eis o comportamento do codigo:

Processo sessao arrancou...

comando: /bin/date

Processo do comando arrancou...

Flag A

Seg Jan 14 15:40:25 WET 2008

Processo do comando arrancou...

Flag A

Seg Jan 14 15:40:25 WET 2008

O que me dá também a entender é que ao ser executada a system call execvp, "perco" o comando do programa, e este fica em standby... :wallbash:

Já agora, em que situações e de que modo se usa dup() e dup2(), pois suponho que a forma como a estou a utilizar nesse código nao deve estar correcta...

Um abraço

Link to comment
Share on other sites

Começa por separar aquilo que o processo filho faz, do que o processo pai faz.

No processo filho, com o dup2, redirecciona o stdout para o descritor aberto para escrita da pipe (no teu código tens dois erros nesta parte...).

No fim, executa o comando (no teu código, está a executar o comando antes de redireccionares o stdout).

No processo pai, espera pelo fim do processo filho, e lê os dados da pipe (por exemplo, com um ciclo).

Tenta fazer isto e depois coloca aqui o código.

PS: isto pode ajudar.

Link to comment
Share on other sites

Aqui fica o código funcional:

(...)

if((pid = fork())==-1){
       perror("fork: ");
       exit(2);
}
else if(pid == 0){
             close(pipes_out[0]);    	 	 	     	 	 	
             int dup = dup2(pipes_out[1], 1);
     	 	
    if (dup == -1){
             perror("dup2: ");
             exit(3);
     }
     	   	 	 	     	 	
     int exe = execvp(*args, args);
     	 	 	   	 	 	
     if(exe==-1){
          perror("execv: ");
          exit(4);
    }
}	  
close(pipes_out[1]);		

char ch;
   while(read(pipes_out[0], &ch, sizeof(char))){
write(cfd, &ch, sizeof(char));
}		

(...)

Obrigado pela ajuda Rui Carlos. Um Abraço.

Link to comment
Share on other sites

  • 11 months later...

Gostava de obter ajuda no codigo que cito abaixo :

#include <sys/types.h>

#include <unistd.h>


#include <stdlib.h>

#include <stdio.h>



int main() {



  char buffer[256];    

  pid_t procID;

  int desc[2];         /* Descritores */

  

   /* Criação do pipe */

   if ( pipe(desc) != 0 ) {



      printf("Erro na criação do pipe\n");

      return EXIT_FAILURE;

   }



   /* Criação de um processo */

   procID = fork();



  if ( procID < 0 ) {



      printf("Erro na criação do processo\n");

      return EXIT_FAILURE;

  }

  else if ( procID == 0 ) {

    

      /* Processo filho */

      close(desc[1]);



      /* Receber do pipe */

      read(desc[0], buffer, 255);

      printf("Quantidade de litros disponivel:\n%s", buffer);

  }

  else {

    

      /* Processo pai */

      close(desc[0]);

      

      /* Pedir uma mensagem ao utilizador */

      printf("Digitar quantidade litros disponiveis ? (CQD) ")

             (Max. 255 caracteres):\n");

      fgets(buffer, 255, stdin);

    

      /*Enviar para o pipe */

      write(desc[1], buffer, 255);

  }

  return EXIT_SUCCESS;

}

Este codigo esta a fazer o seguinte : (corrijam me se estiver errado)

-o processo pai escreve : Digitar quantidade litros disponiveis ? (CQD)

-o processo filho le o valor digitado

o que eu pretendo é que se o valor lido pelo processo filho for < ou = 8 apareca informacao no ecran ( RESERVA ) , senao aparece (NORMAL).

espero resposta.

obrigado

luis dinis

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.