]> granicus.if.org Git - vim/commitdiff
patch 8.0.0048 v8.0.0048
authorBram Moolenaar <Bram@vim.org>
Thu, 27 Oct 2016 14:46:53 +0000 (16:46 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 27 Oct 2016 14:46:53 +0000 (16:46 +0200)
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. (Yasuhiro Matsumoto, closes #1184)

src/os_win32.c
src/structs.h
src/version.c

index d52beb8869a5add503f6cef2841bcc3ceaf85e3d..fca29f80d7509d597337982c93ad5cd73689e2a3 100644 (file)
 # 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
@@ -4796,7 +4800,6 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
 {
     STARTUPINFO                si;
     PROCESS_INFORMATION        pi;
-    HANDLE             jo;
     SECURITY_ATTRIBUTES saAttr;
     channel_T          *channel = NULL;
     HANDLE             ifd[2];
@@ -4821,13 +4824,6 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
     efd[0] = INVALID_HANDLE_VALUE;
     efd[1] = INVALID_HANDLE_VALUE;
 
-    jo = CreateJobObject(NULL, NULL);
-    if (jo == NULL)
-    {
-       job->jv_status = JOB_FAILED;
-       goto failed;
-    }
-
     ZeroMemory(&pi, sizeof(pi));
     ZeroMemory(&si, sizeof(si));
     si.cb = sizeof(si);
@@ -4912,28 +4908,17 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
     }
 
     if (!vim_create_process(cmd, TRUE,
-           CREATE_SUSPENDED |
            CREATE_DEFAULT_ERROR_MODE |
            CREATE_NEW_PROCESS_GROUP |
            CREATE_NEW_CONSOLE,
            &si, &pi))
     {
-       CloseHandle(jo);
        job->jv_status = JOB_FAILED;
        goto failed;
     }
 
-    if (!AssignProcessToJobObject(jo, pi.hProcess))
-    {
-       /* if failing, switch the way to terminate
-        * process with TerminateProcess. */
-       CloseHandle(jo);
-       jo = NULL;
-    }
-    ResumeThread(pi.hThread);
     CloseHandle(pi.hThread);
     job->jv_proc_info = pi;
-    job->jv_job_object = jo;
     job->jv_status = JOB_STARTED;
 
     CloseHandle(ifd[0]);
@@ -5020,6 +5005,44 @@ 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)
+           goto theend;
+
+       pe.dwSize = sizeof(PROCESSENTRY32);
+       if (Process32First(h, &pe))
+       {
+           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);
+}
+
     int
 mch_stop_job(job_T *job, char_u *how)
 {
@@ -5027,10 +5050,7 @@ mch_stop_job(job_T *job, char_u *how)
 
     if (STRCMP(how, "term") == 0 || STRCMP(how, "kill") == 0 || *how == NUL)
     {
-       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))
@@ -5051,8 +5071,6 @@ 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);
     }
 }
index 7a4d7fbe42742d639b05c62d398a47777e9da78a..bb0fc3a5238b7e5383a1dadaf53e65793d944de3 100644 (file)
@@ -1437,7 +1437,6 @@ struct jobvar_S
 #endif
 #ifdef WIN32
     PROCESS_INFORMATION        jv_proc_info;
-    HANDLE             jv_job_object;
 #endif
     jobstatus_T        jv_status;
     char_u     *jv_stoponexit; /* allocated */
index 001c74098a02cd20504d00e2cfabb50d7d68f33f..81de3d0471d3c73abbccac339ec8dd6edc3cf0f8 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    48,
 /**/
     47,
 /**/