diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-02-12 19:30:26 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-02-12 19:30:26 +0100 |
commit | 76467dfcafcf295fd987f712730774c6f55317d3 (patch) | |
tree | 9a841fa293b8dd6ee0c8170451f45c4d1ab13abb /src/os_win32.c | |
parent | 7c29f387819b5817b003d2ba73e2b5cf3cb3d0dd (diff) | |
download | vim-76467dfcafcf295fd987f712730774c6f55317d3.zip |
patch 7.4.1306
Problem: Job control doesn't work well on MS-Windows.
Solution: Various fixes. (Ken Takata, Ozaki Kiichi , Yukihiro Nakadaira,
Yasuhiro Matsumoto)
Diffstat (limited to 'src/os_win32.c')
-rw-r--r-- | src/os_win32.c | 76 |
1 files changed, 62 insertions, 14 deletions
diff --git a/src/os_win32.c b/src/os_win32.c index 5841d135d..cc5fc3dee 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -5038,19 +5038,44 @@ mch_start_job(char *cmd, job_T *job) { STARTUPINFO si; PROCESS_INFORMATION pi; + HANDLE jo; + jo = CreateJobObject(NULL, NULL); + if (jo == NULL) + { + job->jv_status = JOB_FAILED; + return; + } + + ZeroMemory(&pi, sizeof(pi)); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; if (!vim_create_process(cmd, FALSE, + CREATE_SUSPENDED | CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_PROCESS_GROUP | - CREATE_NO_WINDOW, + CREATE_NEW_CONSOLE, &si, &pi)) + { + CloseHandle(jo); job->jv_status = JOB_FAILED; + } else { - job->jv_pi = pi; + if (!AssignProcessToJobObject(jo, pi.hProcess)) + { + /* if failing, switch the way to terminate + * process with TerminateProcess. */ + CloseHandle(jo); + jo = NULL; + } + ResumeThread(pi.hThread); + CloseHandle(job->jv_proc_info.hThread); + job->jv_proc_info = pi; + job->jv_job_object = jo; job->jv_status = JOB_STARTED; } } @@ -5060,12 +5085,10 @@ mch_job_status(job_T *job) { DWORD dwExitCode = 0; - if (!GetExitCodeProcess(job->jv_pi.hProcess, &dwExitCode)) - return "dead"; - if (dwExitCode != STILL_ACTIVE) + if (!GetExitCodeProcess(job->jv_proc_info.hProcess, &dwExitCode) + || dwExitCode != STILL_ACTIVE) { - CloseHandle(job->jv_pi.hProcess); - CloseHandle(job->jv_pi.hThread); + job->jv_status = JOB_ENDED; return "dead"; } return "run"; @@ -5074,14 +5097,39 @@ mch_job_status(job_T *job) int mch_stop_job(job_T *job, char_u *how) { + int ret = 0; + int ctrl_c = STRCMP(how, "int") == 0; + if (STRCMP(how, "kill") == 0) - TerminateProcess(job->jv_pi.hProcess, 0); - else - return GenerateConsoleCtrlEvent( - STRCMP(how, "hup") == 0 ? - CTRL_BREAK_EVENT : CTRL_C_EVENT, - job->jv_pi.dwProcessId) ? OK : FAIL; - return OK; + { + if (job->jv_job_object != NULL) + return TerminateJobObject(job->jv_job_object, 0) ? OK : FAIL; + else + return TerminateProcess(job->jv_proc_info.hProcess, 0) ? OK : FAIL; + } + + if (!AttachConsole(job->jv_proc_info.dwProcessId)) + return FAIL; + ret = GenerateConsoleCtrlEvent( + ctrl_c ? CTRL_C_EVENT : CTRL_BREAK_EVENT, + job->jv_proc_info.dwProcessId) + ? OK : FAIL; + FreeConsole(); + return ret; +} + +/* + * Clear the data related to "job". + */ + void +mch_clear_job(job_T *job) +{ + if (job->jv_status != JOB_FAILED) + { + if (job->jv_job_object != NULL) + CloseHandle(job->jv_job_object); + CloseHandle(job->jv_proc_info.hProcess); + } } #endif |