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
The returnvalue of the child process is in the top
168 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.
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");
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/