Ken Thomases : libport: For spawnvp(_P_DETACH, ...), double-fork to avoid creating zombies.
Alexandre Julliard
julliard at winehq.org
Thu Dec 1 14:05:32 CST 2011
Module: wine
Branch: master
Commit: fda27ccc1b8357302708601f0618ea9915aa236a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=fda27ccc1b8357302708601f0618ea9915aa236a
Author: Ken Thomases <ken at codeweavers.com>
Date: Wed Nov 30 16:49:37 2011 -0600
libport: For spawnvp(_P_DETACH, ...), double-fork to avoid creating zombies.
---
libs/port/spawn.c | 35 ++++++++++++++++++++++++++++++-----
1 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/libs/port/spawn.c b/libs/port/spawn.c
index 40efebb..0cdc08c 100644
--- a/libs/port/spawn.c
+++ b/libs/port/spawn.c
@@ -36,7 +36,7 @@
int spawnvp(int mode, const char *cmdname, const char *const argv[])
{
#ifndef HAVE__SPAWNVP
- int pid = 0, status, wret;
+ int pid, status, wret;
if (mode == _P_OVERLAY)
{
@@ -51,20 +51,45 @@ int spawnvp(int mode, const char *cmdname, const char *const argv[])
pid = fork();
if (pid == 0)
{
+ /* in child */
+ if (mode == _P_DETACH)
+ {
+ pid = fork();
+ if (pid == -1) _exit(1);
+ else if (pid > 0) _exit(0);
+ /* else in grandchild */
+ }
+
signal( SIGPIPE, SIG_DFL );
execvp(cmdname, (char **)argv);
_exit(1);
}
- if (pid != -1 && mode == _P_OVERLAY) exit(0);
+ if (pid == -1)
+ return -1;
+
+ if (mode == _P_OVERLAY) exit(0);
- if (pid != -1 && mode == _P_WAIT)
+ if (mode == _P_WAIT || mode == _P_DETACH)
{
while (pid != (wret = waitpid(pid, &status, 0)))
if (wret == -1 && errno != EINTR) break;
- if (pid == wret && WIFEXITED(status)) pid = WEXITSTATUS(status);
- else pid = 255; /* abnormal exit with an abort or an interrupt */
+ if (pid == wret && WIFEXITED(status))
+ {
+ if (mode == _P_WAIT)
+ pid = WEXITSTATUS(status);
+ else /* mode == _P_DETACH */
+ if (WEXITSTATUS(status) != 0) /* child couldn't fork grandchild */
+ pid = -1;
+ }
+ else
+ {
+ if (mode == _P_WAIT)
+ pid = 255; /* abnormal exit with an abort or an interrupt */
+ else /* mode == _P_DETACH */
+ pid = -1;
+ }
}
return pid;
More information about the wine-cvs
mailing list