• [^] # Re: Impossible

    Posté par . En réponse au message Communication entre processus avec pipe() et dup2().. Évalué à 1. Dernière modification le 01 mars 2020 à 11:09.

    Alors quand je fait sans pipe() et dup2() ça marche avec le prompt :

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #define NB_PIPE 2
    int main(int argc, char **argv){
     int pid;
     /* Création du processus fils */
     if((pid = fork()) == -1){
     perror("fork failed\n");
     return 2;
     }
     /* Processus fils */
     if(pid == 0){
     execve("/bin/bash",NULL,NULL);
     }
     /* Processus père */
     else{
     wait(0);
     }
     return 0;
    }

    Quand je fait :

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <sys/select.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <errno.h>
    #define BUFF_SIZE 4096 /* the capacity of a pipe is 4096 bytes */
    #define NB_PIPE 2
    int main(int argc, char **argv){
     char *buff; /* Déclaration des variables */
     int pid,i,fd_stdin,fd_stdout,ret,nb_read;
     int fd[NB_PIPE][2];
     FILE *f = NULL;
     fd_set readfds;
     struct timeval timeout;
     for(i=0;i<NB_PIPE;i++){ /* Création des pipes */
     if(pipe(fd[i]) == -1){
     perror("pipe failed\n");
     return 1;
     }
     }
     fd_stdin = 0; /* Initialisation des variables */
     fd_stdout = 1;
     f = fopen("tmp_log","wba+");
     if((pid = fork()) == -1){ /* Création du processus fils */
     perror("fork failed\n");
     return 2;
     }
     if(pid == 0){ /* Processus fils */
     close(fd[0][1]); /* Ferme l'entrée de pipe 1 */
     close(fd[1][0]); /* Ferme la sortie de pipe 2 */
     dup2(fd[0][0],0); /* Duplique la sortie de pipe 1 sur STDIN */
     dup2(fd[1][1],1); /* Duplique l'entrée de pipe 2 sur STDOUT */
     argv[0] = "/bin/bash";
     argv[1] = "-li";
     argv[2] = NULL;
     execve("/bin/bash",argv,NULL); /* Lance l'execution d'un bash */
     }
     else{ /* Processus père */
     close(fd[0][0]); /* Ferme la sortie de pipe 1 */
     close(fd[1][1]); /* Ferme l'entrée de pipe 2 */
     while(1){
     timeout.tv_sec = 5; /* Initialisation timeout et des file descriptor a écouter */
     timeout.tv_usec = 0;
     FD_ZERO(&readfds);
     FD_SET(fd_stdin,&readfds);
     FD_SET(fd[1][0],&readfds);
     select(FD_SETSIZE,&readfds,NULL,NULL,&timeout); /* On ecoute les descripteurs de fichier contenu dans readfds */
     /* Activité detectée */
     if(FD_ISSET(fd_stdin,&readfds)){ /* Sur STDIN */
     printf("toto\n");
     nb_read = read(fd_stdin,buff,BUFF_SIZE); /* Lecture sur STDIN* */
     printf("toto\n");
     write(fd[0][1],buff,nb_read); /* Ecriture sur l'entrée de pipe 1 */
     fseek(f, 0, SEEK_END); /* Se déplace a la fin du fichier */
     for(i=0;i<nb_read;i++){
     fputc(buff[i],f); /* Ecrit un caractère a la fin du fichier */
     }
     }
     if(FD_ISSET(fd[1][0],&readfds)){ /* Sur la sortie du pipe 2 */
     nb_read = read(fd[1][0],buff,BUFF_SIZE); /* Lecture sur la sortie de pipe 2 */
     write(fd_stdout,buff,nb_read); /* Ecriture sur STDOUT*/
     fseek(f, 0, SEEK_END); /* Se déplace a la fin du fichier */
     for(i=0;i<nb_read;i++){
     fputc(buff[i],f); /* Ecrit un caractère a la fin du fichier */
     }
     }
     }
     }
     return 0;
    }

    L'exécution donne :

    toto@ThinkPad:~/lab$ ./main 
    toto@ThinkPad:/home/toto/lab$ ls
    toto
    [1]+ Arrêté ./main
    toto@ThinkPad:~/lab$ ls
    main main.c main.o Makefile tmp_log toto toto.c toto.o
    toto@ThinkPad:~/lab$ 
    

    Le prompt s'affiche mais quand j'exécute "ls" le bash se ferme
    et exécute "ls" dans le bash qui appelle main.

    L'erreur semble venir du read de STDIN dans le père.