changeset 10317:25cc0021a8d7 v8.0.0054

commit https://github.com/vim/vim/commit/fb63090b62801d718fe7e1f44407358404c08724 Author: Bram Moolenaar <Bram@vim.org> 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)
author Christian Brabandt <cb@256bit.org>
date Sat, 29 Oct 2016 15:00:04 +0200
parents ca4163abc040
children a0279bd5d079
files src/os_win32.c src/version.c
diffstat 2 files changed, 50 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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))
--- 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,