Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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 differently when there are errors or no error.

#include "execxi.h"



using namespace std;


int execXI::run(string command)
{

    FILE *in;
    char buff[512];
    // is this the check for command execution exited with not 0?
    if(!(in = popen(command.c_str(), "r"))){
            // I want to return the exit code and error message too if any
        return 1;
    }
    // this part echoes the output of the command that's executed
    while(fgets(buff, sizeof(buff), in)!=NULL){
        cout << buff;
    }
    pclose(in);
    return 0;



}

is what I have so far.

Let's say this script ran make to build a program and it gave an error like so

on_target_webkit_version out/Release/obj/gen/webkit_version.h
Traceback (most recent call last):
  File "../build/webkit_version.py", line 107, in <module>
    sys.exit(main())
  File "../build/webkit_version.py", line 103, in main
    return EmitVersionHeader(*sys.argv[1:])
  File "../build/webkit_version.py", line 86, in EmitVersionHeader
    webkit_revision = GetWebKitRevision(webkit_dir, version_file)
  File "../build/webkit_version.py", line 60, in GetWebKitRevision
    version_info = lastchange.FetchVersionInfo(
AttributeError: 'module' object has no attribute 'FetchVersionInfo'
make: *** [out/Release/obj/gen/webkit_version.h] Error 1
  • Is it possible for me to know that this exited with error?

    • Does that exit with code else than 0 since it is an error?

    • Is that last part outputted in stderr?

Considering that make exited with code not 0, let's say 1, and it output in stderr is it not possible for me to capture these exit codes and error message in the end?

How can I capture the exit code and stderr after outputting the results of the program, and return the exit code/ stderr in the function?

like image 910
Logan Avatar asked Feb 25 '13 01:02

Logan


People also ask

What is the exit code for a successful command execution?

A successful command returns a 0, while an unsuccessful one returns a non-zero value that usually can be interpreted as an error code. Well-behaved UNIX commands, programs, and utilities return a 0 exit code upon successful completion, though there are some exceptions.

What is program exit code?

An exit code, or sometimes known as a return code, is the code returned to a parent process by an executable. On POSIX systems the standard exit code is 0 for success and any number from 1 to 255 for anything else. Exit codes can be interpreted by machine scripts to adapt in the event of successes of failures.

What is the command to get the exit status of the most recent command process?

Exit status 0 It tells you that your latest command or script executed successfully.

What is exit code in shell script?

Exit Codes. Exit codes are a number between 0 and 255, which is returned by any Unix command when it returns control to its parent process. Other numbers can be used, but these are treated modulo 256, so exit -10 is equivalent to exit 246 , and exit 257 is equivalent to exit 1 .


2 Answers

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/

like image 139
lpapp Avatar answered Sep 19 '22 13:09

lpapp


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.

like image 35
Logan Avatar answered Sep 17 '22 13:09

Logan