diff --git a/7.3.296 b/7.3.296 new file mode 100644 index 0000000..80369d1 --- /dev/null +++ b/7.3.296 @@ -0,0 +1,222 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.3.296 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.3.296 +Problem: When writing to an external command a zombie process may be left + behind. +Solution: Wait on the process. (James Vega) +Files: src/os_unix.c + + +*** ../vim-7.3.295/src/os_unix.c 2011-09-07 14:06:38.000000000 +0200 +--- src/os_unix.c 2011-09-07 14:54:11.000000000 +0200 +*************** +*** 154,159 **** +--- 154,166 ---- + + 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,3665 **** +--- 3667,3713 ---- + /* 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,4240 **** + { + MSG_PUTS(_("\nCannot fork\n")); + } +! else if (wpid == 0) + { + linenr_T lnum = curbuf->b_op_start.lnum; + int written = 0; +--- 4282,4288 ---- + { + MSG_PUTS(_("\nCannot fork\n")); + } +! else if (wpid == 0) /* child */ + { + linenr_T lnum = curbuf->b_op_start.lnum; + int written = 0; +*************** +*** 4242,4248 **** + char_u *s; + size_t l; + +- /* child */ + close(fromshell_fd); + for (;;) + { +--- 4290,4295 ---- +*************** +*** 4287,4293 **** + } + _exit(0); + } +! else + { + close(toshell_fd); + toshell_fd = -1; +--- 4334,4340 ---- + } + _exit(0); + } +! else /* parent */ + { + close(toshell_fd); + toshell_fd = -1; +*************** +*** 4584,4590 **** + * typed characters (otherwise we would lose typeahead). + */ + # ifdef __NeXT__ +! wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *) 0); + # else + wait_pid = waitpid(pid, &status, WNOHANG); + # endif +--- 4631,4637 ---- + * typed characters (otherwise we would lose typeahead). + */ + # ifdef __NeXT__ +! wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0); + # else + wait_pid = waitpid(pid, &status, WNOHANG); + # endif +*************** +*** 4633,4665 **** + * 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; +! } + + # ifdef FEAT_GUI + /* Close slave side of pty. Only do this after the child has +--- 4680,4687 ---- + * Don't wait if wait_pid was already set above, indicating the + * child already exited. + */ +! 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,4678 **** +--- 4694,4703 ---- + /* 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 +*** ../vim-7.3.295/src/version.c 2011-09-07 14:06:39.000000000 +0200 +--- src/version.c 2011-09-07 15:03:24.000000000 +0200 +*************** +*** 711,712 **** +--- 711,714 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 296, + /**/ + +-- +If your company is not involved in something called "ISO 9000" you probably +have no idea what it is. If your company _is_ involved in ISO 9000 then you +definitely have no idea what it is. + (Scott Adams - The Dilbert principle) + + /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 ///