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 #include "OSCommand.h"
00026
00027 namespace cmlabs {
00028
00029
00030
00031
00032
00033 OSCommand::OSCommand() {
00034 init();
00035 }
00036
00037 OSCommand::OSCommand(const JString& cmdline, const JString& startupdir) {
00038 command = cmdline;
00039 startupDir = startupdir;
00040 init();
00041 }
00042
00043 OSCommand::~OSCommand() {
00044 cleanUp();
00045 delete [] outbuffer;
00046 delete [] errbuffer;
00047 }
00048
00049 bool OSCommand::init() {
00050
00051 binary = false;
00052 consoleOutput = false;
00053 autoRestart = false;
00054 startedTime.setInvalid();
00055 endedTime.setInvalid();
00056 #ifdef WIN32
00057 procInfo.hProcess = NULL;
00058 procInfo.hThread = NULL;
00059 procInfo.dwProcessId = 0;
00060 procInfo.dwThreadId = 0;
00061 #else
00062 stdin_pipe[0] = 0;
00063 stdin_pipe[1] = 0;
00064 stdout_pipe[0] = 0;
00065 stdout_pipe[1] = 0;
00066 stderr_pipe[0] = 0;
00067 stderr_pipe[1] = 0;
00068 #endif
00069 outbuffer = NULL;
00070 outbuffercount = 0;
00071 outbuffermax = 0;
00072 resizeOutputBuffer(10000);
00073 errbuffer = NULL;
00074 errbuffercount = 0;
00075 errbuffermax = 0;
00076 resizeErrorBuffer(10000);
00077 proc_stdin = NULL;
00078 proc_stdout = NULL;
00079 proc_stderr = NULL;
00080 procID = -1;
00081 returncode = -1;
00082 return true;
00083 }
00084
00085 bool OSCommand::restart() {
00086 terminate();
00087 cleanUp();
00088 delete [] outbuffer;
00089 delete [] errbuffer;
00090 startedTime.setInvalid();
00091 endedTime.setInvalid();
00092 #ifdef WIN32
00093 procInfo.hProcess = NULL;
00094 procInfo.hThread = NULL;
00095 procInfo.dwProcessId = 0;
00096 procInfo.dwThreadId = 0;
00097 #else
00098 stdin_pipe[0] = 0;
00099 stdin_pipe[1] = 0;
00100 stdout_pipe[0] = 0;
00101 stdout_pipe[1] = 0;
00102 stderr_pipe[0] = 0;
00103 stderr_pipe[1] = 0;
00104 #endif
00105 outbuffer = NULL;
00106 outbuffercount = 0;
00107 outbuffermax = 0;
00108 resizeOutputBuffer(10000);
00109 errbuffer = NULL;
00110 errbuffercount = 0;
00111 errbuffermax = 0;
00112 resizeErrorBuffer(10000);
00113 proc_stdin = NULL;
00114 proc_stdout = NULL;
00115 proc_stderr = NULL;
00116 procID = -1;
00117 returncode = -1;
00118 return start();
00119 }
00120
00121 bool OSCommand::setBinary() {
00122 binary = true;
00123 return true;
00124 }
00125
00126 bool OSCommand::setASCII() {
00127 binary = false;
00128 return true;
00129 }
00130
00131 JString OSCommand::getCommand() {
00132 return command;
00133 }
00134
00135 int OSCommand::getReturnCode() {
00136 if (isRunning())
00137 return -1;
00138 return returncode;
00139 }
00140
00141 bool OSCommand::hasTerminated() {
00142 if (!hasBeenStarted())
00143 return false;
00144 return (!isRunning());
00145 }
00146
00147 JTime OSCommand::getStartedTime() {
00148 return startedTime;
00149 }
00150
00151 JTime OSCommand::getEndedTime() {
00152 return endedTime;
00153 }
00154
00155
00156 JString OSCommand::getStartupDir() {
00157 return startupDir;
00158 }
00159
00160 int OSCommand::getProcID() {
00161 return procID;
00162 }
00163
00164 bool OSCommand::hasOutput() {
00165 return (getOutputCharCount() > 0);
00166 }
00167
00168 bool OSCommand::hasErrors() {
00169 return (getErrorCharCount() > 0);
00170 }
00171
00172 int OSCommand::getOutputCharCount() {
00173 readIntoBuffers();
00174 return outbuffercount;
00175 }
00176
00177 int OSCommand::getErrorCharCount() {
00178 readIntoBuffers();
00179 return errbuffercount;
00180 }
00181
00182 bool OSCommand::writeToStandardInput(const JString& text) {
00183 return writeToStandardInput(text, text.length());
00184 }
00185
00186 JString OSCommand::getCurrentOutput() {
00187 getNewOutput();
00188 return outputHistory;
00189 }
00190
00191 JString OSCommand::getCurrentError() {
00192 getNewError();
00193 return errorHistory;
00194 }
00195
00196 JString OSCommand::getNewOutput() {
00197 readIntoBuffers();
00198 if (getOutputCharCount() <= 0)
00199 return "";
00200 JString str = outbuffer;
00201 outbuffercount = 0;
00202 outputHistory += str;
00203 if (outputHistory.length() > 10000)
00204 outputHistory = outputHistory.getLast(10000);
00205 return str;
00206 }
00207
00208 JString OSCommand::getNewError() {
00209 readIntoBuffers();
00210 if (getErrorCharCount() <= 0)
00211 return "";
00212 JString str = errbuffer;
00213 errbuffercount = 0;
00214 errorHistory += str;
00215 if (errorHistory.length() > 10000)
00216 errorHistory = errorHistory.getLast(10000);
00217 return str;
00218 }
00219
00220 JString OSCommand::readOutputLine(int timeout) {
00221
00222 JTime start;
00223
00224 readIntoBuffers();
00225
00226 char* str = strchr(outbuffer, 10);
00227 if (str == NULL) {
00228 if (timeout == 0)
00229 return "";
00230
00231 while ( (str = strchr(outbuffer, 10)) == NULL ) {
00232 readIntoBuffers();
00233
00234 if (start.getAge() >= timeout)
00235 return "";
00236 this->wait(5);
00237 }
00238 }
00239
00240 int len = (int)(str - outbuffer);
00241 if (len > outbuffermax)
00242 return "";
00243 str[0] = 0;
00244 JString s = outbuffer;
00245 s = s.trim();
00246 memmove(outbuffer, str+1, len+1);
00247 return s;
00248 }
00249
00250 Collection OSCommand::readCurrentLines() {
00251 readIntoBuffers();
00252 Collection lines;
00253 if (getOutputCharCount() <= 0)
00254 return lines;
00255 JString str = outbuffer;
00256 lines = str.splitIntoLines();
00257 outbuffercount = 0;
00258 return lines;
00259 }
00260
00261 JString OSCommand::waitForProcessToFinishAndGetOutput(int timeout) {
00262 readIntoBuffers();
00263 if (!waitForProcessToFinish(timeout))
00264 return "";
00265 readIntoBuffers();
00266 JString str = outbuffer;
00267 outbuffercount = 0;
00268 return str;
00269 }
00270
00271 JString OSCommand::waitForProcessToFinishAndGetError(int timeout) {
00272 readIntoBuffers();
00273 if (!waitForProcessToFinish(timeout))
00274 return "";
00275 readIntoBuffers();
00276 JString str = errbuffer;
00277 errbuffercount = 0;
00278 return str;
00279 }
00280
00281
00282 char* OSCommand::readOutputBytes(int length, int* readcount, int timeout) {
00283
00284 *readcount = 0;
00285 if (length > outbuffermax) {
00286 if (!resizeOutputBuffer(length))
00287 return NULL;
00288 }
00289
00290 JTime start;
00291
00292 readIntoBuffers();
00293
00294 if (timeout > 0) {
00295 while (outbuffercount < length) {
00296 readIntoBuffers();
00297
00298 if (start.getAge() >= timeout)
00299 break;
00300 this->wait(5);
00301 }
00302 }
00303
00304 int len = 0;
00305 if (outbuffercount <= length)
00306 len = outbuffercount;
00307 else
00308 len = length;
00309
00310 *readcount = len;
00311 char* buf = new char[len+1];
00312 memcpy(buf, outbuffer, len);
00313 outbuffercount -= len;
00314
00315 if (outbuffercount > 0)
00316 memmove(outbuffer, outbuffer+len, outbuffercount);
00317
00318 return buf;
00319 }
00320
00321 bool OSCommand::resizeOutputBuffer(int max) {
00322
00323 if (max <= outbuffermax)
00324 return true;
00325
00326 char* newbuffer = new char[max+1];
00327 if (outbuffercount > 0) {
00328 memcpy(newbuffer, outbuffer, outbuffercount);
00329 }
00330 delete [] outbuffer;
00331 outbuffer = newbuffer;
00332 outbuffer[outbuffermax] = 0;
00333 outbuffermax = max;
00334 outbuffer[outbuffermax] = 0;
00335 return true;
00336 }
00337
00338 bool OSCommand::resizeErrorBuffer(int max) {
00339
00340 if (max <= errbuffermax)
00341 return true;
00342
00343 char* newbuffer = new char[max+1];
00344 if (errbuffercount > 0) {
00345 memcpy(newbuffer, errbuffer, errbuffercount);
00346 }
00347 delete [] errbuffer;
00348 errbuffer = newbuffer;
00349 errbuffer[errbuffermax] = 0;
00350 errbuffermax = max;
00351 errbuffer[errbuffermax] = 0;
00352 return true;
00353 }
00354
00355
00356
00357
00358
00359 #if defined(WIN32_DESKTOP)
00360
00361
00362
00363 bool OSCommand::start() {
00364
00365 startedTime = JTime();
00366 if (command.length() == 0) {
00367 returncode = 0;
00368 endedTime = JTime();
00369 return false;
00370 }
00371
00372 STARTUPINFO si;
00373
00374 SECURITY_ATTRIBUTES sa;
00375
00376 ZeroMemory(&si, sizeof(si));
00377 si.cb = sizeof(si);
00378 si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
00379
00380 si.wShowWindow = SW_HIDE;
00381
00382
00383 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
00384 sa.lpSecurityDescriptor = NULL;
00385 sa.bInheritHandle = TRUE;
00386
00387
00388 HANDLE hStdinRead,hStdinWrite;
00389 HANDLE hStdoutRead,hStdoutWrite;
00390 HANDLE hStderrRead,hStderrWrite;
00391
00392
00393
00394 if (!CreatePipe(&hStdinRead,&hStdinWrite,&sa,0)) {
00395 endedTime = JTime();
00396 return false;
00397 }
00398
00399 if (!CreatePipe(&hStdoutRead,&hStdoutWrite,&sa,0)) {
00400 endedTime = JTime();
00401 return false;
00402 }
00403
00404 if (!CreatePipe(&hStderrRead,&hStderrWrite,&sa,0)) {
00405 endedTime = JTime();
00406 return false;
00407 }
00408
00409
00410
00411
00412
00413 if (!DuplicateHandle(GetCurrentProcess(),hStdinWrite,
00414 GetCurrentProcess(),
00415 &proc_stdin,
00416 0,FALSE,
00417 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) {
00418 endedTime = JTime();
00419 return false;
00420 }
00421
00422 if (!DuplicateHandle(GetCurrentProcess(),hStdoutRead,
00423 GetCurrentProcess(),
00424 &proc_stdout,
00425 0,FALSE,
00426 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) {
00427 endedTime = JTime();
00428 return false;
00429 }
00430 if (!DuplicateHandle(GetCurrentProcess(),hStderrRead,
00431 GetCurrentProcess(),
00432 &proc_stderr,
00433 0,FALSE,
00434 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) {
00435 endedTime = JTime();
00436 return false;
00437 }
00438
00439 si.hStdInput = hStdinRead;
00440 si.hStdOutput = hStdoutWrite;
00441 si.hStdError = hStderrWrite;
00442
00443 JString winCommand = command;
00444 winCommand.replace("/", "\\");
00445 char* cmd = new char[winCommand.length() + 10];
00446 strcpy(cmd, winCommand);
00447
00448 char* initdir = NULL;
00449 if (startupDir.length() > 0) {
00450 JString winStartupDir = startupDir;
00451 winStartupDir.replace("/", "\\");
00452 if (!JFile::doesAFileExist(winStartupDir))
00453 printf("Warning: Startup directory '%s' does not appear to exist, using default...\n", (char*) winStartupDir);
00454 else {
00455 initdir = new char[winStartupDir.length() + 10];
00456 strcpy(initdir, winStartupDir);
00457 }
00458 }
00459
00460 int res = CreateProcess(
00461 NULL,
00462 cmd,
00463 NULL,
00464 NULL,
00465 TRUE,
00466
00467 0,
00468 NULL,
00469 initdir,
00470 &si,
00471 &procInfo);
00472
00473 delete [] cmd;
00474
00475 if (res == 0) {
00476 char msg[256];
00477 int length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
00478 NULL, GetLastError(), 0, msg, sizeof(msg), NULL);
00479 msg[length] = '\0';
00480 if (DEBUGLEVEL(STATUS))
00481 printf("CreateProcess Error: %s\n", msg);
00482 endedTime = JTime();
00483 return false;
00484 }
00485 if (DEBUGLEVEL(DEBUG))
00486 printf("CreateProcess Success: %s\n", (char*)command);
00487
00488
00489
00490 if (!CloseHandle(hStdinRead)) {
00491 endedTime = JTime();
00492 return false;
00493 }
00494 if (!CloseHandle(hStdoutWrite)) {
00495 endedTime = JTime();
00496 return false;
00497 }
00498 if (!CloseHandle(hStderrWrite)) {
00499 endedTime = JTime();
00500 return false;
00501 }
00502
00503 procID = procInfo.dwProcessId;
00504
00505 return true;
00506 }
00507
00508 bool OSCommand::terminate() {
00509 if (!isRunning())
00510 return true;
00511 if (procInfo.hProcess == NULL)
00512 return false;
00513
00514 if (TerminateProcess(procInfo.hProcess, 10) == 0)
00515 return false;
00516
00517 if (!endedTime.isValid())
00518 endedTime = JTime();
00519 return true;
00520 }
00521
00522 bool OSCommand::cleanUp() {
00523 terminate();
00524 CloseHandle(proc_stdin);
00525 CloseHandle(proc_stdout);
00526 CloseHandle(proc_stderr);
00527 CloseHandle(procInfo.hProcess);
00528 CloseHandle(procInfo.hThread);
00529 return true;
00530 }
00531
00532 bool OSCommand::waitForProcessToFinish(int timeout) {
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 if (procInfo.hProcess == NULL)
00545 return false;
00546 return (WaitForSingleObject(procInfo.hProcess, timeout) == WAIT_OBJECT_0);
00547 }
00548
00549 bool OSCommand::hasBeenStarted() {
00550 return (proc_stdout != NULL);
00551 }
00552
00553 bool OSCommand::isRunning() {
00554 if (!hasBeenStarted())
00555 return false;
00556 if (procInfo.hProcess <= 0) {
00557 if (!endedTime.isValid())
00558 endedTime = JTime();
00559 return false;
00560 }
00561 if (returncode != -1) {
00562 if (!endedTime.isValid())
00563 endedTime = JTime();
00564 return false;
00565 }
00566
00567 DWORD exitCode;
00568 if (GetExitCodeProcess(procInfo.hProcess, &exitCode) == 0) {
00569 returncode = -999;
00570 if (!endedTime.isValid())
00571 endedTime = JTime();
00572 return false;
00573 }
00574
00575 if (exitCode == STILL_ACTIVE) {
00576 if (DEBUGLEVEL(HEARTBEAT))
00577 printf("ProcID %d still running...\n", procID);
00578 return true;
00579 }
00580
00581 returncode = (int)exitCode;
00582 if (DEBUGLEVEL(DEBUG))
00583 printf("ProcID %d exited with %d...\n", procID, returncode);
00584 if (!endedTime.isValid())
00585 endedTime = JTime();
00586 return false;
00587 }
00588
00589 bool OSCommand::writeToStandardInput(char* bytes, int len) {
00590 if (proc_stdin == NULL)
00591 return false;
00592 DWORD nBytesWrote;
00593 if (WriteFile(proc_stdin,bytes,len,&nBytesWrote,NULL) == 0) {
00594 isRunning();
00595 return false;
00596 }
00597 return true;
00598 }
00599
00600 int OSCommand::readIntoBuffers() {
00601
00602 if (proc_stdout == NULL)
00603 return -1;
00604
00605 if (outbuffercount > (outbuffermax*0.90))
00606 resizeOutputBuffer(outbuffermax*2);
00607 if (errbuffercount > (errbuffermax*0.90))
00608 resizeErrorBuffer(errbuffermax*2);
00609
00610 DWORD outBytesRead = 0;
00611 DWORD outBytesToRead = 0;
00612 DWORD errBytesRead = 0;
00613 DWORD errBytesToRead = 0;
00614
00615 outBytesToRead = (outbuffermax-outbuffercount);
00616
00617 if ( (PeekNamedPipe(proc_stdout, NULL, 0, NULL, &outBytesToRead, NULL) != 0) &&
00618 (outBytesToRead > 0) ) {
00619
00620 if (outBytesToRead > (DWORD)(outbuffermax-outbuffercount)) {
00621 outBytesToRead = (DWORD)(outbuffermax-outbuffercount);
00622 }
00623 if (ReadFile(proc_stdout,outbuffer+outbuffercount,outBytesToRead, &outBytesRead, NULL) != 0) {
00624 outbuffercount += outBytesRead;
00625 outbuffer[outbuffercount] = 0;
00626 }
00627 }
00628
00629 errBytesToRead = (errbuffermax-errbuffercount);
00630
00631 if ( (PeekNamedPipe(proc_stderr, NULL, 0, NULL, &errBytesToRead, NULL) != 0) &&
00632 (errBytesToRead > 0) ) {
00633
00634 if (errBytesToRead > (DWORD)(errbuffermax-errbuffercount)) {
00635 errBytesToRead = (DWORD)(errbuffermax-errbuffercount);
00636 }
00637 if (ReadFile(proc_stderr,errbuffer+errbuffercount, errBytesToRead, &errBytesRead, NULL) != 0) {
00638 errbuffercount += errBytesRead;
00639 errbuffer[errbuffercount] = 0;
00640 }
00641 }
00642
00643 isRunning();
00644
00645 return outBytesRead+errBytesRead;
00646 }
00647
00648
00649
00650 #elif defined(WIN32_POCKETPC)
00651
00652
00653 bool OSCommand::start() {
00654 return false;
00655 }
00656
00657 bool OSCommand::terminate() {
00658 return true;
00659 }
00660
00661 bool OSCommand::cleanUp() {
00662 return true;
00663 }
00664
00665 bool OSCommand::waitForProcessToFinish(int timeout) {
00666 return false;
00667 }
00668
00669 bool OSCommand::hasBeenStarted() {
00670 return false;
00671 }
00672
00673 bool OSCommand::isRunning() {
00674 return false;
00675 }
00676
00677 bool OSCommand::writeToStandardInput(char* bytes, int len) {
00678 return false;
00679 }
00680
00681 int OSCommand::readIntoBuffers() {
00682 return 0;
00683 }
00684
00685
00686
00687
00688
00689
00690 #else // WIN32
00691
00692
00693 bool OSCommand::start() {
00694
00695 if (hasBeenStarted())
00696 return true;
00697
00698 startedTime = JTime();
00699 if (command.length() == 0) {
00700 returncode = 0;
00701 endedTime = JTime();
00702 return false;
00703 }
00704
00705 if ( (pipe(stdin_pipe) != 0) || (pipe(stdout_pipe) != 0) || (pipe(stderr_pipe) != 0) ) {
00706 endedTime = JTime();
00707 return false;
00708 }
00709
00710 int pid = fork();
00711
00712 if (pid < 0) {
00713 endedTime = JTime();
00714 return false;
00715 }
00716
00717
00718 else if (pid == 0) {
00719
00720
00721
00722
00723
00724
00725
00726
00727 close(0);
00728
00729
00730 dup2(stdin_pipe[0], 0);
00731
00732
00733 close(stdin_pipe[0]);
00734 close(stdin_pipe[1]);
00735
00736
00737 close(1);
00738 dup(stdout_pipe[1]);
00739 close(stdout_pipe[0]);
00740 close(stdout_pipe[1]);
00741
00742
00743 close(2);
00744 dup(stderr_pipe[1]);
00745 close(stderr_pipe[0]);
00746 close(stderr_pipe[1]);
00747
00748
00749 Collection args = command.splitOnWhiteSpaces();
00750 int argc = args.getCount();
00751 char** argv = new char*[argc+1];
00752 int len;
00753 JString s;
00754 for (int n=0; n<argc; n++) {
00755 s = args.get(n);
00756 s.replace("\\ ", " ");
00757 argv[n] = s.getCharCopy(len);
00758 }
00759 argv[argc] = NULL;
00760
00761 if (startupDir.length() > 0) {
00762 JString myStartupDir = startupDir;
00763 myStartupDir.replace("\\", "/");
00764 if (!JFile::doesAFileExist(myStartupDir))
00765 printf("Warning: Startup directory '%s' does not appear to exist, using default...\n", (char*) myStartupDir);
00766 else {
00767 if (chdir(myStartupDir) != 0)
00768 printf("Warning: Startup directory '%s' does not appear to be valid, using default...\n", (char*) myStartupDir);
00769 }
00770 }
00771
00772 if (DEBUGLEVEL(DEBUG))
00773 printf("OSCommand running: %s (%d args) %s...\n", (char*) command, argc, (char*)args.printListLine("|")); fflush(stdout);
00774
00775 execvp(argv[0],argv);
00776
00777 int res = errno;
00778
00779 if (DEBUGLEVEL(DEBUG))
00780 printf("OSCommand: Fork failed with error: %d!\n", res);
00781 exit(0);
00782 }
00783
00784
00785 else {
00786 procID = pid;
00787
00788 close(stdin_pipe[0]);
00789 close(stdout_pipe[1]);
00790 close(stderr_pipe[1]);
00791
00792 long parm = fcntl(stdout_pipe[0], F_GETFL);
00793 parm |= O_NONBLOCK;
00794 fcntl(stdout_pipe[0], F_SETFL, parm);
00795 parm = fcntl(stderr_pipe[0], F_GETFL);
00796 parm |= O_NONBLOCK;
00797 fcntl(stderr_pipe[0], F_SETFL, parm);
00798
00799 if (binary) {
00800 if ( (proc_stdin = fdopen(stdin_pipe[1], "wb")) == NULL)
00801 printf("Error: stdin creation...\n");
00802 if ( (proc_stdout = fdopen(stdout_pipe[0], "rb")) == NULL)
00803 printf("Error: stdin creation...\n");
00804 if ( (proc_stderr = fdopen(stderr_pipe[0], "rb")) == NULL)
00805 printf("Error: stdin creation...\n");
00806 }
00807 else {
00808 if ( (proc_stdin = fdopen(stdin_pipe[1], "w")) == NULL)
00809 printf("Error: stdin creation...\n");
00810 if ( (proc_stdout = fdopen(stdout_pipe[0], "r")) == NULL)
00811 printf("Error: stdin creation...\n");
00812 if ( (proc_stderr = fdopen(stderr_pipe[0], "r")) == NULL)
00813 printf("Error: stdin creation...\n");
00814 }
00815 }
00816
00817
00818 return true;
00819 }
00820
00821 bool OSCommand::terminate() {
00822 if (!isRunning())
00823 return true;
00824 if (procID <= 0)
00825 return false;
00826
00827 if (kill(procID, SIGKILL) != 0)
00828 return false;
00829
00830 if (!endedTime.isValid())
00831 endedTime = JTime();
00832 return true;
00833 }
00834
00835 bool OSCommand::cleanUp() {
00836
00837 terminate();
00838
00839
00840
00841 if (proc_stdout) {
00842 fclose(proc_stdout);
00843 }
00844 if (proc_stderr) {
00845 fclose(proc_stderr);
00846 }
00847 if (proc_stdin) {
00848 fclose(proc_stdin);
00849 }
00850 return true;
00851 }
00852
00853 bool OSCommand::waitForProcessToFinish(int timeout) {
00854
00855 JTime start;
00856
00857
00858 while (isRunning()) {
00859
00860 if (start.getAge() >= timeout)
00861 return false;
00862 this->wait(5);
00863 }
00864 return true;
00865 }
00866
00867 bool OSCommand::hasBeenStarted() {
00868 return (proc_stdout != NULL);
00869 }
00870
00871 bool OSCommand::isRunning() {
00872 if (!hasBeenStarted())
00873 return false;
00874 if (returncode >= 0) {
00875 if (!endedTime.isValid())
00876 endedTime = JTime();
00877 return false;
00878 }
00879 int status;
00880
00881 int res = waitpid(procID, &status, WNOHANG);
00882 if (res == procID) {
00883 returncode = WEXITSTATUS(status);
00884 if (DEBUGLEVEL(DEBUG))
00885 printf("ProcID %d exited with %d...\n", procID, returncode);
00886 if (!endedTime.isValid())
00887 endedTime = JTime();
00888 return false;
00889 }
00890 else if (res == 0) {
00891 if (DEBUGLEVEL(HEARTBEAT))
00892 printf("ProcID %d still running...\n", procID);
00893 return true;
00894 }
00895
00896
00897 kill(procID, SIGKILL);
00898 returncode = 99;
00899 if (DEBUGLEVEL(DEBUG))
00900 printf("ProcID %d error %d...\n", procID, errno);
00901 if (!endedTime.isValid())
00902 endedTime = JTime();
00903 return false;
00904 }
00905
00906 bool OSCommand::writeToStandardInput(char* bytes, int len) {
00907
00908 if (proc_stdin == NULL)
00909 return -1;
00910
00911 int nBytesWrote;
00912 if ( (nBytesWrote = fwrite(bytes, 1, len, proc_stdin)) <= len) {
00913 isRunning();
00914 return false;
00915 }
00916 return true;
00917 }
00918
00919 int OSCommand::readIntoBuffers() {
00920
00921
00922
00923 if (proc_stdout == NULL)
00924 return -1;
00925
00926 int res = 0;
00927
00928 int outBytesRead = fread(outbuffer+outbuffercount, 1, outbuffermax-outbuffercount, proc_stdout);
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939 if (outBytesRead < 0) {
00940 }
00941
00942 outbuffercount += outBytesRead;
00943 outbuffer[outbuffercount] = 0;
00944
00945
00946
00947 int errBytesRead = fread(errbuffer+errbuffercount, 1, errbuffermax-errbuffercount, proc_stderr);
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957 if (errBytesRead < 0) {
00958 }
00959
00960 errbuffercount += errBytesRead;
00961 errbuffer[errbuffercount] = 0;
00962 isRunning();
00963
00964 return outBytesRead+errBytesRead;
00965 }
00966
00967
00968
00969
00970
00971 #endif // WIN32
00972
00973
00974
00975
00976 bool OSCommand::unitTest() {
00977
00978 JString cmd;
00979 #ifdef WIN32
00980 cmd = "notepad";
00981 #else //WIN32
00982 cmd = "ls / /bla";
00983
00984 #endif //WIN32
00985
00986 OSCommand* com = new OSCommand(cmd);
00987 if (!com->start())
00988 return false;
00989
00990 JTime start;
00991 JString out = com->waitForProcessToFinishAndGetOutput(3000);
00992 JString err = com->waitForProcessToFinishAndGetError(3000);
00993 JTime end;
00994
00995
00996 delete(com);
00997 return true;
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017 }
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 }