]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.296 v7.3.296
authorBram Moolenaar <Bram@vim.org>
Wed, 7 Sep 2011 13:04:31 +0000 (15:04 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 7 Sep 2011 13:04:31 +0000 (15:04 +0200)
Problem:    When writing to an external command a zombie process may be left
            behind.
Solution:   Wait on the process. (James Vega)

src/os_unix.c
src/version.c

index d654f5f3dd8638b95f585c0a1c45c7583116e306..8dcf8c7d0d3c0415ea6f0661064b2370d03fc1a5 100644 (file)
@@ -154,6 +154,13 @@ static int did_set_icon = FALSE;
 
 static void may_core_dump __ARGS((void));
 
+#ifdef HAVE_UNION_WAIT
+typedef union wait waitstatus;
+#else
+typedef int waitstatus;
+#endif
+static int  wait4pid __ARGS((pid_t, waitstatus *));
+
 static int  WaitForChar __ARGS((long));
 #if defined(__BEOS__)
 int  RealWaitForChar __ARGS((int, long, int *));
@@ -3660,6 +3667,47 @@ mch_new_shellsize()
     /* Nothing to do. */
 }
 
+/*
+ * Wait for process "child" to end.
+ * Return "child" if it exited properly, <= 0 on error.
+ */
+    static pid_t
+wait4pid(child, status)
+    pid_t      child;
+    waitstatus *status;
+{
+    pid_t wait_pid = 0;
+
+    while (wait_pid != child)
+    {
+# ifdef _THREAD_SAFE
+       /* Ugly hack: when compiled with Python threads are probably
+        * used, in which case wait() sometimes hangs for no obvious
+        * reason.  Use waitpid() instead and loop (like the GUI). */
+#  ifdef __NeXT__
+       wait_pid = wait4(child, status, WNOHANG, (struct rusage *)0);
+#  else
+       wait_pid = waitpid(child, status, WNOHANG);
+#  endif
+       if (wait_pid == 0)
+       {
+           /* Wait for 1/100 sec before trying again. */
+           mch_delay(10L, TRUE);
+           continue;
+       }
+# else
+       wait_pid = wait(status);
+# endif
+       if (wait_pid <= 0
+# ifdef ECHILD
+               && errno == ECHILD
+# endif
+          )
+           break;
+    }
+    return wait_pid;
+}
+
     int
 mch_call_shell(cmd, options)
     char_u     *cmd;
@@ -4234,7 +4282,7 @@ mch_call_shell(cmd, options)
                    {
                        MSG_PUTS(_("\nCannot fork\n"));
                    }
-                   else if (wpid == 0)
+                   else if (wpid == 0) /* child */
                    {
                        linenr_T    lnum = curbuf->b_op_start.lnum;
                        int         written = 0;
@@ -4242,7 +4290,6 @@ mch_call_shell(cmd, options)
                        char_u      *s;
                        size_t      l;
 
-                       /* child */
                        close(fromshell_fd);
                        for (;;)
                        {
@@ -4287,7 +4334,7 @@ mch_call_shell(cmd, options)
                        }
                        _exit(0);
                    }
-                   else
+                   else /* parent */
                    {
                        close(toshell_fd);
                        toshell_fd = -1;
@@ -4584,7 +4631,7 @@ mch_call_shell(cmd, options)
                     * typed characters (otherwise we would lose typeahead).
                     */
 # ifdef __NeXT__
-                   wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *) 0);
+                   wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
 # else
                    wait_pid = waitpid(pid, &status, WNOHANG);
 # endif
@@ -4633,33 +4680,8 @@ finished:
             * Don't wait if wait_pid was already set above, indicating the
             * child already exited.
             */
-           while (wait_pid != pid)
-           {
-# ifdef _THREAD_SAFE
-               /* Ugly hack: when compiled with Python threads are probably
-                * used, in which case wait() sometimes hangs for no obvious
-                * reason.  Use waitpid() instead and loop (like the GUI). */
-#  ifdef __NeXT__
-               wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
-#  else
-               wait_pid = waitpid(pid, &status, WNOHANG);
-#  endif
-               if (wait_pid == 0)
-               {
-                   /* Wait for 1/100 sec before trying again. */
-                   mch_delay(10L, TRUE);
-                   continue;
-               }
-# else
-               wait_pid = wait(&status);
-# endif
-               if (wait_pid <= 0
-# ifdef ECHILD
-                       && errno == ECHILD
-# endif
-                  )
-                   break;
-           }
+           if (wait_pid != pid)
+               wait_pid = wait4pid(pid, &status);
 
 # ifdef FEAT_GUI
            /* Close slave side of pty.  Only do this after the child has
@@ -4672,7 +4694,10 @@ finished:
            /* Make sure the child that writes to the external program is
             * dead. */
            if (wpid > 0)
+           {
                kill(wpid, SIGKILL);
+               wait4pid(wpid, NULL);
+           }
 
            /*
             * Set to raw mode right now, otherwise a CTRL-C after
index f3f0e931fbf8cd9be2f2b76f0036e0dd971e2156..8362464e6770006f7434713f38beb9cea3978199 100644 (file)
@@ -709,6 +709,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    296,
 /**/
     295,
 /**/