|
rllib
1
|
00001 /*************************************************************************** 00002 rlspawn.cpp - description 00003 ------------------- 00004 begin : Tue Jan 02 2001 00005 copyright : (C) 2001 by Rainer Lehrig 00006 email : lehrig@t-online.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This library is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as * 00013 * published by the Free Software Foundation * 00014 * * 00015 ***************************************************************************/ 00016 #include "rldefine.h" 00017 #include <stdio.h> 00018 #include <stdarg.h> 00019 #include <stdlib.h> 00020 #include <string.h> 00021 #ifndef RLWIN32 00022 #include <unistd.h> 00023 #include <sys/time.h> 00024 #include <sys/types.h> 00025 #endif 00026 #include "rlspawn.h" 00027 #include "rlcutil.h" 00028 #ifdef RLUNIX 00029 #include <sys/wait.h> 00030 #include <signal.h> 00031 #endif 00032 00033 rlSpawn::rlSpawn() 00034 { 00035 toChild = fromChild = NULL; 00036 pid = 0; 00037 } 00038 00039 rlSpawn::~rlSpawn() 00040 { 00041 if(toChild != NULL) ::fclose((FILE*) toChild); 00042 if(fromChild != NULL) ::fclose((FILE*) fromChild); 00043 } 00044 00045 int rlSpawn::spawn(const char *command) 00046 { 00047 #ifdef RLWIN32 00048 return -1; 00049 #else 00050 int to_child[2],from_child[2],ret; 00051 00052 if(toChild != NULL) ::fclose((FILE*) toChild); 00053 if(fromChild != NULL) ::fclose((FILE*) fromChild); 00054 toChild = fromChild = NULL; 00055 00056 ret = ::pipe(to_child); 00057 if(ret == -1) return -1; 00058 ret = ::pipe(from_child); 00059 if(ret == -1) return -1; 00060 00061 if((pid = ::fork()) == 0) 00062 { 00063 if(to_child[0] != 0) // stdin 00064 { 00065 ::dup2(to_child[0],0); 00066 ::close(to_child[0]); 00067 } 00068 if(from_child[1] != 2) // stderr 00069 { 00070 ::dup2(from_child[1] ,2); 00071 } 00072 if(from_child[1] != 1) // stdout 00073 { 00074 ::dup2(from_child[1],1); 00075 ::close(from_child[1]); 00076 } 00077 ::close(to_child[1]); 00078 ::close(from_child[0]); 00079 ::rlexec(command); 00080 ::exit(0); 00081 } 00082 00083 ::close(to_child[0]); 00084 ::close(from_child[1]); 00085 toChild = (void*) ::fdopen(to_child[1],"w"); 00086 if(toChild == NULL) { return -1; } 00087 fromChild = (void*) ::fdopen(from_child[0],"r"); 00088 if(fromChild == NULL) { ::fclose((FILE*) toChild); return -1; } 00089 return pid; 00090 #endif 00091 } 00092 00093 const char *rlSpawn::readLine() 00094 { 00095 if(fromChild == NULL) return NULL; 00096 if(::fgets(line,sizeof(line)-1,(FILE*) fromChild) == NULL) 00097 { 00098 #ifdef RLUNIX 00099 if(pid != 0) 00100 { 00101 int status; 00102 waitpid(pid, &status, 0); 00103 kill(pid,SIGHUP); 00104 } 00105 #endif 00106 return NULL; 00107 } 00108 return line; 00109 } 00110 00111 int rlSpawn::getchar() 00112 { 00113 if(fromChild == NULL) return EOF; 00114 return ::fgetc((FILE*) fromChild); 00115 } 00116 00117 int rlSpawn::write(const char *buf, int len) 00118 { 00119 #ifdef RLWIN32 00120 return -1; 00121 #else 00122 if(toChild == NULL) return -1; 00123 return ::write(fileno((FILE*)toChild),buf,len); 00124 #endif 00125 } 00126 00127 int rlSpawn::printf(const char *format, ...) 00128 { 00129 int ret; 00130 char message[rl_PRINTF_LENGTH]; // should be big enough 00131 00132 va_list ap; 00133 va_start(ap,format); 00134 ret = rlvsnprintf(message, rl_PRINTF_LENGTH - 1, format, ap); 00135 va_end(ap); 00136 if(ret < 0) return ret; 00137 return write(message,strlen(message)); 00138 } 00139 00140 int rlSpawn::writeString(const char *buf) 00141 { 00142 if(toChild == NULL) return -1; 00143 return fprintf((FILE*)toChild,"%s",buf); 00144 } 00145 00146 void rlSpawn::printAll() 00147 { 00148 const char *cptr; 00149 while((cptr=readLine()) != NULL) ::printf("%s",cptr); 00150 } 00151 00152 int rlSpawn::select(int timeout) 00153 { 00154 #ifdef RLWIN32 00155 return -1; 00156 #else 00157 struct timeval timout; 00158 fd_set wset,rset,eset; 00159 int ret,maxfdp1,s; 00160 00161 if(fromChild == NULL) return -1; 00162 s = fileno((FILE *) fromChild); 00163 /* setup sockets to read */ 00164 maxfdp1 = s+1; 00165 FD_ZERO(&rset); 00166 FD_SET (s,&rset); 00167 FD_ZERO(&wset); 00168 FD_ZERO(&eset); 00169 timout.tv_sec = timeout / 1000; 00170 timout.tv_usec = (timeout % 1000) * 1000; 00171 00172 ret = ::select(maxfdp1,&rset,&wset,&eset,&timout); 00173 if(ret == 0) return 0; /* timeout */ 00174 return 1; 00175 #endif 00176 } 00177 00178
1.7.5.1