Karsten Hopp 7af524
To: vim_dev@googlegroups.com
Karsten Hopp 7af524
Subject: Patch 7.3.296
Karsten Hopp 7af524
Fcc: outbox
Karsten Hopp 7af524
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 7af524
Mime-Version: 1.0
Karsten Hopp 7af524
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 7af524
Content-Transfer-Encoding: 8bit
Karsten Hopp 7af524
------------
Karsten Hopp 7af524
Karsten Hopp 7af524
Patch 7.3.296
Karsten Hopp 7af524
Problem:    When writing to an external command a zombie process may be left
Karsten Hopp 7af524
	    behind.
Karsten Hopp 7af524
Solution:   Wait on the process. (James Vega)
Karsten Hopp 7af524
Files:	    src/os_unix.c
Karsten Hopp 7af524
Karsten Hopp 7af524
Karsten Hopp 7af524
*** ../vim-7.3.295/src/os_unix.c	2011-09-07 14:06:38.000000000 +0200
Karsten Hopp 7af524
--- src/os_unix.c	2011-09-07 14:54:11.000000000 +0200
Karsten Hopp 7af524
***************
Karsten Hopp 7af524
*** 154,159 ****
Karsten Hopp 7af524
--- 154,166 ----
Karsten Hopp 7af524
  
Karsten Hopp 7af524
  static void may_core_dump __ARGS((void));
Karsten Hopp 7af524
  
Karsten Hopp 7af524
+ #ifdef HAVE_UNION_WAIT
Karsten Hopp 7af524
+ typedef union wait waitstatus;
Karsten Hopp 7af524
+ #else
Karsten Hopp 7af524
+ typedef int waitstatus;
Karsten Hopp 7af524
+ #endif
Karsten Hopp 7af524
+ static int  wait4pid __ARGS((pid_t, waitstatus *));
Karsten Hopp 7af524
+ 
Karsten Hopp 7af524
  static int  WaitForChar __ARGS((long));
Karsten Hopp 7af524
  #if defined(__BEOS__)
Karsten Hopp 7af524
  int  RealWaitForChar __ARGS((int, long, int *));
Karsten Hopp 7af524
***************
Karsten Hopp 7af524
*** 3660,3665 ****
Karsten Hopp 7af524
--- 3667,3713 ----
Karsten Hopp 7af524
      /* Nothing to do. */
Karsten Hopp 7af524
  }
Karsten Hopp 7af524
  
Karsten Hopp 7af524
+ /*
Karsten Hopp 7af524
+  * Wait for process "child" to end.
Karsten Hopp 7af524
+  * Return "child" if it exited properly, <= 0 on error.
Karsten Hopp 7af524
+  */
Karsten Hopp 7af524
+     static pid_t
Karsten Hopp 7af524
+ wait4pid(child, status)
Karsten Hopp 7af524
+     pid_t	child;
Karsten Hopp 7af524
+     waitstatus	*status;
Karsten Hopp 7af524
+ {
Karsten Hopp 7af524
+     pid_t wait_pid = 0;
Karsten Hopp 7af524
+ 
Karsten Hopp 7af524
+     while (wait_pid != child)
Karsten Hopp 7af524
+     {
Karsten Hopp 7af524
+ # ifdef _THREAD_SAFE
Karsten Hopp 7af524
+ 	/* Ugly hack: when compiled with Python threads are probably
Karsten Hopp 7af524
+ 	 * used, in which case wait() sometimes hangs for no obvious
Karsten Hopp 7af524
+ 	 * reason.  Use waitpid() instead and loop (like the GUI). */
Karsten Hopp 7af524
+ #  ifdef __NeXT__
Karsten Hopp 7af524
+ 	wait_pid = wait4(child, status, WNOHANG, (struct rusage *)0);
Karsten Hopp 7af524
+ #  else
Karsten Hopp 7af524
+ 	wait_pid = waitpid(child, status, WNOHANG);
Karsten Hopp 7af524
+ #  endif
Karsten Hopp 7af524
+ 	if (wait_pid == 0)
Karsten Hopp 7af524
+ 	{
Karsten Hopp 7af524
+ 	    /* Wait for 1/100 sec before trying again. */
Karsten Hopp 7af524
+ 	    mch_delay(10L, TRUE);
Karsten Hopp 7af524
+ 	    continue;
Karsten Hopp 7af524
+ 	}
Karsten Hopp 7af524
+ # else
Karsten Hopp 7af524
+ 	wait_pid = wait(status);
Karsten Hopp 7af524
+ # endif
Karsten Hopp 7af524
+ 	if (wait_pid <= 0
Karsten Hopp 7af524
+ # ifdef ECHILD
Karsten Hopp 7af524
+ 		&& errno == ECHILD
Karsten Hopp 7af524
+ # endif
Karsten Hopp 7af524
+ 	   )
Karsten Hopp 7af524
+ 	    break;
Karsten Hopp 7af524
+     }
Karsten Hopp 7af524
+     return wait_pid;
Karsten Hopp 7af524
+ }
Karsten Hopp 7af524
+ 
Karsten Hopp 7af524
      int
Karsten Hopp 7af524
  mch_call_shell(cmd, options)
Karsten Hopp 7af524
      char_u	*cmd;
Karsten Hopp 7af524
***************
Karsten Hopp 7af524
*** 4234,4240 ****
Karsten Hopp 7af524
  		    {
Karsten Hopp 7af524
  			MSG_PUTS(_("\nCannot fork\n"));
Karsten Hopp 7af524
  		    }
Karsten Hopp 7af524
! 		    else if (wpid == 0)
Karsten Hopp 7af524
  		    {
Karsten Hopp 7af524
  			linenr_T    lnum = curbuf->b_op_start.lnum;
Karsten Hopp 7af524
  			int	    written = 0;
Karsten Hopp 7af524
--- 4282,4288 ----
Karsten Hopp 7af524
  		    {
Karsten Hopp 7af524
  			MSG_PUTS(_("\nCannot fork\n"));
Karsten Hopp 7af524
  		    }
Karsten Hopp 7af524
! 		    else if (wpid == 0) /* child */
Karsten Hopp 7af524
  		    {
Karsten Hopp 7af524
  			linenr_T    lnum = curbuf->b_op_start.lnum;
Karsten Hopp 7af524
  			int	    written = 0;
Karsten Hopp 7af524
***************
Karsten Hopp 7af524
*** 4242,4248 ****
Karsten Hopp 7af524
  			char_u	    *s;
Karsten Hopp 7af524
  			size_t	    l;
Karsten Hopp 7af524
  
Karsten Hopp 7af524
- 			/* child */
Karsten Hopp 7af524
  			close(fromshell_fd);
Karsten Hopp 7af524
  			for (;;)
Karsten Hopp 7af524
  			{
Karsten Hopp 7af524
--- 4290,4295 ----
Karsten Hopp 7af524
***************
Karsten Hopp 7af524
*** 4287,4293 ****
Karsten Hopp 7af524
  			}
Karsten Hopp 7af524
  			_exit(0);
Karsten Hopp 7af524
  		    }
Karsten Hopp 7af524
! 		    else
Karsten Hopp 7af524
  		    {
Karsten Hopp 7af524
  			close(toshell_fd);
Karsten Hopp 7af524
  			toshell_fd = -1;
Karsten Hopp 7af524
--- 4334,4340 ----
Karsten Hopp 7af524
  			}
Karsten Hopp 7af524
  			_exit(0);
Karsten Hopp 7af524
  		    }
Karsten Hopp 7af524
! 		    else /* parent */
Karsten Hopp 7af524
  		    {
Karsten Hopp 7af524
  			close(toshell_fd);
Karsten Hopp 7af524
  			toshell_fd = -1;
Karsten Hopp 7af524
***************
Karsten Hopp 7af524
*** 4584,4590 ****
Karsten Hopp 7af524
  		     * typed characters (otherwise we would lose typeahead).
Karsten Hopp 7af524
  		     */
Karsten Hopp 7af524
  # ifdef __NeXT__
Karsten Hopp 7af524
! 		    wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *) 0);
Karsten Hopp 7af524
  # else
Karsten Hopp 7af524
  		    wait_pid = waitpid(pid, &status, WNOHANG);
Karsten Hopp 7af524
  # endif
Karsten Hopp 7af524
--- 4631,4637 ----
Karsten Hopp 7af524
  		     * typed characters (otherwise we would lose typeahead).
Karsten Hopp 7af524
  		     */
Karsten Hopp 7af524
  # ifdef __NeXT__
Karsten Hopp 7af524
! 		    wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
Karsten Hopp 7af524
  # else
Karsten Hopp 7af524
  		    wait_pid = waitpid(pid, &status, WNOHANG);
Karsten Hopp 7af524
  # endif
Karsten Hopp 7af524
***************
Karsten Hopp 7af524
*** 4633,4665 ****
Karsten Hopp 7af524
  	     * Don't wait if wait_pid was already set above, indicating the
Karsten Hopp 7af524
  	     * child already exited.
Karsten Hopp 7af524
  	     */
Karsten Hopp 7af524
! 	    while (wait_pid != pid)
Karsten Hopp 7af524
! 	    {
Karsten Hopp 7af524
! # ifdef _THREAD_SAFE
Karsten Hopp 7af524
! 		/* Ugly hack: when compiled with Python threads are probably
Karsten Hopp 7af524
! 		 * used, in which case wait() sometimes hangs for no obvious
Karsten Hopp 7af524
! 		 * reason.  Use waitpid() instead and loop (like the GUI). */
Karsten Hopp 7af524
! #  ifdef __NeXT__
Karsten Hopp 7af524
! 		wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
Karsten Hopp 7af524
! #  else
Karsten Hopp 7af524
! 		wait_pid = waitpid(pid, &status, WNOHANG);
Karsten Hopp 7af524
! #  endif
Karsten Hopp 7af524
! 		if (wait_pid == 0)
Karsten Hopp 7af524
! 		{
Karsten Hopp 7af524
! 		    /* Wait for 1/100 sec before trying again. */
Karsten Hopp 7af524
! 		    mch_delay(10L, TRUE);
Karsten Hopp 7af524
! 		    continue;
Karsten Hopp 7af524
! 		}
Karsten Hopp 7af524
! # else
Karsten Hopp 7af524
! 		wait_pid = wait(&status);
Karsten Hopp 7af524
! # endif
Karsten Hopp 7af524
! 		if (wait_pid <= 0
Karsten Hopp 7af524
! # ifdef ECHILD
Karsten Hopp 7af524
! 			&& errno == ECHILD
Karsten Hopp 7af524
! # endif
Karsten Hopp 7af524
! 		   )
Karsten Hopp 7af524
! 		    break;
Karsten Hopp 7af524
! 	    }
Karsten Hopp 7af524
  
Karsten Hopp 7af524
  # ifdef FEAT_GUI
Karsten Hopp 7af524
  	    /* Close slave side of pty.  Only do this after the child has
Karsten Hopp 7af524
--- 4680,4687 ----
Karsten Hopp 7af524
  	     * Don't wait if wait_pid was already set above, indicating the
Karsten Hopp 7af524
  	     * child already exited.
Karsten Hopp 7af524
  	     */
Karsten Hopp 7af524
! 	    if (wait_pid != pid)
Karsten Hopp 7af524
! 		wait_pid = wait4pid(pid, &status);
Karsten Hopp 7af524
  
Karsten Hopp 7af524
  # ifdef FEAT_GUI
Karsten Hopp 7af524
  	    /* Close slave side of pty.  Only do this after the child has
Karsten Hopp 7af524
***************
Karsten Hopp 7af524
*** 4672,4678 ****
Karsten Hopp 7af524
--- 4694,4703 ----
Karsten Hopp 7af524
  	    /* Make sure the child that writes to the external program is
Karsten Hopp 7af524
  	     * dead. */
Karsten Hopp 7af524
  	    if (wpid > 0)
Karsten Hopp 7af524
+ 	    {
Karsten Hopp 7af524
  		kill(wpid, SIGKILL);
Karsten Hopp 7af524
+ 		wait4pid(wpid, NULL);
Karsten Hopp 7af524
+ 	    }
Karsten Hopp 7af524
  
Karsten Hopp 7af524
  	    /*
Karsten Hopp 7af524
  	     * Set to raw mode right now, otherwise a CTRL-C after
Karsten Hopp 7af524
*** ../vim-7.3.295/src/version.c	2011-09-07 14:06:39.000000000 +0200
Karsten Hopp 7af524
--- src/version.c	2011-09-07 15:03:24.000000000 +0200
Karsten Hopp 7af524
***************
Karsten Hopp 7af524
*** 711,712 ****
Karsten Hopp 7af524
--- 711,714 ----
Karsten Hopp 7af524
  {   /* Add new patch number below this line */
Karsten Hopp 7af524
+ /**/
Karsten Hopp 7af524
+     296,
Karsten Hopp 7af524
  /**/
Karsten Hopp 7af524
Karsten Hopp 7af524
-- 
Karsten Hopp 7af524
If your company is not involved in something called "ISO 9000" you probably
Karsten Hopp 7af524
have no idea what it is.  If your company _is_ involved in ISO 9000 then you
Karsten Hopp 7af524
definitely have no idea what it is.
Karsten Hopp 7af524
				(Scott Adams - The Dilbert principle)
Karsten Hopp 7af524
Karsten Hopp 7af524
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 7af524
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 7af524
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 7af524
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///