mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -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:
@@ -154,6 +154,13 @@ static int did_set_icon = FALSE;
|
|||||||
|
|
||||||
static void may_core_dump __ARGS((void));
|
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));
|
static int WaitForChar __ARGS((long));
|
||||||
#if defined(__BEOS__)
|
#if defined(__BEOS__)
|
||||||
int RealWaitForChar __ARGS((int, long, int *));
|
int RealWaitForChar __ARGS((int, long, int *));
|
||||||
@@ -3660,6 +3667,47 @@ mch_new_shellsize()
|
|||||||
/* Nothing to do. */
|
/* 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
|
int
|
||||||
mch_call_shell(cmd, options)
|
mch_call_shell(cmd, options)
|
||||||
char_u *cmd;
|
char_u *cmd;
|
||||||
@@ -4234,7 +4282,7 @@ mch_call_shell(cmd, options)
|
|||||||
{
|
{
|
||||||
MSG_PUTS(_("\nCannot fork\n"));
|
MSG_PUTS(_("\nCannot fork\n"));
|
||||||
}
|
}
|
||||||
else if (wpid == 0)
|
else if (wpid == 0) /* child */
|
||||||
{
|
{
|
||||||
linenr_T lnum = curbuf->b_op_start.lnum;
|
linenr_T lnum = curbuf->b_op_start.lnum;
|
||||||
int written = 0;
|
int written = 0;
|
||||||
@@ -4242,7 +4290,6 @@ mch_call_shell(cmd, options)
|
|||||||
char_u *s;
|
char_u *s;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
/* child */
|
|
||||||
close(fromshell_fd);
|
close(fromshell_fd);
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@@ -4287,7 +4334,7 @@ mch_call_shell(cmd, options)
|
|||||||
}
|
}
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
else
|
else /* parent */
|
||||||
{
|
{
|
||||||
close(toshell_fd);
|
close(toshell_fd);
|
||||||
toshell_fd = -1;
|
toshell_fd = -1;
|
||||||
@@ -4584,7 +4631,7 @@ mch_call_shell(cmd, options)
|
|||||||
* typed characters (otherwise we would lose typeahead).
|
* typed characters (otherwise we would lose typeahead).
|
||||||
*/
|
*/
|
||||||
# ifdef __NeXT__
|
# ifdef __NeXT__
|
||||||
wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *) 0);
|
wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
|
||||||
# else
|
# else
|
||||||
wait_pid = waitpid(pid, &status, WNOHANG);
|
wait_pid = waitpid(pid, &status, WNOHANG);
|
||||||
# endif
|
# endif
|
||||||
@@ -4633,33 +4680,8 @@ finished:
|
|||||||
* Don't wait if wait_pid was already set above, indicating the
|
* Don't wait if wait_pid was already set above, indicating the
|
||||||
* child already exited.
|
* child already exited.
|
||||||
*/
|
*/
|
||||||
while (wait_pid != pid)
|
if (wait_pid != pid)
|
||||||
{
|
wait_pid = wait4pid(pid, &status);
|
||||||
# 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
|
# ifdef FEAT_GUI
|
||||||
/* Close slave side of pty. Only do this after the child has
|
/* 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
|
/* Make sure the child that writes to the external program is
|
||||||
* dead. */
|
* dead. */
|
||||||
if (wpid > 0)
|
if (wpid > 0)
|
||||||
|
{
|
||||||
kill(wpid, SIGKILL);
|
kill(wpid, SIGKILL);
|
||||||
|
wait4pid(wpid, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set to raw mode right now, otherwise a CTRL-C after
|
* Set to raw mode right now, otherwise a CTRL-C after
|
||||||
|
@@ -709,6 +709,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
296,
|
||||||
/**/
|
/**/
|
||||||
295,
|
295,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user