• [^] # Re: Impossible

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

    Bonjour, ça fonctionne avec un PTY.
    Merci pour votre aide.

    #define _XOPEN_SOURCE 600
    #include <stdlib.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <unistd.h>
    #include <stdio.h>
    #define __USE_BSD
    #include <termios.h>
    #include <sys/select.h>
    #include <sys/ioctl.h>
    #include <string.h>
    #define BUFF_SIZE 4096
    #define OPERATION_FAIL -1
    int main(int ac, char *av[]){
     int fd_master, fd_slave, pid, rc, i, nb_read;
     FILE *f = NULL;
     char *buffer;
     char* const basharg[]={"/bin/bash",NULL};
     fd_set readfd_slave;
     struct timeval timeout;
     buffer = malloc(BUFF_SIZE*sizeof(char));
     f = fopen("tmp_log","wba+");
     memset(buffer,0,BUFF_SIZE);
     /* Open PTY in read and write mode */
     fd_master = posix_openpt(O_RDWR);
     if (fd_master == OPERATION_FAIL){
     fprintf(stderr, "Error %d on posix_openpt()\n", errno);
     exit(EXIT_FAILURE);
     }
     /* Change acces rigth of slave side and set group */
     rc = grantpt(fd_master);
     if (rc == OPERATION_FAIL){
     fprintf(stderr, "Error %d on grantpt()\n", errno);
     exit(EXIT_FAILURE);
     }
     /* Unlock slave side */
     rc = unlockpt(fd_master);
     if (rc == OPERATION_FAIL){
     fprintf(stderr, "Error %d on unlockpt()\n", errno);
     exit(EXIT_FAILURE);
     }
     /* Get file descriptor of slave */
     fd_slave = open(ptsname(fd_master), O_RDWR);
     if (rc == OPERATION_FAIL){
     fprintf(stderr, "Error %d on open()\n", errno);
     exit(EXIT_FAILURE);
     }
     /* Create son process */
     if((pid = fork()) == OPERATION_FAIL){
     fprintf(stderr, "Error %d on fork()\n", errno);
     exit(EXIT_FAILURE);
     }
     /* Soon process */
     if(pid==0){
     struct termios slave_orig_term_settings; // Saved terminal settings
     struct termios new_term_settings; // Current terminal settings
     // Close the master side of the PTY
     close(fd_master);
     // Save the default parameters of the slave side of the PTY
     rc = tcgetattr(fd_slave, &slave_orig_term_settings);
     // Set raw mode on the slave side of the PTY
     new_term_settings = slave_orig_term_settings;
     cfmakeraw (&new_term_settings);
     tcsetattr (fd_slave, TCSANOW, &new_term_settings);
     // The slave side of the PTY becomes the standard input and outputs of the child process
     close(0); // Close standard input (current terminal)
     close(1); // Close standard output (current terminal)
     close(2); // Close standard error (current terminal)
     dup(fd_slave); // PTY becomes standard input (0)
     dup(fd_slave); // PTY becomes standard output (1)
     dup(fd_slave); // PTY becomes standard error (2)
     // Now the original file descriptor is useless
     close(fd_slave);
     // Make the current process a new session leader
     setsid();
     // As the child is a session leader, set the controlling terminal to be the slave side of the PTY
     // (Mandatory for programs like the shell to make them manage correctly their outputs)
     ioctl(0, TIOCSCTTY, 1);
     // Execution of the program
     {
     execve("/bin/bash",basharg ,NULL);
     }
     }
     /* Father process */
     else{
     /* Close the slave side of the PTY */
     close(fd_slave);
     /* While soon process is not terminated */
     while(waitpid (pid, NULL, WNOHANG) != pid){
     /* Set timeout for select() */
     timeout.tv_sec = 5;
     timeout.tv_usec = 0;
     /* Set on wich file descriptor listen*/
     FD_ZERO(&readfd_slave);
     FD_SET(STDIN_FILENO,&readfd_slave);
     FD_SET(fd_master,&readfd_slave);
     /* Listen file descriptor */
     rc = select(FD_SETSIZE,&readfd_slave, NULL, NULL,&timeout);
     if (rc == OPERATION_FAIL){
     fprintf(stderr, "Error %d on select()\n", errno);
     exit(EXIT_FAILURE);
     }
     /* Data on STDIN */
     if(FD_ISSET(STDIN_FILENO,&readfd_slave)){
     nb_read = read(STDIN_FILENO,buffer,BUFF_SIZE);
     if(nb_read == OPERATION_FAIL){
     fprintf(stderr, "Error %d on read standard input\n", errno);
     exit(EXIT_FAILURE);
     }
     else{
     write(fd_master,buffer,nb_read);
     for(i=0;i<nb_read;i++){
     fputc(buffer[i],f);
     }
     }
     }
     /* Data on fd_slave */
     if(FD_ISSET(fd_master,&readfd_slave)){
     nb_read = read(fd_master,buffer,BUFF_SIZE);
     if(nb_read == OPERATION_FAIL){
     fprintf(stderr, "Error %d on read master PTY\n", errno);
     exit(EXIT_FAILURE);
     }
     else{
     write(STDOUT_FILENO ,buffer,nb_read);
     for(i=0;i<nb_read;i++){
     fputc(buffer[i],f);
     }
     }
     }
     }
     close(f);
     free(buffer);
     }
     exit(EXIT_SUCCESS);
    }