• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

NameException

comunicação entre processos (pipes)

6 mensagens neste tópico

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Depois de fazeres o fork, precisas de distinguir entre o processo pai e o processo filho. No processo filho executas o comando e envias o output para a pipe (ou seja, redireccionas o stdout para a pipe). No processo pai, lês o conteúdo da pipe.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É exectamente isso que quero fazer... Mas nao sei como se faz esse redirecionamento... como faço, para que o output seja "escrito" na pipe?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora