summaryrefslogtreecommitdiff
path: root/src/os_win32.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-10-27 21:13:10 +0200
committerBram Moolenaar <Bram@vim.org>2016-10-27 21:13:10 +0200
commit14207f487c9e79a913256a41e3e9716b03b46955 (patch)
tree6e2f7f56921eb81b3d7e59c034740abd7ced0d81 /src/os_win32.c
parent01688ad545ff0809ddad5c8fa6b149dc5d67312b (diff)
downloadvim-14207f487c9e79a913256a41e3e9716b03b46955.zip
patch 8.0.0051
Problem: New code for job_stop() breaks channel test on AppVeyor. Solution: Revert the change.
Diffstat (limited to 'src/os_win32.c')
-rw-r--r--src/os_win32.c68
1 files changed, 25 insertions, 43 deletions
diff --git a/src/os_win32.c b/src/os_win32.c
index fca29f80d..d52beb886 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -50,10 +50,6 @@
# 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
@@ -4800,6 +4796,7 @@ 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];
@@ -4824,6 +4821,13 @@ 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);
@@ -4908,17 +4912,28 @@ 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]);
@@ -5005,44 +5020,6 @@ 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)
{
@@ -5050,7 +5027,10 @@ mch_stop_job(job_T *job, char_u *how)
if (STRCMP(how, "term") == 0 || STRCMP(how, "kill") == 0 || *how == NUL)
{
- return terminate_all(job->jv_proc_info.hProcess, 0) ? OK : FAIL;
+ 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;
}
if (!AttachConsole(job->jv_proc_info.dwProcessId))
@@ -5071,6 +5051,8 @@ 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);
}
}