Othman El houfi
Othman El houfi

Reputation: 53

Capture sdtout and stderr with pipe and dupe2 using C langage

I am writing a program in C language that acts like a shell terminal, the user enters a command and I parse the line then use "execv()" to execute the command.

Now I'm trying to print the standard output and the error output with different colors (making sure that the order doesn't change. But I'm having troubles both outputs.

Thanks you for your help

void dumsh_execute1(char **command_args, char **redirection_args) {

  int first_pipe[2];
  int second_pipe[2];
  if( pipe(first_pipe) == -1 || pipe(second_pipe) ) {
    fprintf(stderr, "Error creating pipe\n");
  }


  pid_t pid = fork();
  int status;
  switch (pid) {
    case -1:
      // error, failed to fork()

      break;
    case 0:
      // the child process
      close(first_pipe[0]);
      close(second_pipe[0]);
      dup2(first_pipe[1], 1);
      dup2(second_pipe[1], 2);
      close(first_pipe[1]);
      close(second_pipe[1]);

      if (execvp(command_args[0], command_args) < 0) {
        printf("Could not execute command..\n");
        exit(0);
      }

      break;
    default:
      // the parent process
      while (1) {

        fd_set rfds;
        int retval;

        /* Watch stdin (fd 0), stdout (fd 1) and stderr (fd 2) to see when it has I/O. */
        FD_ZERO(&rfds);
        FD_SET(first_pipe[0], &rfds);
        FD_SET(second_pipe[0], &rfds);

        struct timeval timeout;
        timeout.tv_sec = 0;
        timeout.tv_usec = 100000;

        retval = select( max(first_pipe[0], second_pipe[0] ) + 1, &rfds, 0, 0, &timeout);

        if (retval == -1) {
          perror("select()");
          break;
        } else if (retval) {

          if ( FD_ISSET(first_pipe[0], &rfds) ) {
            char msg[1024];
            int r = read(first_pipe[0], msg, sizeof(msg));
            if ( r < 1 ) {
              break;
            }
            printf("\033[%sm%s\033[%s", GREEN, msg, RESET);

          }
          if ( FD_ISSET(second_pipe[0], &rfds) ) {
            char msg[1024];
            int r = read(second_pipe[0], msg, sizeof(msg));
            if ( r < 1 ) {
              break;
            }
            printf("\033[%sm%s\033[%s", RED, msg, RESET);
          }
        }

      } //end while

      waitpid(pid, &status, 0);
      break;
  }

}

Upvotes: 0

Views: 210

Answers (0)

Related Questions