Skip to content

Instantly share code, notes, and snippets.

@airekans
Created October 24, 2012 21:15
Show Gist options
  • Save airekans/3948937 to your computer and use it in GitHub Desktop.
Save airekans/3948937 to your computer and use it in GitHub Desktop.
Popen in C++
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;
int main(int argc, char *argv[])
{
if (argc < 2)
{
cerr << "please input command to execute" << endl;
exit(1);
}
int stdinPipe[2] = {0};
int stdoutPipe[2] = {0};
int stderrPipe[2] = {0};
const int READ_FD = 0, WRITE_FD = 1;
if (pipe(stdinPipe) == -1)
{
cerr << "failed to create pipe" << endl;
exit(1);
}
if (pipe(stdoutPipe) == -1)
{
cerr << "failed to create pipe" << endl;
exit(1);
}
if (pipe(stderrPipe) == -1)
{
cerr << "failed to create pipe" << endl;
exit(1);
}
pid_t pid = fork();
if (pid == -1)
{
cerr << "failed to fork" << endl;
exit(1);
}
else if (pid == 0) // child
{
// close useless fds
close(stdinPipe[WRITE_FD]);
close(stdoutPipe[READ_FD]);
close(stderrPipe[READ_FD]);
if (dup2(stdinPipe[READ_FD], STDIN_FILENO) == -1 ||
dup2(stdoutPipe[WRITE_FD], STDOUT_FILENO) == -1 ||
dup2(stderrPipe[WRITE_FD], STDERR_FILENO) == -1)
{
cerr << "failed to dup2 fd" << endl;
exit(1);
}
else
{
close(stdinPipe[READ_FD]);
close(stdoutPipe[WRITE_FD]);
close(stderrPipe[WRITE_FD]);
}
execvp(argv[1], argv + 1);
// should not reach here
cerr << "failed to exec" << endl;
exit(1);
}
else // parent
{
// close useless fds
close(stdinPipe[READ_FD]);
close(stdoutPipe[WRITE_FD]);
close(stderrPipe[WRITE_FD]);
char c;
while (read(stdoutPipe[READ_FD], &c, 1) == 1)
{
cout << c;
}
cout << "child exit" << endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment