Patch 7.4.1306
Problem:    Job control doesn't work well on MS-Windows.
Solution:   Various fixes. (Ken Takata, Ozaki Kiichi , Yukihiro Nakadaira,
            Yasuhiro Matsumoto)
Files:      src/Make_mvc.mak, src/eval.c, src/os_unix.c, src/os_win32.c,
            src/proto/os_unix.pro, src/proto/os_win32.pro, src/structs.h


*** ../vim-7.4.1305/src/Make_mvc.mak    2016-02-02 18:50:41.403602887 +0100
--- src/Make_mvc.mak    2016-02-12 19:18:38.277211213 +0100
***************
*** 113,119 ****
  #     Processor Version: CPUNR=[i386, i486, i586, i686, pentium4] (default is
  #     i386)
  #
! #     Version Support: WINVER=[0x0400, 0x0500] (default is 0x0400)
  #
  #     Debug version: DEBUG=yes
  #     Mapfile: MAP=[no, yes or lines] (default is yes)
--- 113,119 ----
  #     Processor Version: CPUNR=[i386, i486, i586, i686, pentium4] (default is
  #     i386)
  #
! #     Version Support: WINVER=[0x0400, 0x0500] (default is 0x0500)
  #
  #     Debug version: DEBUG=yes
  #     Mapfile: MAP=[no, yes or lines] (default is yes)
***************
*** 370,378 ****
  !endif
  
  ### Set the default $(WINVER) to make it work with VC++7.0 (VS.NET)
- #  When set to 0x0500 ":browse" stops working.
  !ifndef WINVER
! WINVER = 0x0400
  !endif
  
  # If you have a fixed directory for $VIM or $VIMRUNTIME, other than the normal
--- 370,377 ----
  !endif
  
  ### Set the default $(WINVER) to make it work with VC++7.0 (VS.NET)
  !ifndef WINVER
! WINVER = 0x0500
  !endif
  
  # If you have a fixed directory for $VIM or $VIMRUNTIME, other than the normal
*** ../vim-7.4.1305/src/eval.c  2016-02-11 21:08:27.540531286 +0100
--- src/eval.c  2016-02-12 19:25:58.172620678 +0100
***************
*** 7720,7727 ****
      static void
  job_free(job_T *job)
  {
!     /* TODO: free any handles */
! 
      vim_free(job);
  }
  
--- 7720,7726 ----
      static void
  job_free(job_T *job)
  {
!     mch_clear_job(job);
      vim_free(job);
  }
  
***************
*** 14369,14377 ****
                s = vim_strsave_shellescape(s, FALSE, TRUE);
                if (s == NULL)
                    goto theend;
            }
!           ga_concat(&ga, s);
!           vim_free(s);
            if (li->li_next != NULL)
                ga_append(&ga, ' ');
  #endif
--- 14368,14378 ----
                s = vim_strsave_shellescape(s, FALSE, TRUE);
                if (s == NULL)
                    goto theend;
+               ga_concat(&ga, s);
+               vim_free(s);
            }
!           else
!               ga_concat(&ga, s);
            if (li->li_next != NULL)
                ga_append(&ga, ' ');
  #endif
***************
*** 21623,21629 ****
                            "process %ld %s", (long)job->jv_pid, status);
  # elif defined(WIN32)
                vim_snprintf((char *)buf, NUMBUFLEN,
!                           "process %ld %s", (long)job->jv_pi.dwProcessId,
                            status);
  # else
                /* fall-back */
--- 21624,21631 ----
                            "process %ld %s", (long)job->jv_pid, status);
  # elif defined(WIN32)
                vim_snprintf((char *)buf, NUMBUFLEN,
!                           "process %ld %s",
!                           (long)job->jv_proc_info.dwProcessId,
                            status);
  # else
                /* fall-back */
*** ../vim-7.4.1305/src/os_unix.c       2016-02-09 11:37:46.417354447 +0100
--- src/os_unix.c       2016-02-12 19:22:31.174780515 +0100
***************
*** 5092,5097 ****
--- 5092,5103 ----
        job->jv_status = JOB_ENDED;
        return "dead";
      }
+     if (WIFSIGNALED(status))
+     {
+       job->jv_exitval = -1;
+       job->jv_status = JOB_ENDED;
+       return "dead";
+     }
      return "run";
  }
  
***************
*** 5099,5104 ****
--- 5105,5111 ----
  mch_stop_job(job_T *job, char_u *how)
  {
      int sig = -1;
+     pid_t job_pid;
  
      if (STRCMP(how, "hup") == 0)
        sig = SIGHUP;
***************
*** 5112,5121 ****
        sig = atoi((char *)how);
      else
        return FAIL;
      /* TODO: have an option to only kill the process, not the group? */
!     kill(-job->jv_pid, sig);
      return OK;
  }
  #endif
  
  /*
--- 5119,5148 ----
        sig = atoi((char *)how);
      else
        return FAIL;
+ 
      /* TODO: have an option to only kill the process, not the group? */
!     job_pid = job->jv_pid;
!     if (job_pid == getpgid(job_pid))
!       job_pid = -job_pid;
! 
!     kill(job_pid, sig);
! 
      return OK;
  }
+ 
+ /*
+  * Clear the data related to "job".
+  */
+     void
+ mch_clear_job(job_T *job)
+ {
+     /* call waitpid because child process may become zombie */
+ # ifdef __NeXT__
+     wait4(job->jv_pid, NULL, WNOHANG, (struct rusage *)0);
+ # else
+     waitpid(job->jv_pid, NULL, WNOHANG);
+ # endif
+ }
  #endif
  
  /*
*** ../vim-7.4.1305/src/os_win32.c      2016-02-11 12:48:32.692069619 +0100
--- src/os_win32.c      2016-02-12 19:25:39.000820698 +0100
***************
*** 5038,5056 ****
  {
      STARTUPINFO               si;
      PROCESS_INFORMATION       pi;
  
      ZeroMemory(&si, sizeof(si));
      si.cb = sizeof(si);
  
      if (!vim_create_process(cmd, FALSE,
            CREATE_DEFAULT_ERROR_MODE |
            CREATE_NEW_PROCESS_GROUP |
!           CREATE_NO_WINDOW,
            &si, &pi))
        job->jv_status = JOB_FAILED;
      else
      {
!       job->jv_pi = pi;
        job->jv_status = JOB_STARTED;
      }
  }
--- 5038,5081 ----
  {
      STARTUPINFO               si;
      PROCESS_INFORMATION       pi;
+     HANDLE            jo;
  
+     jo = CreateJobObject(NULL, NULL);
+     if (jo == NULL)
+     {
+       job->jv_status = JOB_FAILED;
+       return;
+     }
+ 
+     ZeroMemory(&pi, sizeof(pi));
      ZeroMemory(&si, sizeof(si));
      si.cb = sizeof(si);
+     si.dwFlags = STARTF_USESHOWWINDOW;
+     si.wShowWindow = SW_HIDE;
  
      if (!vim_create_process(cmd, FALSE,
+           CREATE_SUSPENDED |
            CREATE_DEFAULT_ERROR_MODE |
            CREATE_NEW_PROCESS_GROUP |
!           CREATE_NEW_CONSOLE,
            &si, &pi))
+     {
+       CloseHandle(jo);
        job->jv_status = JOB_FAILED;
+     }
      else
      {
!       if (!AssignProcessToJobObject(jo, pi.hProcess))
!       {
!           /* if failing, switch the way to terminate
!            * process with TerminateProcess. */
!           CloseHandle(jo);
!           jo = NULL;
!       }
!       ResumeThread(pi.hThread);
!       CloseHandle(job->jv_proc_info.hThread);
!       job->jv_proc_info = pi;
!       job->jv_job_object = jo;
        job->jv_status = JOB_STARTED;
      }
  }
***************
*** 5060,5071 ****
  {
      DWORD dwExitCode = 0;
  
!     if (!GetExitCodeProcess(job->jv_pi.hProcess, &dwExitCode))
!       return "dead";
!     if (dwExitCode != STILL_ACTIVE)
      {
!       CloseHandle(job->jv_pi.hProcess);
!       CloseHandle(job->jv_pi.hThread);
        return "dead";
      }
      return "run";
--- 5085,5094 ----
  {
      DWORD dwExitCode = 0;
  
!     if (!GetExitCodeProcess(job->jv_proc_info.hProcess, &dwExitCode)
!           || dwExitCode != STILL_ACTIVE)
      {
!       job->jv_status = JOB_ENDED;
        return "dead";
      }
      return "run";
***************
*** 5074,5087 ****
      int
  mch_stop_job(job_T *job, char_u *how)
  {
      if (STRCMP(how, "kill") == 0)
!       TerminateProcess(job->jv_pi.hProcess, 0);
!     else
!       return GenerateConsoleCtrlEvent(
!           STRCMP(how, "hup") == 0 ?
!                   CTRL_BREAK_EVENT : CTRL_C_EVENT,
!               job->jv_pi.dwProcessId) ? OK : FAIL;
!     return OK;
  }
  #endif
  
--- 5097,5135 ----
      int
  mch_stop_job(job_T *job, char_u *how)
  {
+     int ret = 0;
+     int ctrl_c = STRCMP(how, "int") == 0;
+ 
      if (STRCMP(how, "kill") == 0)
!     {
!       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))
!       return FAIL;
!     ret = GenerateConsoleCtrlEvent(
!           ctrl_c ? CTRL_C_EVENT : CTRL_BREAK_EVENT,
!           job->jv_proc_info.dwProcessId)
!       ? OK : FAIL;
!     FreeConsole();
!     return ret;
! }
! 
! /*
!  * Clear the data related to "job".
!  */
!     void
! 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);
!     }
  }
  #endif
  
*** ../vim-7.4.1305/src/proto/os_unix.pro       2016-02-07 14:26:12.179054006 
+0100
--- src/proto/os_unix.pro       2016-02-12 19:22:35.958730593 +0100
***************
*** 60,65 ****
--- 60,66 ----
  void mch_start_job(char **argv, job_T *job);
  char *mch_job_status(job_T *job);
  int mch_stop_job(job_T *job, char_u *how);
+ void mch_clear_job(job_T *job);
  void mch_breakcheck(void);
  int mch_expandpath(garray_T *gap, char_u *path, int flags);
  int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u 
***file, int flags);
*** ../vim-7.4.1305/src/proto/os_win32.pro      2016-02-07 19:57:12.192788494 
+0100
--- src/proto/os_win32.pro      2016-02-12 19:22:41.018677790 +0100
***************
*** 43,48 ****
--- 43,49 ----
  void mch_start_job(char *cmd, job_T *job);
  char *mch_job_status(job_T *job);
  int mch_stop_job(job_T *job, char_u *how);
+ void mch_clear_job(job_T *job);
  void mch_set_normal_colors(void);
  void mch_write(char_u *s, int len);
  void mch_delay(long msec, int ignoreinput);
*** ../vim-7.4.1305/src/structs.h       2016-02-11 12:48:32.696069578 +0100
--- src/structs.h       2016-02-12 19:25:48.324723420 +0100
***************
*** 1249,1255 ****
      int               jv_exitval;
  #endif
  #ifdef WIN32
!     PROCESS_INFORMATION       jv_pi;
  #endif
      jobstatus_T       jv_status;
  
--- 1249,1256 ----
      int               jv_exitval;
  #endif
  #ifdef WIN32
!     PROCESS_INFORMATION       jv_proc_info;
!     HANDLE            jv_job_object;
  #endif
      jobstatus_T       jv_status;
  
*** ../vim-7.4.1305/src/version.c       2016-02-12 19:08:10.479766970 +0100
--- src/version.c       2016-02-12 19:19:57.516384136 +0100
***************
*** 749,750 ****
--- 749,752 ----
  {   /* Add new patch number below this line */
+ /**/
+     1306,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
238. You think faxes are old-fashioned.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui