How to capture the exit_code and stderr of the command that is run in C++?

后端 未结 3 1866
梦谈多话
梦谈多话 2020-12-31 02:38

I\'m writing a c++ program that executes and outputs (in real-time) a shell script, makefile or just another program. However I would like to have my program return differen

相关标签:
3条回答
  • 2020-12-31 03:19

    The returnvalue of the child process is in the top 16 8 bits. You have to divide the returned value of pclose by 256, then you get the searched return value of the child process.

    Gotten from http://bytes.com/topic/c/answers/131694-pclose-returning-termination-status-command

    My answer would be pclose(in)/256 is exit code.

    I still don't know how to capture stderr or sdtout differently but until there's an answer for that I will accept this as my answer.

    0 讨论(0)
  • 2020-12-31 03:19

    Thanks for the reply about exit code Logan.

    I believe a round-trip to get stderr would be to redirect it to a temporary file:

    FILE* f = popen("cmd 2>/tmp/tmpfile.txt", "r");
    
    0 讨论(0)
  • 2020-12-31 03:33

    If you are interested in the error code, this is a more portable way of getting it rather than dividing by 256:

    printf("Exit code: %i\n", WEXITSTATUS(pclose(fp)));
    

    However, popen is one way, so you are either creating further workarounds by the usual redirection style in shell, or you follow this untested code to do it right:

    #include <unistd.h>
    #include <stdio.h>
    
    /* since pipes are unidirectional, we need two pipes.
       one for data to flow from parent's stdout to child's
       stdin and the other for child's stdout to flow to
       parent's stdin */
    
    #define NUM_PIPES          2
    
    #define PARENT_WRITE_PIPE  0
    #define PARENT_READ_PIPE   1
    
    int pipes[NUM_PIPES][2];
    
    /* always in a pipe[], pipe[0] is for read and 
       pipe[1] is for write */
    #define READ_FD  0
    #define WRITE_FD 1
    
    #define PARENT_READ_FD  ( pipes[PARENT_READ_PIPE][READ_FD]   )
    #define PARENT_WRITE_FD ( pipes[PARENT_WRITE_PIPE][WRITE_FD] )
    
    #define CHILD_READ_FD   ( pipes[PARENT_WRITE_PIPE][READ_FD]  )
    #define CHILD_WRITE_FD  ( pipes[PARENT_READ_PIPE][WRITE_FD]  )
    
    void
    main()
    {
        int outfd[2];
        int infd[2];
    
        // pipes for parent to write and read
        pipe(pipes[PARENT_READ_PIPE]);
        pipe(pipes[PARENT_WRITE_PIPE]);
    
        if(!fork()) {
            char *argv[]={ "/usr/bin/bc", "-q", 0};
    
            dup2(CHILD_READ_FD, STDIN_FILENO);
            dup2(CHILD_WRITE_FD, STDOUT_FILENO);
    
            /* Close fds not required by child. Also, we don't
               want the exec'ed program to know these existed */
            close(CHILD_READ_FD);
            close(CHILD_WRITE_FD);
            close(PARENT_READ_FD);
            close(PARENT_WRITE_FD);
    
            execv(argv[0], argv);
        } else {
            char buffer[100];
            int count;
    
            /* close fds not required by parent */       
            close(CHILD_READ_FD);
            close(CHILD_WRITE_FD);
    
            // Write to child’s stdin
            write(PARENT_WRITE_FD, "2^32\n", 5);
    
            // Read from child’s stdout
            count = read(PARENT_READ_FD, buffer, sizeof(buffer)-1);
            if (count >= 0) {
                buffer[count] = 0;
                printf("%s", buffer);
            } else {
                printf("IO Error\n");
            }
        }
    }
    

    The code is from here:

    http://jineshkj.wordpress.com/2006/12/22/how-to-capture-stdin-stdout-and-stderr-of-child-program/

    0 讨论(0)
提交回复
热议问题