# HG changeset patch # User Christian Brabandt # Date 1477746004 -7200 # Node ID 25cc0021a8d72d1d9eea0a63bf5436cbedb25787 # Parent ca4163abc0404cadca614184e14e3da51b3b347f commit https://github.com/vim/vim/commit/fb63090b62801d718fe7e1f44407358404c08724 Author: Bram Moolenaar Date: Sat Oct 29 14:55:00 2016 +0200 patch 8.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) diff --git a/src/os_win32.c b/src/os_win32.c --- a/src/os_win32.c +++ b/src/os_win32.c @@ -50,6 +50,10 @@ # endif #endif +#ifdef FEAT_JOB_CHANNEL +# include +#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 --- 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,