static foreign_t process_create(term_t exe, term_t options) { p_options info; int rc = FALSE; memset(&info, 0, sizeof(info)); if ( !get_exe(exe, &info) ) goto out; if ( !parse_options(options, &info) ) goto out; if ( !create_pipes(&info) ) goto out; rc = do_create_process(&info); out: free_options(&info); return rc; }
DWORD create_process(const CharType* application, CharType* command_line) { DWORD exit_status; typename startupinfo<CharType>::type si; si.cb = sizeof(si); si.lpReserved = NULL; si.lpDesktop = NULL; si.lpTitle = NULL; si.dwX = 0; si.dwY = 0; si.dwXSize = 0; si.dwYSize = 0; si.dwXCountChars = 0; si.dwYCountChars = 0; si.dwFillAttribute = 0; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // Remove STARTF_USESTDHANDLES to show stdout si.wShowWindow = SW_HIDE; si.cbReserved2 = 0; si.lpReserved2 = NULL; si.hStdInput = INVALID_HANDLE_VALUE; #if FREELAN_DEBUG si.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); #else si.hStdOutput = INVALID_HANDLE_VALUE; #endif si.hStdError = INVALID_HANDLE_VALUE; PROCESS_INFORMATION pi; #if FREELAN_DEBUG output(command_line); #endif if (!do_create_process(application, command_line, si, pi)) { throw boost::system::system_error(::GetLastError(), boost::system::system_category()); } handle_closer thread_closer(pi.hThread); handle_closer process_closer(pi.hProcess); DWORD wait_result = ::WaitForSingleObject(pi.hProcess, INFINITE); switch (wait_result) { case WAIT_OBJECT_0: { DWORD exit_code = 0; if (::GetExitCodeProcess(pi.hProcess, &exit_code)) { exit_status = static_cast<int>(exit_code); } else { throw boost::system::system_error(::GetLastError(), boost::system::system_category()); } break; } default: { throw boost::system::system_error(::GetLastError(), boost::system::system_category()); } } return exit_status; }