00001
00002
00003
00004
00005
00006
00007
00008 #include "CmdPipe.h"
00009
00010
00011 extern "C" {
00012 #include <string.h>
00013 #include <unistd.h>
00014 #include <sys/wait.h>
00015 #include <sys/types.h>
00016 #include <string.h>
00017 #include <signal.h>
00018
00019 #if defined(__alpha__)
00020 #include <cma.h>
00021 #endif
00022
00023 #if defined(AIX)
00024 #include <sys/select.h>
00025 #else
00026 #include <unistd.h>
00027 #endif
00028
00029 #if defined(__linux__)
00030 #include <sys/time.h>
00031 #endif
00032
00033 #include <time.h>
00034 #include <errno.h>
00035 }
00036
00037 static void kaputt(const char * c1, const char * c2) {
00038 fprintf(stderr,"error: %s%s\n",c1,c2);
00039 _exit(20);
00040 }
00041
00042 Pipe::Pipe(void) : fail(true) {
00043
00044 fds[0] = 0;
00045 fds[1] = 1;
00046
00047 if (-1 == pipe(fds)) {
00048 kaputt("Pipe: ","unable to create pipe");
00049 return;
00050 }
00051
00052 fail = false;
00053 return;
00054 }
00055
00056 Pipe::~Pipe(void) {
00057
00058 if (! fail) {
00059 close(fds[0]);
00060 close(fds[1]);
00061 }
00062 return;
00063 }
00064
00065 unsigned long Pipe::ewrite(const void * buf, unsigned long len) {
00066
00067 unsigned long wsum = 0;
00068 while (len) {
00069 long wlen;
00070
00071 wlen = ::write(fds[1], buf, (long) len);
00072 if (wlen <= 0) {
00073 kaputt("Pipe::ewrite ","write-error");
00074 }
00075
00076 len -= wlen;
00077 buf = (void*) ((char*) buf + wlen);
00078 wsum += wlen;
00079 }
00080 return wsum;
00081 }
00082
00083 unsigned long Pipe::eread(void * buf, unsigned long len) {
00084
00085 unsigned long rsum = 0;
00086 while (len) {
00087 long rlen;
00088
00089 rlen = ::read(fds[0], buf, (long) len);
00090
00091 if (rlen <= 0) {
00092 kaputt("Pipe::eread ","read-error");
00093 }
00094
00095 len -= rlen;
00096 buf = (void*) ((char*) buf + rlen);
00097 rsum += rlen;
00098 }
00099 return rsum;
00100 }
00101
00102 int Pipe::probe(void) const {
00103
00104 fd_set set;
00105 FD_ZERO(&set);
00106 FD_SET(fds[0], &set);
00107
00108 struct timeval tv;
00109 tv.tv_sec = 0;
00110 tv.tv_usec = 0;
00111
00112 int res;
00113
00114
00115 res = select(FD_SETSIZE, &set, (fd_set *)0, (fd_set *)0, &tv);
00116
00117 if (res > 0) return -1;
00118 return 0;
00119
00120 }
00121
00122 CmdPipe::CmdPipe(const char * command, const char * arg, int nicediff) : childpid(0), fail(true) {
00123
00124 if (tocmd.fail || fromcmd.fail) {
00125 kaputt("CmdPipe: ","unable to initialize pipes");
00126 return;
00127 }
00128
00129 childpid = fork();
00130
00131 if (childpid == -1) {
00132 childpid = 0;
00133 kaputt("CmdPipe: ","unable to fork process");
00134 return;
00135 }
00136
00137 if (childpid == 0) {
00138
00139 if (nicediff) {
00140 if (-1 == nice(nicediff)) {
00141 fprintf(stderr,"CmdPipe: unable to change nice-level (non-fatal)");
00142 }
00143 }
00144
00145 dup2(tocmd.get_read_fd(), STDIN_FILENO);
00146
00147 dup2(fromcmd.get_write_fd(), STDOUT_FILENO);
00148 execlp(command, "Frodo_GUI", arg, (char *)0);
00149 kaputt("CmdPipe: unable to execute child process ",command);
00150 _exit(0);
00151 }
00152
00153 fail = false;
00154 return;
00155 }
00156
00157 CmdPipe::~CmdPipe(void) {
00158
00159 if (childpid) {
00160 int status;
00161 waitpid(childpid, &status, 0);
00162
00163 if (status != 0) {
00164 fprintf(stderr,"~CmdPipe child process returned error\n");
00165 }
00166 }
00167 }