00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <string>
00038 #ifndef _WIN32
00039 # include <sys/types.h>
00040 # include <sys/stat.h>
00041 # include <sys/poll.h>
00042 # include <stdio.h>
00043 #else
00044 # include <windows.h>
00045 #endif
00046 #include <errno.h>
00047
00048 using namespace std;
00049
00050 #include "exec.h"
00051
00052 #include "params.h"
00053
00054
00055 #ifndef _MSC_VER
00056 #pragma package(smart_init)
00057 #endif
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 int exec_read_output(s_exec_handle* h, char*& lpBuffer, int& buffer_size)
00071 {
00072 if(!h->out_buffer) {
00073 lpBuffer=new char[32];
00074 return buffer_size=0;
00075 }
00076 lpBuffer=h->out_buffer;
00077 buffer_size=h->out_buffer_size;
00078 h->out_buffer=NULL;
00079 h->out_buffer_size=0;
00080 return buffer_size;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 s_exec_handle* exec_async_exec(const char* cmd, const char* params, const char* dir)
00094 {
00095 #ifdef _WIN32
00096 _STARTUPINFOA SI;
00097 memset(&SI,0,sizeof(SI));
00098 GetStartupInfoA(&SI);
00099 SI.dwFlags=STARTF_USESHOWWINDOW | STARTF_FORCEOFFFEEDBACK | STARTF_USESTDHANDLES;
00100 SI.wShowWindow=SW_HIDE;
00101 string ln=cmd;
00102 if(ln.length()>0 && ln[0]!='\"' && ln.find(0x20,0)!=string::npos)
00103 ln=(string)"\""+ln+"\"";
00104 ln+=" ";
00105 ln+=params;
00106
00107 s_exec_handle* h=new s_exec_handle;
00108 memset(&(h->PI),0,sizeof(h->PI));
00109
00110 {
00111 HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
00112 HANDLE hInputWriteTmp,hInputRead,hInputWrite;
00113 HANDLE hErrorWrite;
00114 SECURITY_ATTRIBUTES sa;
00115 memset(&sa,0,sizeof(sa));
00116 sa.nLength=sizeof(sa);
00117 sa.lpSecurityDescriptor=NULL;
00118 sa.bInheritHandle=TRUE;
00119 CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0);
00120 DuplicateHandle(GetCurrentProcess(),hOutputWrite,GetCurrentProcess(),&hErrorWrite,0,TRUE,DUPLICATE_SAME_ACCESS);
00121 CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0);
00122 DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,GetCurrentProcess(),&hOutputRead,0,FALSE,DUPLICATE_SAME_ACCESS);
00123 DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,GetCurrentProcess(),&hInputWrite,0,FALSE,DUPLICATE_SAME_ACCESS);
00124 CloseHandle(hOutputReadTmp);
00125 CloseHandle(hInputWriteTmp);
00126
00127 h->hOutputWrite=hOutputWrite;
00128 h->hOutputRead=hOutputRead;
00129
00130 h->hInputRead=hInputRead;
00131 h->hInputWrite=hInputWrite;
00132
00133 h->hErrorWrite=hErrorWrite;
00134
00135 SI.hStdOutput=h->hOutputWrite;
00136 SI.hStdInput=h->hInputRead;
00137 SI.hStdError=h->hErrorWrite;
00138 }
00139 char fully_qualified_path[_MAX_PATH+128+1];
00140 LPTSTR* dummy=NULL;
00141 if(GetFullPathName(dir,sizeof(fully_qualified_path)-1,fully_qualified_path,dummy))
00142 h->error=!CreateProcessA(NULL,(LPSTR)ln.c_str(),NULL,NULL,true,NORMAL_PRIORITY_CLASS,NULL,(LPSTR)fully_qualified_path,&SI,&(h->PI));
00143 else
00144 h->error=!CreateProcessA(NULL,(LPSTR)ln.c_str(),NULL,NULL,true,NORMAL_PRIORITY_CLASS,NULL,NULL,&SI,&(h->PI));
00145
00146 h->os_hnd=h->PI.hProcess;
00147 return h;
00148 #else
00149 int size=0;
00150 if(cmd)
00151 size+=strlen(cmd);
00152 else {
00153 s_exec_handle* h=new s_exec_handle;
00154 h->os_hnd=NULL;
00155 h->error=true;
00156 h->out_buffer=NULL;
00157 h->out_buffer_size=0;
00158 return h;
00159 }
00160 if(params)
00161 size+=strlen(params);
00162 if(dir)
00163 size+=strlen(dir);
00164 char* ln=new char[size+1024];
00165 ln[0]=0;
00166 if(dir) {
00167 strcpy(ln,"cd ");
00168 if(dir[0]!='\"')
00169 strcat(ln,"\"");
00170 strcat(ln,dir);
00171 if(dir[0]!='\"')
00172 strcat(ln,"\"");
00173 strcat(ln,"; ");
00174 }
00175 strcat(ln,cmd);
00176 if(params) {
00177 strcat(ln," ");
00178 strcat(ln,params);
00179 }
00180 FILE* hnd=popen(ln,"r");
00181 delete[] ln;
00182 s_exec_handle* h=new s_exec_handle;
00183 h->os_hnd=hnd;
00184 h->error=!hnd;
00185 h->out_buffer=NULL;
00186 h->out_buffer_size=0;
00187 return h;
00188 #endif
00189 }
00190
00191
00192
00193
00194
00195
00196 bool exec_process_active(s_exec_handle* h)
00197 {
00198 if(h==NULL)
00199 return false;
00200 if(h->os_hnd==NULL)
00201 return false;
00202 #ifdef _WIN32
00203 DWORD dwExitCode;
00204 GetExitCodeProcess(h->os_hnd,&dwExitCode);
00205 if(dwExitCode!=STILL_ACTIVE) {
00206 HANDLE hPipeRead=h->hOutputRead;
00207
00208 DWORD nBytesRead;
00209
00210 int buffer_size=GetFileSize(hPipeRead,NULL);
00211 if(buffer_size>0) {
00212 h->out_buffer=(char*)malloc(buffer_size);
00213 h->out_buffer_size=buffer_size;
00214 ReadFile(hPipeRead,h->out_buffer,h->out_buffer_size,&nBytesRead,NULL);
00215 } else {
00216
00217 h->out_buffer=(char*)malloc(1);
00218 h->out_buffer_size=0;
00219 }
00220 exec_process_end(h);
00221 h->os_hnd=NULL;
00222 h->exit_code=dwExitCode;
00223 }
00224 return dwExitCode==STILL_ACTIVE;
00225 #else
00226 pollfd to_poll;
00227 to_poll.fd=fileno(h->os_hnd);
00228 to_poll.events=POLLIN|POLLPRI;
00229
00230
00231 if(poll(&to_poll,1,1)<0) {
00232 h->out_buffer=(char*)malloc(1);
00233 h->out_buffer_size=0;
00234 exec_process_end(h);
00235 h->os_hnd=NULL;
00236 h->exit_code=-1;
00237 return false;
00238 }
00239 if((to_poll.revents&POLLIN)==POLLIN || (to_poll.revents&POLLPRI)==POLLPRI) {
00240 int size=128;
00241 char* tmp=new char[size+1];
00242 again:
00243 size=fread(tmp,1,size,h->os_hnd);
00244 if(size>0) {
00245 tmp[size]=0;
00246 if(!h->out_buffer) {
00247 h->out_buffer=(char*)malloc(size);
00248 h->out_buffer_size=size;
00249 memcpy(h->out_buffer,tmp,size);
00250 } else {
00251 int pos=h->out_buffer_size;
00252 h->out_buffer_size+=size;
00253 h->out_buffer=(char*)realloc(h->out_buffer,h->out_buffer_size);
00254 memcpy(&(h->out_buffer[pos]),tmp,size);
00255 }
00256 size=128;
00257 goto again;
00258 }
00259 delete[] tmp;
00260 return true;
00261 }
00262 if((to_poll.revents&POLLHUP)==POLLHUP) {
00263 h->exit_code=pclose(h->os_hnd);
00264 h->os_hnd=NULL;
00265 int pos=h->out_buffer_size;
00266 h->out_buffer_size+=1;
00267 h->out_buffer=(char*)realloc(h->out_buffer,h->out_buffer_size);
00268 h->out_buffer[pos]=0;
00269 return false;
00270 }
00271 return true;
00272 #endif
00273 return true;
00274 }
00275
00276
00277
00278
00279
00280
00281 DWORD exec_get_exit_code(s_exec_handle* h)
00282 {
00283 if(!h)
00284 return (DWORD)-1;
00285 if(h->os_hnd==NULL)
00286 return h->exit_code;
00287 if(exec_process_active(h))
00288 return (DWORD)-2;
00289 #ifndef _WIN32
00290 h->exit_code=pclose(h->os_hnd);
00291 h->os_hnd=NULL;
00292 return h->exit_code;
00293 #else
00294 DWORD dwExitCode;
00295 GetExitCodeProcess(h->os_hnd,&dwExitCode);
00296 if(dwExitCode==STILL_ACTIVE)
00297 return (DWORD)-2;
00298 return dwExitCode;
00299 #endif
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 int exec_process_end(s_exec_handle* h)
00311 {
00312 #ifdef _WIN32
00313 if(!h->os_hnd)
00314 return 0;
00315
00316 DWORD dwExitCode;
00317 GetExitCodeProcess(h->os_hnd,&dwExitCode);
00318
00319 if(h->hOutputWrite)
00320 CloseHandle(h->hOutputWrite);
00321 h->hOutputWrite=NULL;
00322
00323 if(h->hOutputRead)
00324 CloseHandle(h->hOutputRead);
00325 h->hOutputRead=NULL;
00326
00327 if(h->hInputWrite)
00328 CloseHandle(h->hInputWrite);
00329 h->hInputWrite=NULL;
00330
00331 if(h->hInputRead)
00332 CloseHandle(h->hInputRead);
00333 h->hInputRead=NULL;
00334
00335 if(h->hErrorWrite)
00336 CloseHandle(h->hErrorWrite);
00337 h->hErrorWrite=NULL;
00338
00339 CloseHandle(h->PI.hProcess);
00340 CloseHandle(h->PI.hThread);
00341 TerminateProcess(h->os_hnd,0);
00342
00343 return dwExitCode;
00344 #else
00345 if(!h)
00346 return -1;
00347 if(h->os_hnd)
00348 h->exit_code=pclose(h->os_hnd);
00349 h->os_hnd=NULL;
00350 if(h->out_buffer) {
00351 free(h->out_buffer);
00352 h->out_buffer=NULL;
00353 h->out_buffer_size=0;
00354 }
00355 return h->exit_code;
00356 #endif
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 void exec_terminate_process(s_exec_handle* h, int error_code)
00368 {
00369 #ifdef _WIN32
00370 TerminateProcess(h->os_hnd,error_code);
00371 CloseHandle(h->PI.hProcess);
00372 CloseHandle(h->PI.hThread);
00373 h->os_hnd=NULL;
00374 if(h->out_buffer) {
00375 free(h->out_buffer);
00376 h->out_buffer=NULL;
00377 h->out_buffer_size=0;
00378 }
00379 #else
00380 if(h->os_hnd) {
00381 h->exit_code=pclose(h->os_hnd);
00382 h->os_hnd=NULL;
00383 if(h->out_buffer) {
00384 free(h->out_buffer);
00385 h->out_buffer=NULL;
00386 h->out_buffer_size=0;
00387 }
00388 }
00389 #endif
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 s_exec_handle* exec_async_exec2(const char* cmd, const char* params, const char* dir)
00404 {
00405 #ifdef _WIN32
00406 _STARTUPINFOA SI;
00407 memset(&SI,0,sizeof(SI));
00408 GetStartupInfoA(&SI);
00409 SI.dwFlags=STARTF_USESHOWWINDOW | STARTF_FORCEOFFFEEDBACK | STARTF_USESTDHANDLES;
00410 SI.wShowWindow=SW_HIDE;
00411 string ln=cmd;
00412 if(ln.length()>0 && ln[0]!='\"' && ln.find(0x20,0)!=string::npos)
00413 ln=(string)"\""+ln+"\"";
00414 if(params) {
00415 ln+=" ";
00416 ln+=params;
00417 }
00418
00419 s_exec_handle* h=new s_exec_handle;
00420 memset(&(h->PI),0,sizeof(h->PI));
00421
00422 {
00423 h->hOutputWrite=NULL;
00424 h->hOutputRead=NULL;
00425
00426 h->hInputRead=NULL;
00427 h->hInputWrite=NULL;
00428
00429 h->hErrorWrite=NULL;
00430 }
00431 char fully_qualified_path[_MAX_PATH+128+1];
00432 LPTSTR* dummy=NULL;
00433 if(GetFullPathName(dir,sizeof(fully_qualified_path)-1,fully_qualified_path,dummy))
00434 h->error=!CreateProcessA(NULL,(LPSTR)ln.c_str(),NULL,NULL,false,NORMAL_PRIORITY_CLASS,NULL,(LPSTR)fully_qualified_path,&SI,&(h->PI));
00435 else
00436 h->error=!CreateProcessA(NULL,(LPSTR)ln.c_str(),NULL,NULL,false,NORMAL_PRIORITY_CLASS,NULL,NULL,&SI,&(h->PI));
00437
00438 h->os_hnd=h->PI.hProcess;
00439 return h;
00440 #else
00441 int size=0;
00442 if(cmd)
00443 size+=strlen(cmd);
00444 else {
00445 s_exec_handle* h=new s_exec_handle;
00446 h->os_hnd=NULL;
00447 h->error=true;
00448 h->out_buffer=NULL;
00449 h->out_buffer_size=0;
00450 return h;
00451 }
00452 if(params)
00453 size+=strlen(params);
00454 if(dir)
00455 size+=strlen(dir);
00456 char* ln=new char[size+1024];
00457 ln[0]=0;
00458 if(dir) {
00459 strcpy(ln,"cd ");
00460 if(dir[0]!='\"')
00461 strcat(ln,"\"");
00462 strcat(ln,dir);
00463 if(dir[0]!='\"')
00464 strcat(ln,"\"");
00465 strcat(ln,"; ");
00466 }
00467 strcat(ln,cmd);
00468 if(params) {
00469 strcat(ln," ");
00470 strcat(ln,params);
00471 }
00472 FILE* hnd=popen(ln,"r");
00473 delete[] ln;
00474 s_exec_handle* h=new s_exec_handle;
00475 h->os_hnd=hnd;
00476 h->error=!hnd;
00477 h->out_buffer=NULL;
00478 h->out_buffer_size=0;
00479 return h;
00480 #endif
00481 }
00482