#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
pid_t exec_redirect(char * prog, char * args[], int* infd, int* outfd, int* errfd)
{
// Fork new process
pid_t pchild = fork();
if (pchild == 0) {
// Child process
// Redirect standard input
if (infd[0] >= 0) {
close(STDIN_FILENO);
dup2(infd[0], STDIN_FILENO);
}
// Redirect standard output
if (outfd[1] >= 0) {
close(STDOUT_FILENO);
dup2(outfd[1], STDOUT_FILENO);
}
// Redirect standard error
if (errfd[1] >= 0) {
close(STDERR_FILENO);
dup2(errfd[1], STDERR_FILENO);
}
// Close unneeded ends of pipes
if (infd[1] >= 0) close(infd[1]);
if (outfd[0] >= 0) close (outfd[0]);
if (errfd[0] >= 0) close (outfd[0]);
// Execute the command
execv(prog, args);
return 0;
} else {
// Parent process
// Close unneeded ends of pipes
if (infd[0] >= 0) close(infd[0]);
if (outfd[1] >= 0) close (outfd[1]);
if (errfd[1] >= 0) close (errfd[1]);
return pchild;
}
}
void readFromPipe(int pfd) {
char buf;
bool newline = true;
while (read(pfd, &buf, 1) > 0) {
if (newline) {
std::cout << “[Child] “;
newline = false;
}
std::cout << buf;
if (buf == ‘\n’) {
newline = true;
}
}
}
int main(int argc, char* argv[]) {
if (argc < 1) {
std::cerr << “Please supply an argument\n”;
exit(1);
}
char * childproc = argv[1];
char ** childprocargs = new char*[argc];
std::cout << “Executing “;
for (int i = 1; i < argc; ++i) {
std::cout << argv[i] << ” “;
childprocargs[i-1] = strdup(argv[i]);
}
childprocargs[argc-1] = 0;
std::cout << “\n”;
// Creating pipes for communication
int pfddown[2]; // down: Parent writes, child reads
int pfdup[2]; // up: Child writes, parent reads
int pfderr[2]; // err: Child writes, parent reads
if (pipe(pfdup) != 0 || pipe(pfddown) != 0 || pipe(pfderr) != 0) {
std::cerr << “Unable to create pipes. Aborting\n”;
exit(1);
}
pid_t child = exec_redirect(childproc, childprocargs, pfddown, pfdup, pfderr);
std::cout << “Forked child, pid is ” << child << “\n”;
std::cout << “Sending Hello\\n\n”;
write(pfddown[1],”Hello\n”,6);
std::cout << “Sending World!\\n\n”;
write(pfddown[1],”World!\n”,7);
close(pfddown[1]);
readFromPipe(pfdup[0]);
close(pfdup[0]);
wait(0);
// cleaning the nasty arg array
for (int i = 0; i < argc-1; ++i) {
free(childprocargs[i]);
}
delete [] childprocargs;
}
Output:
treuss@foo:~/src$ ./test /bin/cat
Executing /bin/cat
Forked child, pid is 9514
Sending Hello\n
Sending World!\n
[Child] Hello
[Child] World!
treuss@foo:~/src$ ./test /usr/bin/tac
Executing /usr/bin/tac
Forked child, pid is 9526
Sending Hello\n
Sending World!\n
[Child] World!
[Child] Hello
treuss@foo:~/src$ ./test /bin/sed -e’s/o/x/g’
Executing /bin/sed -es/o/x/g
Forked child, pid is 9532
Sending Hello\n
Sending World!\n
[Child] Hellx
[Child] Wxrld!
}
From: http://codeguru.earthweb.com/forum/showthread.php?p=1788381
