@@ -5038,19 +5038,44 @@ mch_start_job(char *cmd, job_T *job)
50385038{
50395039 STARTUPINFO si ;
50405040 PROCESS_INFORMATION pi ;
5041+ HANDLE jo ;
50415042
5043+ jo = CreateJobObject (NULL , NULL );
5044+ if (jo == NULL )
5045+ {
5046+ job -> jv_status = JOB_FAILED ;
5047+ return ;
5048+ }
5049+
5050+ ZeroMemory (& pi , sizeof (pi ));
50425051 ZeroMemory (& si , sizeof (si ));
50435052 si .cb = sizeof (si );
5053+ si .dwFlags = STARTF_USESHOWWINDOW ;
5054+ si .wShowWindow = SW_HIDE ;
50445055
50455056 if (!vim_create_process (cmd , FALSE,
5057+ CREATE_SUSPENDED |
50465058 CREATE_DEFAULT_ERROR_MODE |
50475059 CREATE_NEW_PROCESS_GROUP |
5048- CREATE_NO_WINDOW ,
5060+ CREATE_NEW_CONSOLE ,
50495061 & si , & pi ))
5062+ {
5063+ CloseHandle (jo );
50505064 job -> jv_status = JOB_FAILED ;
5065+ }
50515066 else
50525067 {
5053- job -> jv_pi = pi ;
5068+ if (!AssignProcessToJobObject (jo , pi .hProcess ))
5069+ {
5070+ /* if failing, switch the way to terminate
5071+ * process with TerminateProcess. */
5072+ CloseHandle (jo );
5073+ jo = NULL ;
5074+ }
5075+ ResumeThread (pi .hThread );
5076+ CloseHandle (job -> jv_proc_info .hThread );
5077+ job -> jv_proc_info = pi ;
5078+ job -> jv_job_object = jo ;
50545079 job -> jv_status = JOB_STARTED ;
50555080 }
50565081}
@@ -5060,12 +5085,10 @@ mch_job_status(job_T *job)
50605085{
50615086 DWORD dwExitCode = 0 ;
50625087
5063- if (!GetExitCodeProcess (job -> jv_pi .hProcess , & dwExitCode ))
5064- return "dead" ;
5065- if (dwExitCode != STILL_ACTIVE )
5088+ if (!GetExitCodeProcess (job -> jv_proc_info .hProcess , & dwExitCode )
5089+ || dwExitCode != STILL_ACTIVE )
50665090 {
5067- CloseHandle (job -> jv_pi .hProcess );
5068- CloseHandle (job -> jv_pi .hThread );
5091+ job -> jv_status = JOB_ENDED ;
50695092 return "dead" ;
50705093 }
50715094 return "run" ;
@@ -5074,14 +5097,39 @@ mch_job_status(job_T *job)
50745097 int
50755098mch_stop_job (job_T * job , char_u * how )
50765099{
5100+ int ret = 0 ;
5101+ int ctrl_c = STRCMP (how , "int" ) == 0 ;
5102+
50775103 if (STRCMP (how , "kill" ) == 0 )
5078- TerminateProcess (job -> jv_pi .hProcess , 0 );
5079- else
5080- return GenerateConsoleCtrlEvent (
5081- STRCMP (how , "hup" ) == 0 ?
5082- CTRL_BREAK_EVENT : CTRL_C_EVENT ,
5083- job -> jv_pi .dwProcessId ) ? OK : FAIL ;
5084- return OK ;
5104+ {
5105+ if (job -> jv_job_object != NULL )
5106+ return TerminateJobObject (job -> jv_job_object , 0 ) ? OK : FAIL ;
5107+ else
5108+ return TerminateProcess (job -> jv_proc_info .hProcess , 0 ) ? OK : FAIL ;
5109+ }
5110+
5111+ if (!AttachConsole (job -> jv_proc_info .dwProcessId ))
5112+ return FAIL ;
5113+ ret = GenerateConsoleCtrlEvent (
5114+ ctrl_c ? CTRL_C_EVENT : CTRL_BREAK_EVENT ,
5115+ job -> jv_proc_info .dwProcessId )
5116+ ? OK : FAIL ;
5117+ FreeConsole ();
5118+ return ret ;
5119+ }
5120+
5121+ /*
5122+ * Clear the data related to "job".
5123+ */
5124+ void
5125+ mch_clear_job (job_T * job )
5126+ {
5127+ if (job -> jv_status != JOB_FAILED )
5128+ {
5129+ if (job -> jv_job_object != NULL )
5130+ CloseHandle (job -> jv_job_object );
5131+ CloseHandle (job -> jv_proc_info .hProcess );
5132+ }
50855133}
50865134#endif
50875135
0 commit comments