diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-10-29 14:55:00 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-10-29 14:55:00 +0200 |
commit | fb63090b62801d718fe7e1f44407358404c08724 (patch) | |
tree | 1836fbe7b4dc907b300d31935b9421a49df4532c | |
parent | 60ef3e81f4a54d9f7ee617d57021f0811ec8ada5 (diff) | |
download | vim-git-fb63090b62801d718fe7e1f44407358404c08724.tar.gz |
patch 8.0.0054v8.0.0054
Problem: On Windows job_stop() stops cmd.exe, not the processes it runs.
(Linwei)
Solution: Iterate over all processes and terminate the one where the parent
is the job process. Now only when there is no job object.
(Yasuhiro Matsumoto, closes #1203)
-rw-r--r-- | src/os_win32.c | 50 | ||||
-rw-r--r-- | src/version.c | 2 |
2 files changed, 50 insertions, 2 deletions
diff --git a/src/os_win32.c b/src/os_win32.c index d52beb886..9fcb054d0 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -50,6 +50,10 @@ # endif #endif +#ifdef FEAT_JOB_CHANNEL +# include <tlhelp32.h> +#endif + #ifdef __MINGW32__ # ifndef FROM_LEFT_1ST_BUTTON_PRESSED # define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001 @@ -5020,6 +5024,48 @@ mch_detect_ended_job(job_T *job_list) return NULL; } + static BOOL +terminate_all(HANDLE process, int code) +{ + PROCESSENTRY32 pe; + HANDLE h = INVALID_HANDLE_VALUE; + DWORD pid = GetProcessId(process); + + if (pid != 0) + { + h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (h != INVALID_HANDLE_VALUE) + { + pe.dwSize = sizeof(PROCESSENTRY32); + if (!Process32First(h, &pe)) + goto theend; + + do + { + if (pe.th32ParentProcessID == pid) + { + HANDLE ph = OpenProcess( + PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID); + if (ph != NULL) + { + terminate_all(ph, code); + CloseHandle(ph); + } + } + } while (Process32Next(h, &pe)); + + CloseHandle(h); + } + } + +theend: + return TerminateProcess(process, code); +} + +/* + * Send a (deadly) signal to "job". + * Return FAIL if it didn't work. + */ int mch_stop_job(job_T *job, char_u *how) { @@ -5027,10 +5073,10 @@ mch_stop_job(job_T *job, char_u *how) if (STRCMP(how, "term") == 0 || STRCMP(how, "kill") == 0 || *how == NUL) { + /* deadly signal */ 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; + return terminate_all(job->jv_proc_info.hProcess, 0) ? OK : FAIL; } if (!AttachConsole(job->jv_proc_info.dwProcessId)) diff --git a/src/version.c b/src/version.c index 47c65d6e3..68aff327f 100644 --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 54, +/**/ 53, /**/ 52, |