1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
// http://stackoverflow.com/questions/26852198/getting-the-pid-from-popen
#include "popen2.hh"
#include <sys/wait.h>
#include <stdexcept>
#define READ 0
#define WRITE 1
FILE * popen2(std::string command, std::string type, int & pid)
{
pid_t child_pid;
int fd[2];
if(pipe(fd)==-1)
throw std::logic_error("popen2 failed constructing pipe");
if((child_pid = fork()) == -1) {
perror("fork");
exit(1);
}
/* child process */
if (child_pid == 0) {
if (type == "r") {
close(fd[READ]); //Close the READ end of the pipe since the child's fd is write-only
dup2(fd[WRITE], 1); //Redirect stdout to pipe
}
else {
close(fd[WRITE]); //Close the WRITE end of the pipe since the child's fd is read-only
dup2(fd[READ], 0); //Redirect stdin to pipe
}
execl("/bin/sh", "/bin/sh", "-c", command.c_str(), NULL);
exit(0);
}
else {
if (type == "r") {
close(fd[WRITE]); //Close the WRITE end of the pipe since parent's fd is read-only
}
else {
close(fd[READ]); //Close the READ end of the pipe since parent's fd is write-only
}
}
pid = child_pid;
if (type == "r") {
return fdopen(fd[READ], "r");
}
return fdopen(fd[WRITE], "w");
}
int pclose2(FILE * fp, pid_t pid)
{
int stat;
fclose(fp);
while (waitpid(pid, &stat, 0) == -1) {
if (errno != EINTR) {
stat = -1;
break;
}
}
return stat;
}
|