BOOL CIperfThread::InitInstance() { // TODO: スレッドごとの初期化をここで実行します。 HANDLE hOldIn = GetStdHandle(STD_INPUT_HANDLE); HANDLE hOldOut = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE hOldErr = GetStdHandle(STD_ERROR_HANDLE); STARTUPINFOA si; memset(&si,0,sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags |= STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; m_uniqid = mkhash(m_CmdLine, m_uniqid) ; m_uniqid += (WORD)m_nThreadID; m_uniqid += (WORD)m_nThreadID >> 4; FreeConsole(); AllocConsole(); CreateIperfPipe(); if(CreateProcess(NULL, m_CmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &m_ProcessInfo) == FALSE ) { return FALSE; } EnumWindows(WindowHidden, (LPARAM)(PROCESS_INFORMATION *)&m_ProcessInfo); WaitForInputIdle(m_ProcessInfo.hProcess, INFINITE); SetStdHandle(STD_OUTPUT_HANDLE,hOldOut); SetStdHandle(STD_INPUT_HANDLE,hOldIn); SetStdHandle(STD_ERROR_HANDLE,hOldErr); EnumWindows(WindowHidden, (LPARAM)(PROCESS_INFORMATION *)&m_ProcessInfo); return TRUE; }
unsigned SysRunCommandPipe( const char *cmd, int *readpipe ) { int rc; HANDLE pipe_input; HANDLE pipe_output; HANDLE pipe_input_dup; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof( sa ); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; if( !CreatePipe( &pipe_input, &pipe_output, &sa, 0 ) ) { return( GetLastError() ); } SetStdHandle( STD_OUTPUT_HANDLE, pipe_output ); SetStdHandle( STD_ERROR_HANDLE, pipe_output ); DuplicateHandle( GetCurrentProcess(), pipe_input, GetCurrentProcess(), &pipe_input_dup, 0, FALSE, DUPLICATE_SAME_ACCESS ); CloseHandle( pipe_input ); rc = RunChildProcessCmdl( cmd ); CloseHandle( pipe_output ); *readpipe = _hdopen( ( int ) pipe_input_dup, O_RDONLY ); return( rc ); }
APIRET os2APIENTRY DosDupHandle(os2HFILE hFile, PHFILE pHfile) { int srcIdx = (int)hFile; FileTable.lock(srcIdx); if(!FileTable[srcIdx]) { FileTable.unlock(srcIdx); return 1; //FixMe } int dstIdx; if(*pHfile==(os2HFILE)-1) { dstIdx = FileTable.findAndLockFree(); if(dstIdx==-1) { FileTable.unlock(srcIdx); return 4; //too many open files } } else { dstIdx = (int)*pHfile; FileTable.lock(dstIdx); } if(srcIdx==dstIdx) { //no-op FileTable.unlock(srcIdx); return 0; } if(FileTable[dstIdx]) { CloseHandle(FileTable[dstIdx]->ntFileHandle); delete FileTable[dstIdx]; FileTable[dstIdx] = 0; } APIRET rc; HANDLE target; if(DuplicateHandle(GetCurrentProcess(), FileTable[srcIdx]->ntFileHandle, GetCurrentProcess(), &target, 0, TRUE, DUPLICATE_SAME_ACCESS )) { rc = 0; FileTable[dstIdx] = new ntFILE; FileTable[dstIdx]->ntFileHandle = target; FileTable[dstIdx]->mode = FileTable[srcIdx]->mode; if(dstIdx==0) SetStdHandle(STD_INPUT_HANDLE,target); else if(dstIdx==1) SetStdHandle(STD_OUTPUT_HANDLE,target); else if(dstIdx==2) SetStdHandle(STD_ERROR_HANDLE,target); } else rc = 6; //invalid handle FileTable.unlock(srcIdx); FileTable.unlock(dstIdx); return rc; }
/* * WIN32_strerror with argument for late notification */ const char * WIN32_strerror(int err) { static char xbstrerror_buf[BUFSIZ]; if (err < 0 || err >= sys_nerr) strncpy(xbstrerror_buf, wsastrerror(err), BUFSIZ); else strncpy(xbstrerror_buf, strerror(err), BUFSIZ); return xbstrerror_buf; } int WIN32_Close_FD_Socket(int fd) { int result = 0; if (closesocket(_get_osfhandle(fd)) == SOCKET_ERROR) { errno = WSAGetLastError(); result = 1; } _free_osfhnd(fd); _osfile(fd) = 0; return result; } #if defined(__MINGW32__) /* MinGW environment */ int _free_osfhnd(int filehandle) { if (((unsigned) filehandle < SQUID_MAXFD) && (_osfile(filehandle) & FOPEN) && (_osfhnd(filehandle) != (long) INVALID_HANDLE_VALUE)) { switch (filehandle) { case 0: SetStdHandle(STD_INPUT_HANDLE, NULL); break; case 1: SetStdHandle(STD_OUTPUT_HANDLE, NULL); break; case 2: SetStdHandle(STD_ERROR_HANDLE, NULL); break; } _osfhnd(filehandle) = (long) INVALID_HANDLE_VALUE; return (0); } else { errno = EBADF; /* bad handle */ _doserrno = 0L; /* not an OS error */ return -1; } }
void CIperfThread::CreateIperfPipe() { HANDLE hReadPipeOut; HANDLE hReadPipeErr; HANDLE hReadPipeInp; HANDLE hWritePipeOut; HANDLE hWritePipeErr; HANDLE hWritePipeInp; HANDLE hParent = GetCurrentProcess(); SECURITY_ATTRIBUTES security; security.nLength = sizeof(SECURITY_ATTRIBUTES); security.lpSecurityDescriptor = NULL; security.bInheritHandle = TRUE; if(!CreatePipe(&hReadPipeOut,&hWritePipeOut,&security,0)) ASSERT(0);// ("CreatePipe"); if(!CreatePipe(&hReadPipeErr,&hWritePipeErr,&security,0)) ASSERT(0);// ("CreatePipe"); if(!CreatePipe(&hReadPipeInp,&hWritePipeInp,&security,0)) ASSERT(0);// ("CreatePipe"); SetStdHandle(STD_OUTPUT_HANDLE,hWritePipeOut); SetStdHandle(STD_ERROR_HANDLE, hWritePipeErr); SetStdHandle(STD_INPUT_HANDLE, hReadPipeInp); DuplicateHandle(hParent,hReadPipeOut,hParent,&m_hPipeOut,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(hParent,hReadPipeErr,hParent,&m_hPipeErr,0,FALSE,DUPLICATE_SAME_ACCESS); DuplicateHandle(hParent,hWritePipeInp,hParent,&m_hPipeIn,0,FALSE,DUPLICATE_SAME_ACCESS); CloseHandle(hReadPipeOut); CloseHandle(hReadPipeErr); CloseHandle(hWritePipeInp); }
bool ProcInOut::Exec(const std::string & cmd, std::string & out, DWORD timeout) { bool fSuccess; ZeroMemory(&saAttr, sizeof(saAttr)); saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) return false; if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr)) return false; fSuccess = (DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(), &hChildStdoutRdDup , 0, (FALSE ? false : true), (BOOL)DUPLICATE_SAME_ACCESS) != 0); if( !fSuccess ) return false; CloseHandle(hChildStdoutRd); if (! CreateChildProcess(cmd)) { CloseHandle(hChildStdoutWr); CloseHandle(hChildStdoutRdDup); CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); return false; } if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) return false; if (!CloseHandle(hChildStdoutWr)) return false; HANDLE lpHandles[] = { piProcInfo.hProcess, hChildStdoutRdDup, NULL}; DWORD dwWait; DWORD timerStart = GetTickCount(); DWORD timerEnd; for (;;) { dwWait = WaitForMultipleObjects(2, lpHandles, false, timeout); // process finished if (dwWait == WAIT_OBJECT_0 || dwWait == WAIT_ABANDONED_0 || dwWait == (WAIT_ABANDONED_0 + 1)) { break; } if (dwWait == (WAIT_OBJECT_0 + 1)) { timerEnd = GetTickCount(); // timeout if (timerEnd < timerStart && ((MAXDWORD - timerStart) + timerEnd) >= timeout) // counter has been reinitialized break ; if (timerStart < timerEnd && (timerEnd - timerStart) >= timeout) break ; ReadFromPipe(out); } if (dwWait == WAIT_TIMEOUT) { break; } } CloseHandle(hChildStdoutRdDup); CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); return true; }
/* This function does file handle black magic. Here, we create pipes, duplicate the ones we're going to pass on to the child process, and set the current process's stdin and stdout to be those pipes. (### I'm not sure duplicating them is necessary, but it doesn't hurt...) inpipes, outpipes, and old_handles are 2 element arrays. */ static void pipe_setup (STARTUPINFO *siStartInfo, int inpipes[], int outpipes[], HANDLE old_handles[]) { const int pipe_size = 2000; HANDLE new_stdin, new_stdout; HANDLE parent = GetCurrentProcess(); /* Create new file handles--in binary mode. _pipe sticks the read then the write handle in {in,out}pipes, and returns 0 on success and -1 on failure */ if (_pipe(inpipes, pipe_size, O_BINARY) != 0 || _pipe(outpipes, pipe_size, O_BINARY) != 0 /* Duplicate the stdin and stdout handles. False on failure. */ || !DuplicateHandle(parent, /* source process */ /* next, handle to dup */ (HANDLE) _get_osfhandle(inpipes[0]), parent, /* Proc to give new handles to */ &new_stdin, /* Where new handle is stored */ 0, /* Parameter ignored */ TRUE, /* Make new handle inheritable */ DUPLICATE_SAME_ACCESS) || !DuplicateHandle(parent, /* source process */ /* next, handle to dup */ (HANDLE)_get_osfhandle(outpipes[1]), parent, /* Proc to give new handles to */ &new_stdout, /* Where new handle is stored */ 0, /* Parameter ignored */ TRUE, /* Make new handle inheritable */ DUPLICATE_SAME_ACCESS)) { fprintf(stderr, "Failed while doing pipe stuff for fd_exec"); exit(1); } /* Save the old stdin and stdout handles to some place we can remember */ old_handles[0] = GetStdHandle(STD_INPUT_HANDLE); old_handles[1] = GetStdHandle(STD_OUTPUT_HANDLE); /* Set stdin and stdout to the new handles */ if (!SetStdHandle(STD_INPUT_HANDLE, new_stdin) || !SetStdHandle(STD_OUTPUT_HANDLE, new_stdout)) { fprintf(stderr, "Failed while doing pipe stuff for fd_exec"); exit(1); } /* Now tell the StartInfo to use the handles we just created. By default, child processes don't inherit the stdin and stdout of their parents. */ siStartInfo->dwFlags = STARTF_USESTDHANDLES; siStartInfo->hStdInput = new_stdin; siStartInfo->hStdOutput = new_stdout; /* nothing funny with stderr, but we still have to initialize the field anyway */ siStartInfo->hStdError = GetStdHandle(STD_ERROR_HANDLE); }
static long doExec( const char *std_in, const char *std_out, const char *cmd ) { HANDLE cp; long st; HANDLE old_in; HANDLE new_in; HANDLE old_out; HANDLE new_out; old_in = INVALID_HANDLE_VALUE; new_in = INVALID_HANDLE_VALUE; old_out = INVALID_HANDLE_VALUE; new_out = INVALID_HANDLE_VALUE; preSpawn(); cp = GetCurrentProcess(); if( std_in != NULL ) { old_in = GetStdHandle( STD_INPUT_HANDLE ); new_in = CreateFile( std_in, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( new_in == INVALID_HANDLE_VALUE ) { return( -1L ); } SetStdHandle( STD_INPUT_HANDLE, new_in ); } if( std_out != NULL ) { old_out = GetStdHandle( STD_INPUT_HANDLE ); new_out = CreateFile( std_out, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING | CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL ); if( new_out == INVALID_HANDLE_VALUE ) { if( std_in != NULL ) { SetStdHandle( STD_INPUT_HANDLE, old_in ); CloseHandle( new_in ); } return( -1L ); } SetStdHandle( STD_OUTPUT_HANDLE, new_out ); } if( cmd == NULL ) { st = MySpawn( Comspec ); } else { SetConsoleActiveScreenBuffer( GetStdHandle( STD_OUTPUT_HANDLE ) ); st = system( cmd ); } if( std_in != NULL ) { CloseHandle( new_in ); SetStdHandle( STD_INPUT_HANDLE, old_in ); } if( std_out != NULL ) { CloseHandle( new_out ); SetStdHandle( STD_OUTPUT_HANDLE, old_out ); } postSpawn( st ); return( st ); }
void console_widget_NT_t::restore_console() { FlushConsoleInputBuffer(saved_input); SetConsoleMode(saved_input, saved_mode); SetStdHandle(STD_INPUT_HANDLE, saved_input); SetStdHandle(STD_OUTPUT_HANDLE, saved_output); SetConsoleCursorInfo(saved_output, &saved_cursor); if (allocated_console) { FreeConsole(); } }
/* Here we undo the hackery in the setup, and close any handles we know fd_exec doesn't use. */ static void pipe_cleanup (int inpipes[], int outpipes[], HANDLE old_handles[]) { /* Close unnecessary fd's--the ones the child uses */ if (close(inpipes[0]) != 0 || close(outpipes[1]) != 0 /* close the handles we're pretending are our stdin and stdout */ || !CloseHandle(GetStdHandle(STD_INPUT_HANDLE)) || !CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE)) /* now restore the real stdin and stdout */ || !SetStdHandle(STD_INPUT_HANDLE, old_handles[0]) || !SetStdHandle(STD_OUTPUT_HANDLE, old_handles[1])) { lose("Failed while doing pipe cleanup for fd_exec"); } }
CL_ConsoleWindow_Generic::CL_ConsoleWindow_Generic( const CL_StringRef &title, int width, int height) { #ifdef WIN32 AllocConsole(); SetConsoleTitle(CL_StringHelp::utf8_to_ucs2(title).c_str()); COORD coord; coord.X = width; coord.Y = height; scrbuf = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); if(scrbuf == INVALID_HANDLE_VALUE) throw CL_Exception("Unable to allocate console screen buffer"); SetStdHandle(STD_OUTPUT_HANDLE, scrbuf); SetConsoleActiveScreenBuffer(scrbuf); SetConsoleScreenBufferSize(scrbuf, coord); #endif }
static VOID SetHandle(UINT Number, HANDLE Handle) { if (Number < 3) SetStdHandle(STD_INPUT_HANDLE - Number, Handle); else ExtraHandles[Number - 3] = Handle; }
void QConsolePrivate::setupStandardIO (DWORD stdHandleId, int targetFd, const char* name, const char* devName) { log ("Opening %s...\n", devName); int fd = open (devName, _O_RDWR | _O_BINARY); if (fd != -1) { if (fd != targetFd) { log ("Opened %s is not at target file descriptor %d, " "duplicating...\n", name, targetFd); if (dup2 (fd, targetFd) == -1) log ("Failed to duplicate file descriptor: errno=%d.\n", errno); if (close (fd) == -1) log ("Failed to close original file descriptor: errno=%d.\n", errno); } else log ("%s opened and assigned to file descriptor %d.\n", devName, fd); if (! SetStdHandle (stdHandleId, (HANDLE) _get_osfhandle (targetFd))) log ("Failed to re-assign %s: error=%08x.\n", name, GetLastError ()); } else log ("Failed to open %s: errno=%d.\n", devName, errno); }
/* Start the reader thread and do all the file handle/descriptor redirection. Returns nonzero on success, zero on error. */ int win_stdin_start_thread(void) { int stdin_fd; int stdin_fmode; assert(stdin_thread == NULL); assert(stdin_pipe_r == NULL); assert(stdin_pipe_w == NULL); assert(thread_stdin_handle == NULL); /* Create the pipe that win_stdin_thread_func writes to. We reassign the read end to be the new stdin that the rest of the program sees. */ if (CreatePipe(&stdin_pipe_r, &stdin_pipe_w, NULL, 0) == 0) return 0; /* Make a copy of the stdin handle to be used by win_stdin_thread_func. It will remain a reference to the the true stdin after we fake stdin to read from the pipe instead. */ if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &thread_stdin_handle, 0, FALSE, DUPLICATE_SAME_ACCESS) == 0) { CloseHandle(stdin_pipe_r); CloseHandle(stdin_pipe_w); return 0; } /* Set the stdin handle to read from the pipe. */ if (SetStdHandle(STD_INPUT_HANDLE, stdin_pipe_r) == 0) { CloseHandle(stdin_pipe_r); CloseHandle(stdin_pipe_w); CloseHandle(thread_stdin_handle); return 0; } /* Need to redirect file descriptor 0 also. _open_osfhandle makes a new file descriptor from an existing handle. */ /* Remember the newline translation mode (_O_TEXT or _O_BINARY), and restore it in the new file descriptor. */ stdin_fmode = _getmode(STDIN_FILENO); stdin_fd = _open_osfhandle((intptr_t) GetStdHandle(STD_INPUT_HANDLE), _O_RDONLY | stdin_fmode); if (stdin_fd == -1) { CloseHandle(stdin_pipe_r); CloseHandle(stdin_pipe_w); CloseHandle(thread_stdin_handle); return 0; } dup2(stdin_fd, STDIN_FILENO); /* Finally, start up the thread. We don't bother keeping a reference to it because it runs until program termination. From here on out all reads from the stdin handle or file descriptor 0 will be reading from the anonymous pipe that is fed by the thread. */ stdin_thread = CreateThread(NULL, 0, win_stdin_thread_func, NULL, 0, NULL); if (stdin_thread == NULL) { CloseHandle(stdin_pipe_r); CloseHandle(stdin_pipe_w); CloseHandle(thread_stdin_handle); return 0; } return 1; }
// set_stdhandle_t set_stdhandle_t::set_stdhandle_t( DWORD kind, HANDLE handle ) : m_kind( kind ), m_save_handle( GetStdHandle( kind ) ) { if( m_save_handle==INVALID_HANDLE_VALUE ) throw os_error_t( "set_stdhandle_t::set_stdhandle_t: GetStdHandle() failed" ); if( !SetStdHandle( kind, handle ) ) throw os_error_t( "set_stdhandle_t::set_stdhandle_t: SetStdHandle() failed" ); }
VALUE rb_SetStdHandle( VALUE self, VALUE fd, VALUE hConsoleOutput ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); if (SetStdHandle(NUM2UINT(fd), handle)) return NUM2UINT(1); return rb_getWin32Error(); }
static int MnSetupStdHandles(void) { HANDLE hInFile = CreateFile(NULFILE, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hInFile == INVALID_HANDLE_VALUE) { AddToMessageLog(_T("CreateFile")); return -1; } HANDLE hOutFile = CreateFile(NULFILE, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hOutFile == INVALID_HANDLE_VALUE) { AddToMessageLog(_T("CreateFile")); CloseHandle(hInFile); return -1; } HANDLE hErrFile = CreateFile(NULFILE, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hErrFile == INVALID_HANDLE_VALUE) { AddToMessageLog(_T("CreateFile")); CloseHandle(hOutFile); CloseHandle(hInFile); return -1; } if (!SetStdHandle(STD_INPUT_HANDLE, hInFile) || !SetStdHandle(STD_OUTPUT_HANDLE, hOutFile) || !SetStdHandle(STD_ERROR_HANDLE, hErrFile)) { AddToMessageLog(_T("SetStdHandle")); CloseHandle(hErrFile); CloseHandle(hOutFile); CloseHandle(hInFile); return -1; } return 0; }
OutputLogger::~OutputLogger(void) { // Replace fd with it's original details if (fileOld && fd >= 0) { _dup2(_fileno(fileOld),fd); fd = -1; } if (pThread) { // Wait for the thread to exit (the write handle is now invalid so it will have broken the pipe) SDL_WaitThread(pThread,NULL); pThread = NULL; } // Close the read end of the pipe, completely closing the pipe if (fdPipeRead >= 0) { _close(fdPipeRead); fdPipeRead = -1; } // Close the duplicated original file if (fileOld) { std::fclose(fileOld); fileOld = NULL; } // Close the log file if (fileLog) { // In the event that we did a freopen on the handle remove the windows // output std handle #ifdef WIN32 DWORD stdhandle = 0; if (fileLog == stdout) stdhandle = STD_OUTPUT_HANDLE; else if (fileLog == stderr) stdhandle = STD_ERROR_HANDLE; if (stdhandle) SetStdHandle(stdhandle,NULL); #endif // Get the size written to the log file int sizeLog = std::ftell(fileLog); std::fclose(fileLog); fileLog = NULL; // Delete the log file if it was empty if (!sizeLog) std::remove(filenameLog.c_str()); filenameLog = std::string(); } }
static DWORD RunChildProcessCmdl( const char *cmdl, LPPROCESS_INFORMATION pinfo, LPHANDLE readpipe ) { HANDLE cp; HANDLE parent_std_output; HANDLE parent_std_error; HANDLE pipe_input; HANDLE pipe_output; SECURITY_ATTRIBUTES sa; DWORD rc = 0; sa.nLength = sizeof( sa ); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; if( !CreatePipe( &pipe_input, &pipe_output, &sa, 0 ) ) { return( GetLastError() ); } cp = GetCurrentProcess(); DuplicateHandle( cp, GetStdHandle( STD_OUTPUT_HANDLE ), cp, &parent_std_output, 0, TRUE, DUPLICATE_SAME_ACCESS ); DuplicateHandle( cp, GetStdHandle( STD_ERROR_HANDLE ), cp, &parent_std_error, 0, TRUE, DUPLICATE_SAME_ACCESS ); SetStdHandle( STD_OUTPUT_HANDLE, pipe_output ); SetStdHandle( STD_ERROR_HANDLE, pipe_output ); if( !DuplicateHandle( cp, pipe_input, cp, readpipe, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) { rc = GetLastError(); } CloseHandle( pipe_input ); if( rc == 0 ) { STARTUPINFO sinfo; memset( &sinfo, 0, sizeof( sinfo ) ); sinfo.cb = sizeof( sinfo ); if( !CreateProcess( NULL, (LPSTR)cmdl, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, pinfo ) ) { rc = GetLastError(); } } CloseHandle( pipe_output ); SetStdHandle( STD_OUTPUT_HANDLE, parent_std_output ); SetStdHandle( STD_ERROR_HANDLE, parent_std_error ); CloseHandle( parent_std_output ); CloseHandle( parent_std_error ); return( rc ); }
int nt_dup2(int fdorig,int fdcopy) { HANDLE hdup; HANDLE horig = __gOpenFiles[fdorig].handle; if (__gOpenFiles[fdcopy].handle != INVHL) { CloseHandle((HANDLE)__gOpenFiles[fdcopy].handle ); __gOpenFiles[fdcopy].handle = INVHL; __gOpenFiles[fdcopy].flags = 0; } if (!DuplicateHandle(GetCurrentProcess(), horig, GetCurrentProcess(), &hdup, 0, fdcopy<3?TRUE:FALSE, DUPLICATE_SAME_ACCESS)) { errno = GetLastError(); errno = EBADF; return -1; } __gOpenFiles[fdcopy].handle = hdup; __gOpenFiles[fdcopy].flags = __gOpenFiles[fdorig].flags; switch(fdcopy) { case 0: SetStdHandle(STD_INPUT_HANDLE,hdup); break; case 1: SetStdHandle(STD_OUTPUT_HANDLE,hdup); break; case 2: SetStdHandle(STD_ERROR_HANDLE,hdup); break; default: break; } return 0; }
OutputLogger::OutputLogger(FILE *file, const std::string &filename) : fd(-1), fileOld(NULL), filenameLog(filename), fileLog(NULL), fdPipeRead(-1), pThread(NULL) { // Get the underlying file descriptor for the FILE stream fd = _fileno(file); // Probably on windows and there is no stdout/stderr in Subsystem Windows if (fd < 0) { fileLog = freopen(filenameLog.c_str(),"w",file); #ifdef WIN32 DWORD stdhandle = 0; if (fileLog == stdout) stdhandle = STD_OUTPUT_HANDLE; else if (fileLog == stderr) stdhandle = STD_ERROR_HANDLE; if (stdhandle) SetStdHandle(stdhandle,(HANDLE)_get_osfhandle(_fileno(fileLog))); #endif return; } // Create the pipe int fdsPipe[2]; if (_pipe(fdsPipe,256,_O_BINARY) != 0) { return; } fdPipeRead = fdsPipe[0]; int fdPipeWrite = fdsPipe[1]; // Make sure that buffering is turned off on the incoming file std::setvbuf(file,NULL,_IONBF,0); // Duplicate the fd and create new filestream for it fileOld = _fdopen(_dup(fd),"w"); // If the file was stderr, make sure the new file doesn't have buffering if (fileOld && file == stderr) std::setvbuf(fileOld,NULL,_IONBF,0); // Create the output log file fileLog = std::fopen(filenameLog.c_str(),"w"); // Duplicate pipe write file descriptor and replace original _dup2(fdPipeWrite,fd); // Close the fd for the write end of the pipe _close(fdPipeWrite); fdPipeWrite = -1; // Create the thread pThread = SDL_CreateThread( (int (SDLCALL*)(void*)) &OutputLogger::sThreadMain,this); }
bool DaemonWin32::start() { setlocale(LC_CTYPE, ""); SetConsoleCP(1251); SetConsoleOutputCP(1251); setlocale(LC_ALL, "Russian"); #ifdef WIN32_APP if (!i2p::win32::StartWin32App ()) return false; // override log i2p::config::SetOption("log", std::string ("file")); #endif bool ret = Daemon_Singleton::start(); if (ret && i2p::log::Logger().GetLogType() == eLogFile) { // TODO: find out where this garbage to console comes from SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); } bool insomnia; i2p::config::GetOption("insomnia", insomnia); if (insomnia) SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); return ret; }
static int _to_descriptor(HANDLE source, void* fd) { intptr_t res = (intptr_t)fd; static const DWORD StdHandleTable[] = { STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE }; if (res < 0 || !(res < 3)) { errno = EINVAL; return -1; } // FIXME: int cygwin_attach_handle_to_fd(char* name, int fd, HANDLE handle, mode_t bin, DWORD myaccess) assert(res < sizeof(StdHandleTable)/sizeof(StdHandleTable[0]) ); return SetStdHandle(StdHandleTable[res], source)? 0 : -1; }
HANDLE GetFileHandle(char *pFilePath) { printf("GetFileHandle(%s)", pFilePath); HANDLE hStdOutFile = GetStdHandle(STD_OUTPUT_HANDLE); if (INVALID_HANDLE_VALUE == hStdOutFile)return INVALID_HANDLE_VALUE; if (!pFilePath)return hStdOutFile; HANDLE hFile = CreateFile(pFilePath,GENERIC_READ | GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL); if(INVALID_HANDLE_VALUE == hFile)return hStdOutFile; if (!SetStdHandle(STD_OUTPUT_HANDLE, hFile)) { CloseHandle(hFile); return hStdOutFile; } return hFile; }
/// Try to set std HANDLE from FILE* static void WINAPI_SetStdHandleFromFile(int type, FILE *file) { int fd; HANDLE handle; fd = _fileno(file); if (fd < 0) { return; } handle = (HANDLE)_get_osfhandle(fd); if (! handle || handle == INVALID_HANDLE_VALUE) { return; } SetStdHandle(type, handle); }
static void app_init_logging() { BOOL outputToConsole = !!wcsstr(GetCommandLine(), L"--console"); if (outputToConsole) { AllocConsole(); freopen("CONOUT$", "wb", stdout); freopen("CONOUT$", "wb", stderr); } else { WCHAR buf[MAX_PATH]; MultiByteToWideChar(CP_UTF8, 0, os_log_path, -1, buf, MAX_PATH); wcscat(buf, L"\\log.txt"); _wfreopen(buf, L"w", stderr); HANDLE hLogFile = (HANDLE) _get_osfhandle(_fileno(stderr)); //HANDLE hLogFile = CreateFile(buf, FILE_ALL_ACCESS, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL); //SetStdHandle(STD_OUTPUT_HANDLE, hLogFile); SetStdHandle(STD_ERROR_HANDLE, hLogFile); } time_t startup_time = time(NULL); struct tm *startup_tm = gmtime(&startup_time); fprintf(stderr, "%04d-%02d-%02d %02d:%02d:%02d LiveReload " LIVERELOAD_VERSION " launched\n", 1900 + startup_tm->tm_year, 1 + startup_tm->tm_mon, startup_tm->tm_mday, startup_tm->tm_hour, startup_tm->tm_min, startup_tm->tm_sec); fflush(stderr); }
VOID IN_PROCESS_APPLICATION::SetCallbackHandles( _In_ PFN_REQUEST_HANDLER request_handler, _In_ PFN_SHUTDOWN_HANDLER shutdown_handler, _In_ PFN_MANAGED_CONTEXT_HANDLER async_completion_handler, _In_ VOID* pvRequstHandlerContext, _In_ VOID* pvShutdownHandlerContext ) { m_RequestHandler = request_handler; m_RequestHandlerContext = pvRequstHandlerContext; m_ShutdownHandler = shutdown_handler; m_ShutdownHandlerContext = pvShutdownHandlerContext; m_AsyncCompletionHandler = async_completion_handler; CloseStdErrHandles(); // Can't check the std err handle as it isn't a critical error SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); // Initialization complete SetEvent(m_pInitalizeEvent); m_fInitialized = TRUE; }
// Redirects stdout/stderr back to the original stdout/stderr. // Note, this will not restore the original handle values returned by GetStdHandle, // rather a duplicated number. This is because the original handle value is invalid // due to dup2 closing the file originally in stdout/stderr HRESULT StdWrapper::StopRedirection() const { // After setting the std handle, we need to set stdout/stderr to the current // output/error handle. FILE * file = _fdopen(m_previousFileDescriptor, "w"); if (file == nullptr) { RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID)); } RETURN_LAST_ERROR_IF(!SetStdHandle(m_stdHandleNumber, reinterpret_cast<HANDLE>(_get_osfhandle(m_previousFileDescriptor)))); if (!m_enableNativeRedirection) { return S_OK; } // Set stdout/stderr to the newly created file output. const auto dup2Result = _dup2(_fileno(file), _fileno(m_stdStream)); if (dup2Result != 0) { RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID)); } if (setvbuf(m_stdStream, nullptr, _IONBF, 0) != 0) { RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID)); } if (fclose(m_redirectedFile) != 0) { RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID)); } return S_OK; }
/*static*/ IProcess* WinProcessImpl::Execute(wxEvtHandler *parent, const wxString& cmd, wxString &errMsg, IProcessCreateFlags flags, const wxString &workingDir, IProcessCallback* cb) { SECURITY_ATTRIBUTES saAttr; BOOL fSuccess; MyDirGuard dg; wxString wd(workingDir); if (workingDir.IsEmpty()) { wd = wxGetCwd(); } wxSetWorkingDirectory( wd ); // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; WinProcessImpl *prc = new WinProcessImpl(parent); prc->m_callback = cb; prc->m_flags = flags; // The steps for redirecting child process's STDOUT: // 1. Save current STDOUT, to be restored later. // 2. Create anonymous pipe to be STDOUT for child process. // 3. Set STDOUT of the parent process to be write handle to // the pipe, so it is inherited by the child process. // 4. Create a noninheritable duplicate of the read handle and // close the inheritable read handle. // Save the handle to the current STDOUT. prc->hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); // Create a pipe for the child process's STDOUT. if ( !CreatePipe( &prc->hChildStdoutRd, &prc->hChildStdoutWr, &saAttr, 0) ) { delete prc; return NULL; } // Set a write handle to the pipe to be STDOUT. if ( !SetStdHandle(STD_OUTPUT_HANDLE, prc->hChildStdoutWr) ) { delete prc; return NULL; } // Create noninheritable read handle and close the inheritable read handle. fSuccess = DuplicateHandle( GetCurrentProcess(), prc->hChildStdoutRd, GetCurrentProcess(), &prc->hChildStdoutRdDup , 0, FALSE, DUPLICATE_SAME_ACCESS ); if ( !fSuccess ) { delete prc; return NULL; } CloseHandle( prc->hChildStdoutRd ); // The steps for redirecting child process's STDERR: // 1. Save current STDERR, to be restored later. // 2. Create anonymous pipe to be STDERR for child process. // 3. Set STDERR of the parent process to be write handle to // the pipe, so it is inherited by the child process. // 4. Create a noninheritable duplicate of the read handle and // close the inheritable read handle. // Save the handle to the current STDERR. prc->hSaveStderr = GetStdHandle(STD_ERROR_HANDLE); // Create a pipe for the child process's STDERR. if ( !CreatePipe( &prc->hChildStderrRd, &prc->hChildStderrWr, &saAttr, 0) ) { delete prc; return NULL; } // Set a write handle to the pipe to be STDERR. if ( !SetStdHandle(STD_ERROR_HANDLE, prc->hChildStderrWr) ) { delete prc; return NULL; } // Create noninheritable read handle and close the inheritable read handle. fSuccess = DuplicateHandle( GetCurrentProcess(), prc->hChildStderrRd, GetCurrentProcess(), &prc->hChildStderrRdDup , 0, FALSE, DUPLICATE_SAME_ACCESS ); if ( !fSuccess ) { delete prc; return NULL; } CloseHandle( prc->hChildStderrRd ); // The steps for redirecting child process's STDIN: // 1. Save current STDIN, to be restored later. // 2. Create anonymous pipe to be STDIN for child process. // 3. Set STDIN of the parent to be the read handle to the // pipe, so it is inherited by the child process. // 4. Create a noninheritable duplicate of the write handle, // and close the inheritable write handle. // Save the handle to the current STDIN. prc->hSaveStdin = GetStdHandle(STD_INPUT_HANDLE); // Create a pipe for the child process's STDIN. if ( !CreatePipe(&prc->hChildStdinRd, &prc->hChildStdinWr, &saAttr, 0) ) { delete prc; return NULL; } // Set a read handle to the pipe to be STDIN. if ( !SetStdHandle(STD_INPUT_HANDLE, prc->hChildStdinRd) ) { delete prc; return NULL; } // Duplicate the write handle to the pipe so it is not inherited. fSuccess = DuplicateHandle(GetCurrentProcess(), prc->hChildStdinWr, GetCurrentProcess(), &prc->hChildStdinWrDup, 0, FALSE, // not inherited DUPLICATE_SAME_ACCESS ); if ( !fSuccess ) { delete prc; return NULL; } CloseHandle(prc->hChildStdinWr); // Execute the child process STARTUPINFO siStartInfo; // Set up members of STARTUPINFO structure. ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; ; siStartInfo.hStdInput = prc->hChildStdinRd; siStartInfo.hStdOutput = prc->hChildStdoutWr; siStartInfo.hStdError = prc->hChildStderrWr; // Set the window to hide siStartInfo.wShowWindow = flags & IProcessCreateConsole ? SW_SHOW : SW_HIDE; DWORD creationFlags = flags & IProcessCreateConsole ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW; if(flags & IProcessCreateWithHiddenConsole) { siStartInfo.wShowWindow = SW_HIDE; creationFlags = CREATE_NEW_CONSOLE|CREATE_NEW_PROCESS_GROUP; } BOOL ret = CreateProcess( NULL, cmd.wchar_str(), // shell line execution command NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited creationFlags, // creation flags NULL, // use parent's environment NULL, // CD to tmp dir &siStartInfo, // STARTUPINFO pointer &prc->piProcInfo); // receives PROCESS_INFORMATION if ( ret ) { prc->dwProcessId = prc->piProcInfo.dwProcessId; } else { int err = GetLastError(); wxUnusedVar(err); delete prc; return NULL; } // After process creation, restore the saved STDIN and STDOUT. if ( !SetStdHandle(STD_INPUT_HANDLE, prc->hSaveStdin) ) { delete prc; return NULL; } if ( !SetStdHandle(STD_OUTPUT_HANDLE, prc->hSaveStdout) ) { delete prc; return NULL; } if ( !SetStdHandle(STD_OUTPUT_HANDLE, prc->hSaveStderr) ) { delete prc; return NULL; } if ( prc->m_flags & IProcessCreateConsole || prc->m_flags & IProcessCreateWithHiddenConsole ) { ConsoleAttacher ca(prc->GetPid()); if ( ca.isAttached ) { freopen("CONOUT$","wb", stdout); // reopen stout handle as console window output freopen("CONOUT$","wb", stderr); // reopen stderr handle as console window output } } prc->SetPid( prc->dwProcessId ); prc->StartReaderThread(); return prc; }
// Function name : LaunchMPDProcess // Description : // Return type : void // Argument : LaunchMPDProcessArg *pArg void LaunchMPDProcess(LaunchMPDProcessArg *pArg) { char pBuffer[4096]; char pszEnv[1024] = ""; char pszDir[MAX_PATH] = "."; char pszCmd[1024] = ""; char pszArg[1024] = ""; char pszCmdLine[4096] = ""; char pszStdinHost[100] = ""; char pszStdoutHost[100] = ""; char pszStderrHost[100] = ""; int nStdinPort = 0, nStdoutPort = 0, nStderrPort = 0; int nGroupID = -1, nGroupRank = -1; char *token; HANDLE hStdin, hStdout, hStderr; HANDLE hStdoutPipeW=NULL, hStderrPipeW = NULL, hStdinPipeR=NULL; HANDLE hStdoutPipeR=NULL, hStdinPipeW=NULL; HANDLE hTempPipe=NULL; STARTUPINFO saInfo; PROCESS_INFORMATION psInfo; void *pEnv=NULL; char pszSavedPath[MAX_PATH] = "."; bool bSuccess = false; int nError; unsigned long nSrcIP; int nSrcPort; LaunchNode *pLaunchNode; //printf("cmd before: %s\n", pArg->pszCommand);fflush(stdout); GetStringOpt(pArg->pszCommand, 'e', pszEnv); GetStringOpt(pArg->pszCommand, 'd', pszDir); GetStringOpt(pArg->pszCommand, 'c', pszCmd); GetStringOpt(pArg->pszCommand, 'a', pszArg); //printf("cmd after : %s\n", pArg->pszCommand);fflush(stdout); //printf("pszArg: %s\n", pszArg);fflush(stdout); if (GetStringOpt(pArg->pszCommand, '0', pBuffer) == 0) { token = strtok(pBuffer, ":"); if (token != NULL) { strcpy(pszStdinHost, token); token = strtok(NULL, ""); if (token != NULL) { nStdinPort = atoi(token); } } } if (GetStringOpt(pArg->pszCommand, '1', pBuffer) == 0) { token = strtok(pBuffer, ":"); if (token != NULL) { strcpy(pszStdoutHost, token); token = strtok(NULL, ""); if (token != NULL) { nStdoutPort = atoi(token); } } } if (GetStringOpt(pArg->pszCommand, '2', pBuffer) == 0) { token = strtok(pBuffer, ":"); if (token != NULL) { strcpy(pszStderrHost, token); token = strtok(NULL, ""); if (token != NULL) { nStderrPort = atoi(token); } } } if (GetStringOpt(pArg->pszCommand, 'g', pBuffer) == 0) nGroupID = atoi(pBuffer); if (GetStringOpt(pArg->pszCommand, 'r', pBuffer) == 0) nGroupRank = atoi(pBuffer); pLaunchNode = pArg->pNode; nSrcIP = pArg->nSrcIP; nSrcPort = pArg->nSrcPort; delete pArg->pszCommand; delete pArg; pArg = NULL; // Create the command line HMODULE hModule = GetModuleHandle(NULL); if (!GetModuleFileName(hModule, pszCmdLine, 4096)) strcpy(pszCmdLine, "mpd.exe"); if (pszCmd[0] == '\"') { if (strlen(pszArg)) sprintf(pBuffer, " -cmd %s -args \"%s\"", pszCmd, pszArg); else sprintf(pBuffer, " -cmd %s", pszCmd); } else { if (strlen(pszArg)) sprintf(pBuffer, " -cmd \"%s\" -args \"%s\"", pszCmd, pszArg); else sprintf(pBuffer, " -cmd \"%s\"", pszCmd); } strcat(pszCmdLine, pBuffer); if (strlen(pszEnv) > 0) { sprintf(pBuffer, " -env \"%s\"", pszEnv); strcat(pszCmdLine, pBuffer); } if (strlen(pszDir) > 0) { sprintf(pBuffer, " -dir \"%s\"", pszDir); strcat(pszCmdLine, pBuffer); } if (nStdinPort != 0) { sprintf(pBuffer, " -0 %s:%d", pszStdinHost, nStdinPort); strcat(pszCmdLine, pBuffer); } if (nStdoutPort != 0) { sprintf(pBuffer, " -1 %s:%d", pszStdoutHost, nStdoutPort); strcat(pszCmdLine, pBuffer); } if (nStderrPort != 0) { sprintf(pBuffer, " -2 %s:%d", pszStderrHost, nStderrPort); strcat(pszCmdLine, pBuffer); } if (nGroupID != -1) { sprintf(pBuffer, " -group %d", nGroupID); strcat(pszCmdLine, pBuffer); } if (nGroupRank != -1) { sprintf(pBuffer, " -rank %d", nGroupRank); strcat(pszCmdLine, pBuffer); } //printf("launching:\n'%s'\n", pszCmdLine); fflush(stdout); WaitForSingleObject(g_hLaunchMutex, INFINITE); SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); // Get and save the current standard handles hStdin = GetStdHandle(STD_INPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE) { nError = GetLastError(); printf("0 GetStdHandle failed for stdin, error %d\n", nError);fflush(stdout); ReleaseMutex(g_hLaunchMutex); return; } hStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdout == INVALID_HANDLE_VALUE) { nError = GetLastError(); printf("0 GetStdHandle failed for stdout, error %d\n", nError);fflush(stdout); ReleaseMutex(g_hLaunchMutex); return; } hStderr = GetStdHandle(STD_ERROR_HANDLE); if (hStderr == INVALID_HANDLE_VALUE) { nError = GetLastError(); printf("0 GetStdHandle failed for stderr, error %d\n", nError);fflush(stdout); ReleaseMutex(g_hLaunchMutex); return; } // Set the security attributes to allow handles to be inherited SECURITY_ATTRIBUTES saAttr; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.lpSecurityDescriptor = NULL; saAttr.bInheritHandle = TRUE; // Create an event to be signalled to abort the mpd child process HANDLE hAbortEvent = CreateEvent(&saAttr, TRUE, FALSE, NULL); sprintf(pBuffer, " -hAbortEvent %u", (int)hAbortEvent); strcat(pszCmdLine, pBuffer); //printf("hAbortEvent: %d\n", (int)hAbortEvent);fflush(stdout); //printf("launching:\n'%s'\n", pszCmdLine); fflush(stdout); // Create pipes for stdin, stdout // Stdout if (!CreatePipe(&hTempPipe, &hStdoutPipeW, &saAttr, 0)) { nError = GetLastError(); goto CLEANUP; } // Make the read end of the stdout pipe not inheritable if (!DuplicateHandle(GetCurrentProcess(), hTempPipe, GetCurrentProcess(), &hStdoutPipeR, 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { nError = GetLastError(); goto CLEANUP; } // Stdin if (!CreatePipe(&hStdinPipeR, &hTempPipe, &saAttr, 0)) { nError = GetLastError(); goto CLEANUP; } // Make the write end of the stdin pipe not inheritable if (!DuplicateHandle(GetCurrentProcess(), hTempPipe, GetCurrentProcess(), &hStdinPipeW, 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { nError = GetLastError(); goto CLEANUP; } // Set stdin, stdout, and stderr to the ends of the pipe the created process will use if (!SetStdHandle(STD_INPUT_HANDLE, hStdinPipeR)) { nError = GetLastError(); goto CLEANUP; } if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdoutPipeW)) { nError = GetLastError(); goto RESTORE_CLEANUP; } if (!SetStdHandle(STD_ERROR_HANDLE, hStdoutPipeW)) { nError = GetLastError(); goto RESTORE_CLEANUP; } // Set up the STARTINFO structure memset(&saInfo, 0, sizeof(STARTUPINFO)); saInfo.cb = sizeof(STARTUPINFO); saInfo.hStdInput = hStdinPipeR; saInfo.hStdOutput = hStdoutPipeW; saInfo.hStdError = hStdoutPipeW; saInfo.dwFlags = STARTF_USESTDHANDLES; if (CreateProcess( NULL, pszCmdLine, NULL, NULL, TRUE, //DETACHED_PROCESS | IDLE_PRIORITY_CLASS, //CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS, CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP, //DETACHED_PROCESS | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP, //CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_SUSPENDED, NULL, //pEnv, NULL, &saInfo, &psInfo)) { CloseHandle(psInfo.hThread); bSuccess = true; } else { nError = GetLastError(); printf("CreateProcess failed for '%s', error %d\n", pszCmdLine, nError); } RESTORE_CLEANUP: // Restore stdin, stdout, stderr if (!SetStdHandle(STD_INPUT_HANDLE, hStdin)) { nError = GetLastError(); printf("SetStdHandle failed to restore stdin, error %d\n", nError); } if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdout)) { nError = GetLastError(); printf("SetStdHandle failed to restore stdout, error %d\n", nError); } if (!SetStdHandle(STD_ERROR_HANDLE, hStderr)) { nError = GetLastError(); printf("SetStdHandle failed to restore stderr, error %d\n", nError); } CLEANUP: CloseHandle(hStdoutPipeW); CloseHandle(hStdinPipeR); if (bSuccess) { MPD_CMD_HANDLE hCmd; CommandData cmd; char *pBuf; ProcessNode *p = new ProcessNode; strcpy(p->pszCmdLine, pszCmdLine); p->nPid = psInfo.dwProcessId; //printf("%d\n", psInfo.dwProcessId);fflush(stdout); p->nGroupID = nGroupID; p->hAbortEvent = hAbortEvent; p->hProcess = psInfo.hProcess; p->pNext = g_pProcessList; g_pProcessList = p; cmd.nCommand = MPD_CMD_LAUNCH_RET; pBuf = cmd.pCommandBuffer; *((unsigned long *)pBuf) = nSrcIP; pBuf = pBuf + sizeof(unsigned long); *((int *)pBuf) = nSrcPort; pBuf = pBuf + sizeof(int); *((LaunchNode **)pBuf) = pLaunchNode; pBuf = pBuf + sizeof(LaunchNode *); *((DWORD*)pBuf) = psInfo.dwProcessId; cmd.hCmd.nBufferLength = sizeof(unsigned long) + sizeof(int) + sizeof(LaunchNode*) + sizeof(DWORD); hCmd = InsertCommand(cmd); WaitForCommand(hCmd); ReleaseMutex(g_hLaunchMutex); // Tell everyone on the ring that the load on this node has increased by one process. cmd.nCommand = MPD_CMD_INCREMENT; cmd.hCmd.nBufferLength = 0; //printf("Inserting INCREMENT command.\n");fflush(stdout); hCmd = InsertCommand(cmd); WaitForCommand(hCmd); TerminalClientThreadArg *pArg = new TerminalClientThreadArg; pArg->hInput = hStdoutPipeR; pArg->hOutput = hStdinPipeW; TerminalClientThread(pArg); // The process should already have exited causing the TerminalClientThread function to return. WaitForSingleObject(psInfo.hProcess, 1000); // Remove the process handle from the list by setting it to NULL WaitForSingleObject(g_hLaunchMutex, 10000); p = g_pProcessList; while (p != NULL) { if (p->hProcess == psInfo.hProcess) { p->hProcess = NULL; break; } p = p->pNext; } ReleaseMutex(g_hLaunchMutex); // Tell everyone on the ring that the load on this node has decreased by one process. cmd.nCommand = MPD_CMD_DECREMENT; cmd.hCmd.nBufferLength = 0; //printf("Inserting DECREMENT command.\n");fflush(stdout); hCmd = InsertCommand(cmd); WaitForCommand(hCmd); // Send the exit code back cmd.nCommand = MPD_CMD_LAUNCH_EXITCODE; pBuf = cmd.pCommandBuffer; *((unsigned long *)pBuf) = nSrcIP; pBuf = pBuf + sizeof(unsigned long); *((int *)pBuf) = nSrcPort; pBuf = pBuf + sizeof(int); *((LaunchNode **)pBuf) = pLaunchNode; pBuf = pBuf + sizeof(LaunchNode *); GetExitCodeProcess(psInfo.hProcess, (DWORD*)pBuf); //printf("Process exiting, send exit code: %d\n", *(DWORD*)pBuf);fflush(stdout); pBuf = pBuf + sizeof(DWORD); *((int *)pBuf) = nGroupID; pBuf = pBuf + sizeof(int); *((int *)pBuf) = nGroupRank; cmd.hCmd.nBufferLength = sizeof(unsigned long) + sizeof(int) + sizeof(LaunchNode*) + sizeof(DWORD) + sizeof(int) + sizeof(int); hCmd = InsertCommand(cmd); WaitForCommand(hCmd); CloseHandle(psInfo.hProcess); } else { //printf("0\n");fflush(stdout); ReleaseMutex(g_hLaunchMutex); } CloseHandle(hStdoutPipeR); CloseHandle(hStdinPipeW); }