mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
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)
This commit is contained in:
@@ -50,6 +50,10 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
# include <tlhelp32.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
# ifndef FROM_LEFT_1ST_BUTTON_PRESSED
|
# ifndef FROM_LEFT_1ST_BUTTON_PRESSED
|
||||||
# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001
|
# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001
|
||||||
@@ -4796,7 +4800,6 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
|
|||||||
{
|
{
|
||||||
STARTUPINFO si;
|
STARTUPINFO si;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
HANDLE jo;
|
|
||||||
SECURITY_ATTRIBUTES saAttr;
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
channel_T *channel = NULL;
|
channel_T *channel = NULL;
|
||||||
HANDLE ifd[2];
|
HANDLE ifd[2];
|
||||||
@@ -4821,13 +4824,6 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options)
|
|||||||
efd[0] = INVALID_HANDLE_VALUE;
|
efd[0] = INVALID_HANDLE_VALUE;
|
||||||
efd[1] = 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(&pi, sizeof(pi));
|
||||||
ZeroMemory(&si, sizeof(si));
|
ZeroMemory(&si, sizeof(si));
|
||||||
si.cb = 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,
|
if (!vim_create_process(cmd, TRUE,
|
||||||
CREATE_SUSPENDED |
|
|
||||||
CREATE_DEFAULT_ERROR_MODE |
|
CREATE_DEFAULT_ERROR_MODE |
|
||||||
CREATE_NEW_PROCESS_GROUP |
|
CREATE_NEW_PROCESS_GROUP |
|
||||||
CREATE_NEW_CONSOLE,
|
CREATE_NEW_CONSOLE,
|
||||||
&si, &pi))
|
&si, &pi))
|
||||||
{
|
{
|
||||||
CloseHandle(jo);
|
|
||||||
job->jv_status = JOB_FAILED;
|
job->jv_status = JOB_FAILED;
|
||||||
goto 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);
|
CloseHandle(pi.hThread);
|
||||||
job->jv_proc_info = pi;
|
job->jv_proc_info = pi;
|
||||||
job->jv_job_object = jo;
|
|
||||||
job->jv_status = JOB_STARTED;
|
job->jv_status = JOB_STARTED;
|
||||||
|
|
||||||
CloseHandle(ifd[0]);
|
CloseHandle(ifd[0]);
|
||||||
@@ -5020,6 +5005,44 @@ mch_detect_ended_job(job_T *job_list)
|
|||||||
return NULL;
|
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
|
int
|
||||||
mch_stop_job(job_T *job, char_u *how)
|
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 (STRCMP(how, "term") == 0 || STRCMP(how, "kill") == 0 || *how == NUL)
|
||||||
{
|
{
|
||||||
if (job->jv_job_object != NULL)
|
return terminate_all(job->jv_proc_info.hProcess, 0) ? OK : FAIL;
|
||||||
return TerminateJobObject(job->jv_job_object, 0) ? OK : FAIL;
|
|
||||||
else
|
|
||||||
return TerminateProcess(job->jv_proc_info.hProcess, 0) ? OK : FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AttachConsole(job->jv_proc_info.dwProcessId))
|
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_status != JOB_FAILED)
|
||||||
{
|
{
|
||||||
if (job->jv_job_object != NULL)
|
|
||||||
CloseHandle(job->jv_job_object);
|
|
||||||
CloseHandle(job->jv_proc_info.hProcess);
|
CloseHandle(job->jv_proc_info.hProcess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1437,7 +1437,6 @@ struct jobvar_S
|
|||||||
#endif
|
#endif
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
PROCESS_INFORMATION jv_proc_info;
|
PROCESS_INFORMATION jv_proc_info;
|
||||||
HANDLE jv_job_object;
|
|
||||||
#endif
|
#endif
|
||||||
jobstatus_T jv_status;
|
jobstatus_T jv_status;
|
||||||
char_u *jv_stoponexit; /* allocated */
|
char_u *jv_stoponexit; /* allocated */
|
||||||
|
@@ -764,6 +764,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
48,
|
||||||
/**/
|
/**/
|
||||||
47,
|
47,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user