Skip to content

Commit a350bab

Browse files
committed
patch 8.0.0048
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)
1 parent 50e5376 commit a350bab

3 files changed

Lines changed: 45 additions & 26 deletions

File tree

src/os_win32.c

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
# endif
5151
#endif
5252

53+
#ifdef FEAT_JOB_CHANNEL
54+
# include <tlhelp32.h>
55+
#endif
56+
5357
#ifdef __MINGW32__
5458
# ifndef FROM_LEFT_1ST_BUTTON_PRESSED
5559
# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001
@@ -4796,7 +4800,6 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
47964800
{
47974801
STARTUPINFO si;
47984802
PROCESS_INFORMATION pi;
4799-
HANDLE jo;
48004803
SECURITY_ATTRIBUTES saAttr;
48014804
channel_T *channel = NULL;
48024805
HANDLE ifd[2];
@@ -4821,13 +4824,6 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
48214824
efd[0] = INVALID_HANDLE_VALUE;
48224825
efd[1] = INVALID_HANDLE_VALUE;
48234826

4824-
jo = CreateJobObject(NULL, NULL);
4825-
if (jo == NULL)
4826-
{
4827-
job->jv_status = JOB_FAILED;
4828-
goto failed;
4829-
}
4830-
48314827
ZeroMemory(&pi, sizeof(pi));
48324828
ZeroMemory(&si, sizeof(si));
48334829
si.cb = sizeof(si);
@@ -4912,28 +4908,17 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
49124908
}
49134909

49144910
if (!vim_create_process(cmd, TRUE,
4915-
CREATE_SUSPENDED |
49164911
CREATE_DEFAULT_ERROR_MODE |
49174912
CREATE_NEW_PROCESS_GROUP |
49184913
CREATE_NEW_CONSOLE,
49194914
&si, &pi))
49204915
{
4921-
CloseHandle(jo);
49224916
job->jv_status = JOB_FAILED;
49234917
goto failed;
49244918
}
49254919

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);
49344920
CloseHandle(pi.hThread);
49354921
job->jv_proc_info = pi;
4936-
job->jv_job_object = jo;
49374922
job->jv_status = JOB_STARTED;
49384923

49394924
CloseHandle(ifd[0]);
@@ -5020,17 +5005,52 @@ mch_detect_ended_job(job_T *job_list)
50205005
return NULL;
50215006
}
50225007

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+
50235046
int
50245047
mch_stop_job(job_T *job, char_u *how)
50255048
{
50265049
int ret;
50275050

50285051
if (STRCMP(how, "term") == 0 || STRCMP(how, "kill") == 0 || *how == NUL)
50295052
{
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;
5053+
return terminate_all(job->jv_proc_info.hProcess, 0) ? OK : FAIL;
50345054
}
50355055

50365056
if (!AttachConsole(job->jv_proc_info.dwProcessId))
@@ -5051,8 +5071,6 @@ mch_clear_job(job_T *job)
50515071
{
50525072
if (job->jv_status != JOB_FAILED)
50535073
{
5054-
if (job->jv_job_object != NULL)
5055-
CloseHandle(job->jv_job_object);
50565074
CloseHandle(job->jv_proc_info.hProcess);
50575075
}
50585076
}

src/structs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,6 @@ struct jobvar_S
14371437
#endif
14381438
#ifdef WIN32
14391439
PROCESS_INFORMATION jv_proc_info;
1440-
HANDLE jv_job_object;
14411440
#endif
14421441
jobstatus_T jv_status;
14431442
char_u *jv_stoponexit; /* allocated */

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
48,
767769
/**/
768770
47,
769771
/**/

0 commit comments

Comments
 (0)