int runcmd_timeout(const char *cmd, cetype_t enc, int wait, int visible, const char *fin, const char *fout, const char *ferr, int timeout, int *timedout) { if (!wait && timeout) error("Timeout with background running processes is not supported."); HANDLE hIN = getInputHandle(fin), hOUT, hERR; int ret = 0; PROCESS_INFORMATION pi; int close1 = 0, close2 = 0, close3 = 0; if (hIN && fin && fin[0]) close1 = 1; hOUT = getOutputHandle(fout, 0); if (!hOUT) return 1; if (fout && fout[0]) close2 = 1; if (fout && fout[0] && ferr && streql(fout, ferr)) hERR = hOUT; else { hERR = getOutputHandle(ferr, 1); if (!hERR) return 1; if (ferr && ferr[0]) close3 = 1; } memset(&pi, 0, sizeof(pi)); pcreate(cmd, enc, !wait, visible, hIN, hOUT, hERR, &pi); if (pi.hProcess) { if (wait) { RCNTXT cntxt; begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv, R_NilValue, R_NilValue); cntxt.cend = &terminate_process; cntxt.cenddata = π DWORD timeoutMillis = (DWORD) (1000*timeout); ret = pwait2(pi.hProcess, timeoutMillis, timedout); endcontext(&cntxt); snprintf(RunError, 501, _("Exit code was %d"), ret); ret &= 0xffff; } else ret = 0; CloseHandle(pi.hProcess); } else { ret = NOLAUNCH; } if (close1) CloseHandle(hIN); if (close2) CloseHandle(hOUT); if (close3) CloseHandle(hERR); return ret; }
/* Used for external commands in file.show() and edit(), and for system(intern=FALSE). Also called from postscript(). wait != 0 says wait for child to terminate before returning. visible = -1, 0, 1 for hide, minimized, default fin is either NULL or the name of a file from which to redirect stdin for the child. fout/ferr are NULL (use NUL:), "" (use standard streams) or filenames. */ int runcmd(const char *cmd, cetype_t enc, int wait, int visible, const char *fin, const char *fout, const char *ferr) { HANDLE hIN = getInputHandle(fin), hOUT, hERR; int ret = 0; PROCESS_INFORMATION pi; int close1 = 0, close2 = 0, close3 = 0; if (hIN && fin && fin[0]) close1 = 1; hOUT = getOutputHandle(fout, 0); if (!hOUT) return 1; if (fout && fout[0]) close2 = 1; if (fout && fout[0] && ferr && streql(fout, ferr)) hERR = hOUT; else { hERR = getOutputHandle(ferr, 1); if (!hERR) return 1; if (ferr && ferr[0]) close3 = 1; } memset(&pi, 0, sizeof(pi)); pcreate(cmd, enc, !wait, visible, hIN, hOUT, hERR, &pi); if (!pi.hProcess) return NOLAUNCH; if (wait) { RCNTXT cntxt; begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv, R_NilValue, R_NilValue); cntxt.cend = &terminate_process; cntxt.cenddata = π ret = pwait2(pi.hProcess); endcontext(&cntxt); snprintf(RunError, 501, _("Exit code was %d"), ret); ret &= 0xffff; } else ret = 0; CloseHandle(pi.hProcess); if (close1) CloseHandle(hIN); if (close2) CloseHandle(hOUT); if (close3) CloseHandle(hERR); return ret; }
/* finput is either NULL or the name of a file from which to redirect stdin for the child. visible = -1, 0, 1 for hide, minimized, default io = 0 to read stdout from pipe, 1 to write to pipe, 2 to read stderr from pipe, 3 to read both stdout and stderr from pipe. */ rpipe * rpipeOpen(const char *cmd, cetype_t enc, int visible, const char *finput, int io, const char *fout, const char *ferr) { rpipe *r; HANDLE hTHIS, hIN, hOUT, hERR, hReadPipe, hWritePipe; DWORD id; BOOL res; int close1 = 0, close2 = 0, close3 = 0; if (!(r = (rpipe *) malloc(sizeof(struct structRPIPE)))) { strcpy(RunError, _("Insufficient memory (rpipeOpen)")); return NULL; } r->active = 0; r->pi.hProcess = NULL; r->thread = NULL; res = CreatePipe(&hReadPipe, &hWritePipe, NULL, 0); if (res == FALSE) { rpipeClose(r); strcpy(RunError, "CreatePipe failed"); return NULL; } if(io == 1) { /* pipe for R to write to */ hTHIS = GetCurrentProcess(); r->read = hReadPipe; DuplicateHandle(hTHIS, hWritePipe, hTHIS, &r->write, 0, FALSE, DUPLICATE_SAME_ACCESS); CloseHandle(hWritePipe); CloseHandle(hTHIS); /* This sends stdout and stderr to NUL: */ pcreate(cmd, enc, 1, visible, r->read, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, &(r->pi)); r->active = 1; if (!r->pi.hProcess) return NULL; else return r; } /* pipe for R to read from */ hTHIS = GetCurrentProcess(); r->write = hWritePipe; DuplicateHandle(hTHIS, hReadPipe, hTHIS, &r->read, 0, FALSE, DUPLICATE_SAME_ACCESS); CloseHandle(hReadPipe); CloseHandle(hTHIS); hIN = getInputHandle(finput); /* a file or (usually NUL:) */ if (hIN && finput && finput[0]) close1 = 1; if ((io == 0 || io == 3)) hOUT = r->write; else { if (fout && fout[0]) close2 = 1; hOUT = getOutputHandle(fout, 0); } if (io >= 2) hERR = r->write; else { if (ferr && ferr[0]) close3 = 1; hERR = getOutputHandle(ferr, 1); } pcreate(cmd, enc, 0, visible, hIN, hOUT, hERR, &(r->pi)); if (close1) CloseHandle(hIN); if (close2) CloseHandle(hOUT); if (close3) CloseHandle(hERR); r->active = 1; if (!r->pi.hProcess) return NULL; if (!(r->thread = CreateThread(NULL, 0, threadedwait, r, 0, &id))) { rpipeClose(r); strcpy(RunError, "CreateThread failed"); return NULL; } return r; }
static Console::CodeType getDefaultCode() { CONSOLE_SCREEN_BUFFER_INFO currentInfo; GetConsoleScreenBufferInfo(getOutputHandle(), ¤tInfo); return currentInfo.wAttributes; }
SOFA_HELPER_API std::ostream& operator<<( std::ostream& stream, Console::CodeType code ) { if (Console::shouldUseColors(stream)) SetConsoleTextAttribute(getOutputHandle(), code.value); return stream; }