00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "bidirpipe.h"
00010 #include <signal.h>
00011 #include <sys/wait.h>
00012 #include <errno.h>
00013 #include <fcntl.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <unistd.h>
00017
00018
00019 #define SHELL "/bin/sh"
00020
00021 bidir_pipe::bidir_pipe() {
00022 read=write=0;
00023 pid=0;
00024 }
00025
00026 bool bidir_pipe::open(const char *cmdstring, const char *type)
00027 {
00028 printf("Executing: %s\n", cmdstring);
00029 int pfd[2];
00030 int pfd2[2];
00031
00032 if (pipe(pfd) < 0)
00033 return(false);
00034
00035 if (*type!='r' && *type != 'w') {
00036 if (pipe(pfd2) < 0)
00037 return(false);
00038 }
00039
00040 if ( (pid = fork()) < 0)
00041 return(false);
00042
00043 else if (pid == 0) {
00044 if (*type == 'r') {
00045 ::close(pfd[0]);
00046 if (pfd[1] != STDOUT_FILENO) {
00047 dup2(pfd[1], STDOUT_FILENO);
00048 ::close(pfd[1]);
00049 }
00050 } else if (*type == 'r') {
00051 ::close(pfd[1]);
00052 if (pfd[0] != STDIN_FILENO) {
00053 dup2(pfd[0], STDIN_FILENO);
00054 ::close(pfd[0]);
00055 }
00056 } else {
00057 if (pfd[1] != STDOUT_FILENO) {
00058 dup2(pfd[1], STDOUT_FILENO);
00059 ::close(pfd[1]);
00060 }
00061 if (pfd2[0] != STDIN_FILENO) {
00062 dup2(pfd2[0], STDIN_FILENO);
00063 ::close(pfd2[0]);
00064 }
00065 }
00066
00067 setpgid(0,0);
00068 execl(SHELL, "sh", "-c", cmdstring, (char *) 0);
00069 _exit(127);
00070 }
00071
00072
00073 if (*type == 'r') {
00074 ::close(pfd[1]);
00075 write=0;
00076 if ( (read = fdopen(pfd[0], type)) == NULL)
00077 return(false);
00078 } else if (*type == 'w') {
00079 ::close(pfd[0]);
00080 read=0;
00081 if ( (write = fdopen(pfd[1], type)) == NULL)
00082 return(false);
00083 } else {
00084 ::close(pfd[1]);
00085 ::close(pfd2[0]);
00086 if ( (read = fdopen(pfd[0], "r")) == NULL)
00087 return(false);
00088 if ( (write = fdopen(pfd2[1], "w")) == NULL) {
00089 fclose(read);
00090 read=0;
00091 return(false);
00092 }
00093 }
00094 return(true);
00095 }
00096
00097 int bidir_pipe::close(bool k)
00098 {
00099 if (pid==0) return -1;
00100
00101 if (read) fclose(read);
00102 read=0;
00103 if (write) fclose(write);
00104 write=0;
00105
00106 if (k) {
00107 if (killpg(pid, SIGTERM)<0) {
00108 char str[64];
00109 sprintf(str,"killpg %d",pid);
00110 perror(str);
00111 }
00112 }
00113 int stat;
00114 while (waitpid(pid, &stat, 0) < 0)
00115 if (errno != EINTR)
00116 return(-1);
00117 pid=0;
00118
00119 return(stat);
00120 }
00121
00122
00123
00124