0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

updated for version 7.3.296

Problem:    When writing to an external command a zombie process may be left
            behind.
Solution:   Wait on the process. (James Vega)
This commit is contained in:
Bram Moolenaar
2011-09-07 15:04:31 +02:00
parent 493c7a8541
commit 205b886a41
2 changed files with 58 additions and 31 deletions

View 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

View File

@@ -709,6 +709,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
296,
/**/
295,
/**/