CmdLineOptions::CmdLineOptions(std::string const &program_description, std::string const &additional_args) : programDescription_(program_description), errorStream_(std::cerr), stdStream_(std::cout), parserResultHandler_() { add_switch(HELP_SWITCH_NAME, "Show program help.", false); // Default fail function. parserResultHandler_ = [this](StringList const &unknownInput, StringList const &missingOptions, StringList const &emptyOptions, StringList const &invalidOptions) { for (std::string const &name : emptyOptions) { ErrorPrinter(errorStream_) << "option requires an argument: " << name; } for (std::string const &name : invalidOptions) { ErrorPrinter(errorStream_) << "invalid argument: " << name << " = " << this->get_option(name); } for (std::string const &name : missingOptions) { ErrorPrinter(errorStream_) << "option is required: " << name; } if (!missingOptions.empty() || !invalidOptions.empty() || !emptyOptions.empty()) { exit(EXIT_FAILURE); } }; }
BOOL createChildProcess(char *scriptFile, HANDLE *hChildStdoutWr) { PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bFuncRetn = FALSE; //DebugBreak(); // Set up members of the PROCESS_INFORMATION structure. ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); // Set up members of the STARTUPINFO structure. ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.dwFlags = STARTF_USESTDHANDLES; siStartInfo.hStdInput = 0; siStartInfo.hStdOutput = hChildStdoutWr; siStartInfo.hStdError = hChildStdoutWr; PrintEvent(_T(scriptFile)); // Create the child process. bFuncRetn = CreateProcess(NULL, scriptFile, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // no creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION if (bFuncRetn == 0) { ErrorPrinter(_T("Could Not Create Process"), GetLastError()); errorExit("CreateProcess failed"); return 0; } else { CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); return bFuncRetn; } }
int executeJavaCommand(char *childExecutorFile, int iVerbose, int iLauncherReturn, char *displayName) { SECURITY_ATTRIBUTES saAttr; BOOL fSuccess; PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bFuncRetn = FALSE; DWORD dwWritten; int ii=0; DWORD dwFlag, dwRet; HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup; char *commandSyncStart = "STARTOFCOMMAND"; char *commandSyncEnd = "ENDOFCOMMAND"; HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); char chBuff[BUFSIZ]; char *startChar; // 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. // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // Create a pipe for the child process's STDIN. if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) errorExit("Stdin pipe creation failed"); // Duplicate the write handle to the pipe so it is not inherited. fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE, // not inherited DUPLICATE_SAME_ACCESS); if (! fSuccess) errorExit("DuplicateHandle failed"); CloseHandle(hChildStdinWr); // Now create the child process. // Set up members of the PROCESS_INFORMATION structure. ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); // Set up members of the STARTUPINFO structure. ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.lpReserved = 0; siStartInfo.lpDesktop = NULL; siStartInfo.lpTitle = displayName; siStartInfo.dwX = 0; siStartInfo.dwY = 0; siStartInfo.dwXSize = 0; siStartInfo.dwYSize = 0; siStartInfo.dwXCountChars = 0; siStartInfo.dwYCountChars = 0; siStartInfo.dwFillAttribute = 0; siStartInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; siStartInfo.wShowWindow = SW_SHOWDEFAULT; siStartInfo.cbReserved2 = 0; siStartInfo.lpReserved2 = 0; siStartInfo.hStdInput = hChildStdinRd; siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); siStartInfo.hStdError = GetStdHandle(STD_OUTPUT_HANDLE); if (getDebug()) { printf("\n\n*** Executing ->%s<-\n", childExecutorFile); fflush(stdout); } // create console for verbose mode if (iVerbose) { dwFlag=CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP; } else { dwFlag=CREATE_NEW_PROCESS_GROUP; } // Create the child process. bFuncRetn=CreateProcess(NULL, childExecutorFile, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited dwFlag, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION //printf("\n*** Child Process ID = %s\n", piProcInfo.dwProcessId); if (bFuncRetn == 0) { ErrorPrinter(_T("Could Not Create Process"), GetLastError()); errorExit("CreateProcess for java command failed"); return 0; } if (getDebug()) printf("\n*** Writing to Child process' input using delimiter '%s'\n", delimiter); fflush(stdout); // Write to pipe that is the standard input for a child process. // write out start of command WriteFile(hChildStdinWrDup, commandSyncStart, strlen(commandSyncStart), &dwWritten, NULL); WriteFile(hChildStdinWrDup, delimiter, 1, &dwWritten, NULL); while (commandLine[ii] != NULL) { WriteFile(hChildStdinWrDup, commandLine[ii], strlen(commandLine[ii]), &dwWritten, NULL); WriteFile(hChildStdinWrDup, delimiter, 1, &dwWritten, NULL); ii++; } // writeout end command WriteFile(hChildStdinWrDup, commandSyncEnd, strlen(commandSyncEnd), &dwWritten, NULL); WriteFile(hChildStdinWrDup, delimiter, 1, &dwWritten, NULL); // write out identity information that should be on the stdin WriteFile(hChildStdinWrDup, "IDENTITYINFORMATION", 19, &dwWritten, NULL); WriteFile(hChildStdinWrDup, delimiter, 1, &dwWritten, NULL); while (fgets(chBuff, BUFSIZ, stdin) != NULL) { //printf("%s", buff); if(getDebug()) { // send string to stdout printf("\n\n\n>>STDIN Number Read in: %d - %s", strlen(chBuff), chBuff); } // parse for carrage return startChar=strtok(chBuff, "\n"); while (startChar != NULL) { if(getDebug()) { // send string to pipe for child process printf("Writing Identity element to input pipe - %s", startChar); } WriteFile(hChildStdinWrDup, startChar, strlen(startChar), &dwWritten, NULL); WriteFile(hChildStdinWrDup, delimiter, 1, &dwWritten, NULL); // get next token, if exists startChar=strtok(NULL, "\n"); } } // Close the pipe handle so the child process stops reading. if (! CloseHandle(hChildStdinWrDup)) { errorExit("Close pipe failed"); } if (iVerbose || iLauncherReturn) { // Wait until process exits. WaitForSingleObject(piProcInfo.hProcess, INFINITE); GetExitCodeProcess(piProcInfo.hProcess, &dwRet); if(getDebug()) printf("\nChildProcess returned with and exit code = %d\n", dwRet); fflush(stdout); } // need to detach parent from child return dwRet; }