• [^] # Re: Impossible

    Posté par . En réponse au message Communication entre processus avec pipe() et dup2().. Évalué à 1.

    Merci pour ta réponse, j'ai corrigé.
    Voila ou j'en suis :

    #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>
    #define BUFF_SIZE 256
    #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;
     buff = malloc(BUFF_SIZE*sizeof(char));
     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 */
     execve("/bin/bash",NULL,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é */
     if(FD_ISSET(fd_stdin,&readfds)){ /* Sur STDIN */
     nb_read = read(fd_stdin,buff,BUFF_SIZE); /* Lecture sur STDIN* */
     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;
    }

    Exemple :

    toto@ThinkPad:~/lab$ ./main 
    ls
    Makefile
    main
    main.c
    main.o
    tmp_log
    toto
    toto.c
    toto.o
    env
    PWD=/home/toto/lab
    SHLVL=1
    _=/usr/bin/env
    ^C
    

    Le programme fonctionne quasiment.
    Le soucis maintenant c'est l'affichage, et toujours pas de prompt.
    J'ai essayé les options de bash sans succès.
    Je pense que l'erreur vient d'ailleurs car quand j'exécute ce programme :

    #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;
    }

    J'ai ça :

    toto@ThinkPad:~/lab$ ./toto 
    To run a command as administrator (user "root"), use "sudo <command>".
    See "man sudo_root" for details.
    toto@ThinkPad:/home/toto/lab$ ls
    Makefile main main.c main.o tmp_log toto toto.c toto.o
    toto@ThinkPad:/home/toto/lab$ env
    LS_COLORS=
    M2_HOME=/opt/maven
    LESSCLOSE=/usr/bin/lesspipe %s %s
    PWD=/home/toto/lab
    SHLVL=1
    PATH=/opt/maven/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/var/lib/snapd/snap/bin
    LESSOPEN=| /usr/bin/lesspipe %s
    _=/usr/bin/env
    

    Aussi je ne comprend pas pourquoi le résultat de la commande env est différent.