5050# endif
5151#endif
5252
53- #ifdef FEAT_JOB_CHANNEL
54- # include <tlhelp32.h>
55- #endif
56-
5753#ifdef __MINGW32__
5854# ifndef FROM_LEFT_1ST_BUTTON_PRESSED
5955# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001
@@ -4800,6 +4796,7 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
48004796{
48014797 STARTUPINFO si ;
48024798 PROCESS_INFORMATION pi ;
4799+ HANDLE jo ;
48034800 SECURITY_ATTRIBUTES saAttr ;
48044801 channel_T * channel = NULL ;
48054802 HANDLE ifd [2 ];
@@ -4824,6 +4821,13 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
48244821 efd [0 ] = INVALID_HANDLE_VALUE ;
48254822 efd [1 ] = INVALID_HANDLE_VALUE ;
48264823
4824+ jo = CreateJobObject (NULL , NULL );
4825+ if (jo == NULL )
4826+ {
4827+ job -> jv_status = JOB_FAILED ;
4828+ goto failed ;
4829+ }
4830+
48274831 ZeroMemory (& pi , sizeof (pi ));
48284832 ZeroMemory (& si , sizeof (si ));
48294833 si .cb = sizeof (si );
@@ -4908,17 +4912,28 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
49084912 }
49094913
49104914 if (!vim_create_process (cmd , TRUE,
4915+ CREATE_SUSPENDED |
49114916 CREATE_DEFAULT_ERROR_MODE |
49124917 CREATE_NEW_PROCESS_GROUP |
49134918 CREATE_NEW_CONSOLE ,
49144919 & si , & pi ))
49154920 {
4921+ CloseHandle (jo );
49164922 job -> jv_status = JOB_FAILED ;
49174923 goto failed ;
49184924 }
49194925
4926+ if (!AssignProcessToJobObject (jo , pi .hProcess ))
4927+ {
4928+ /* if failing, switch the way to terminate
4929+ * process with TerminateProcess. */
4930+ CloseHandle (jo );
4931+ jo = NULL ;
4932+ }
4933+ ResumeThread (pi .hThread );
49204934 CloseHandle (pi .hThread );
49214935 job -> jv_proc_info = pi ;
4936+ job -> jv_job_object = jo ;
49224937 job -> jv_status = JOB_STARTED ;
49234938
49244939 CloseHandle (ifd [0 ]);
@@ -5005,52 +5020,17 @@ mch_detect_ended_job(job_T *job_list)
50055020 return NULL ;
50065021}
50075022
5008- static BOOL
5009- terminate_all (HANDLE process , int code )
5010- {
5011- PROCESSENTRY32 pe ;
5012- HANDLE h = INVALID_HANDLE_VALUE ;
5013- DWORD pid = GetProcessId (process );
5014-
5015- if (pid != 0 )
5016- {
5017- h = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS , 0 );
5018- if (h == INVALID_HANDLE_VALUE )
5019- goto theend ;
5020-
5021- pe .dwSize = sizeof (PROCESSENTRY32 );
5022- if (Process32First (h , & pe ))
5023- {
5024- do
5025- {
5026- if (pe .th32ParentProcessID == pid )
5027- {
5028- HANDLE ph = OpenProcess (
5029- PROCESS_ALL_ACCESS , FALSE, pe .th32ProcessID );
5030- if (ph != NULL )
5031- {
5032- terminate_all (ph , code );
5033- CloseHandle (ph );
5034- }
5035- }
5036- } while (Process32Next (h , & pe ));
5037- }
5038-
5039- CloseHandle (h );
5040- }
5041-
5042- theend :
5043- return TerminateProcess (process , code );
5044- }
5045-
50465023 int
50475024mch_stop_job (job_T * job , char_u * how )
50485025{
50495026 int ret ;
50505027
50515028 if (STRCMP (how , "term" ) == 0 || STRCMP (how , "kill" ) == 0 || * how == NUL )
50525029 {
5053- return terminate_all (job -> jv_proc_info .hProcess , 0 ) ? OK : FAIL ;
5030+ if (job -> jv_job_object != NULL )
5031+ return TerminateJobObject (job -> jv_job_object , 0 ) ? OK : FAIL ;
5032+ else
5033+ return TerminateProcess (job -> jv_proc_info .hProcess , 0 ) ? OK : FAIL ;
50545034 }
50555035
50565036 if (!AttachConsole (job -> jv_proc_info .dwProcessId ))
@@ -5071,6 +5051,8 @@ mch_clear_job(job_T *job)
50715051{
50725052 if (job -> jv_status != JOB_FAILED )
50735053 {
5054+ if (job -> jv_job_object != NULL )
5055+ CloseHandle (job -> jv_job_object );
50745056 CloseHandle (job -> jv_proc_info .hProcess );
50755057 }
50765058}
0 commit comments