* dtable.cc (set_std_handle): Use std_consts array to control SetStdHandle
settings. (dtable::fixup_after_fork): Ditto. * exceptions.cc (set_sig_errno): Remove some debugging output. * path.cc (path_conv::check): Don't OR need_directory with flags sent to symlink_info::check. (symlink_info::check): Use PATH_ALL_EXEC to determine when a file is executable. * path.h (path_types): Add PATH_ALL_EXEC. (isexec): Use PATH_ALL_EXEC so that cygexec types will be considered executable. * pinfo.h (_pinfo): Add a process handle that is kept open throughout the life of a cygwin pid. * sigproc.cc (proc_exists): Remove hopefully obsolete stuff. (proc_subproc): Set up process handle that is kept open throughout the life of a cygwin pid. Reorganize PROC_WAIT stuff to use common code. (proc_terminate): Close pid lifetime process handle. (checkstate): Cleanup. (stopped_or_terminated): Move zombie cleanup. (remove_zombie): To here. * spawn.cc (spawn_guts): Reorganize reparenting code for 1247th time.
This commit is contained in:
parent
65bb926f51
commit
164a681ca5
|
@ -1,3 +1,27 @@
|
||||||
|
Sun Oct 8 22:38:40 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* dtable.cc (set_std_handle): Use std_consts array to control
|
||||||
|
SetStdHandle settings.
|
||||||
|
(dtable::fixup_after_fork): Ditto.
|
||||||
|
* exceptions.cc (set_sig_errno): Remove some debugging output.
|
||||||
|
* path.cc (path_conv::check): Don't OR need_directory with flags sent
|
||||||
|
to symlink_info::check.
|
||||||
|
(symlink_info::check): Use PATH_ALL_EXEC to determine when a file is
|
||||||
|
executable.
|
||||||
|
* path.h (path_types): Add PATH_ALL_EXEC.
|
||||||
|
(isexec): Use PATH_ALL_EXEC so that cygexec types will be considered
|
||||||
|
executable.
|
||||||
|
* pinfo.h (_pinfo): Add a process handle that is kept open throughout
|
||||||
|
the life of a cygwin pid.
|
||||||
|
* sigproc.cc (proc_exists): Remove hopefully obsolete stuff.
|
||||||
|
(proc_subproc): Set up process handle that is kept open throughout the
|
||||||
|
life of a cygwin pid. Reorganize PROC_WAIT stuff to use common code.
|
||||||
|
(proc_terminate): Close pid lifetime process handle.
|
||||||
|
(checkstate): Cleanup.
|
||||||
|
(stopped_or_terminated): Move zombie cleanup.
|
||||||
|
(remove_zombie): To here.
|
||||||
|
* spawn.cc (spawn_guts): Reorganize reparenting code for 1247th time.
|
||||||
|
|
||||||
Sat Oct 7 13:59:15 2000 Christopher Faylor <cgf@cygnus.com>
|
Sat Oct 7 13:59:15 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
* fhandler.h (fhandler_base): Remove obsolete _rpos and _rsize
|
* fhandler.h (fhandler_base): Remove obsolete _rpos and _rsize
|
||||||
|
|
|
@ -33,6 +33,9 @@ details. */
|
||||||
|
|
||||||
dtable fdtab;
|
dtable fdtab;
|
||||||
|
|
||||||
|
static DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
|
||||||
|
STD_ERROR_HANDLE};
|
||||||
|
|
||||||
/* Set aside space for the table of fds */
|
/* Set aside space for the table of fds */
|
||||||
void
|
void
|
||||||
dtable_init (void)
|
dtable_init (void)
|
||||||
|
@ -45,11 +48,9 @@ void __stdcall
|
||||||
set_std_handle (int fd)
|
set_std_handle (int fd)
|
||||||
{
|
{
|
||||||
if (fd == 0)
|
if (fd == 0)
|
||||||
SetStdHandle (STD_INPUT_HANDLE, fdtab[fd]->get_handle ());
|
SetStdHandle (std_consts[fd], fdtab[fd]->get_handle ());
|
||||||
else if (fd == 1)
|
else if (fd <= 2)
|
||||||
SetStdHandle (STD_OUTPUT_HANDLE, fdtab[fd]->get_output_handle ());
|
SetStdHandle (std_consts[fd], fdtab[fd]->get_output_handle ());
|
||||||
else if (fd == 2)
|
|
||||||
SetStdHandle (STD_ERROR_HANDLE, fdtab[fd]->get_output_handle ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -453,7 +454,13 @@ dtable::fixup_after_exec (HANDLE parent, size_t sz, fhandler_base **f)
|
||||||
if (fds[i]->get_close_on_exec ())
|
if (fds[i]->get_close_on_exec ())
|
||||||
release (i);
|
release (i);
|
||||||
else
|
else
|
||||||
fds[i]->fixup_after_exec (parent);
|
{
|
||||||
|
fds[i]->fixup_after_exec (parent);
|
||||||
|
if (i == 0)
|
||||||
|
SetStdHandle (std_consts[i], fds[i]->get_io_handle ());
|
||||||
|
else if (i <= 2)
|
||||||
|
SetStdHandle (std_consts[i], fds[i]->get_output_handle ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -688,7 +688,7 @@ set_sig_errno (int e)
|
||||||
{
|
{
|
||||||
set_errno (e);
|
set_errno (e);
|
||||||
sigsave.saved_errno = e;
|
sigsave.saved_errno = e;
|
||||||
debug_printf ("errno %d", e);
|
// sigproc_printf ("errno %d", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SUSPEND_TRIES 10000
|
#define SUSPEND_TRIES 10000
|
||||||
|
|
|
@ -257,7 +257,7 @@ path_conv::check (const char *src, unsigned opt,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
suff = suffixes;
|
suff = suffixes;
|
||||||
sym.pflags = path_flags | need_directory;
|
sym.pflags = path_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = sym.check (path_copy, suff);
|
int len = sym.check (path_copy, suff);
|
||||||
|
@ -2294,7 +2294,7 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Not a symlink, see if executable. */
|
/* Not a symlink, see if executable. */
|
||||||
if (!(pflags & (PATH_EXEC | PATH_CYGWIN_EXEC)) && got >= 2 &&
|
if (!(pflags & PATH_ALL_EXEC) && got >= 2 &&
|
||||||
((cookie_buf[0] == '#' && cookie_buf[1] == '!') ||
|
((cookie_buf[0] == '#' && cookie_buf[1] == '!') ||
|
||||||
(cookie_buf[0] == ':' && cookie_buf[1] == '\n') ||
|
(cookie_buf[0] == ':' && cookie_buf[1] == '\n') ||
|
||||||
(cookie_buf[0] == 'M' && cookie_buf[1] == 'Z')))
|
(cookie_buf[0] == 'M' && cookie_buf[1] == 'Z')))
|
||||||
|
|
|
@ -36,6 +36,7 @@ enum path_types
|
||||||
PATH_BINARY = MOUNT_BINARY,
|
PATH_BINARY = MOUNT_BINARY,
|
||||||
PATH_EXEC = MOUNT_EXEC,
|
PATH_EXEC = MOUNT_EXEC,
|
||||||
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
||||||
|
PATH_ALL_EXEC = PATH_CYGWIN_EXEC | PATH_EXEC,
|
||||||
PATH_SOCKET = 0x40000000,
|
PATH_SOCKET = 0x40000000,
|
||||||
PATH_HASACLS = 0x80000000
|
PATH_HASACLS = 0x80000000
|
||||||
};
|
};
|
||||||
|
@ -52,7 +53,7 @@ class path_conv
|
||||||
int isbinary () {return path_flags & PATH_BINARY;}
|
int isbinary () {return path_flags & PATH_BINARY;}
|
||||||
int issymlink () {return path_flags & PATH_SYMLINK;}
|
int issymlink () {return path_flags & PATH_SYMLINK;}
|
||||||
int issocket () {return path_flags & PATH_SOCKET;}
|
int issocket () {return path_flags & PATH_SOCKET;}
|
||||||
int isexec () {return path_flags & PATH_EXEC;}
|
int isexec () {return path_flags & PATH_ALL_EXEC;}
|
||||||
int iscygexec () {return path_flags & PATH_CYGWIN_EXEC;}
|
int iscygexec () {return path_flags & PATH_CYGWIN_EXEC;}
|
||||||
|
|
||||||
void set_binary () {path_flags |= PATH_BINARY;}
|
void set_binary () {path_flags |= PATH_BINARY;}
|
||||||
|
|
|
@ -258,6 +258,7 @@ pinfo::init (pid_t n, DWORD create, HANDLE in_h)
|
||||||
|
|
||||||
destroy = 1;
|
destroy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pinfo::release ()
|
pinfo::release ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,9 @@ public:
|
||||||
|
|
||||||
#define PINFO_REDIR_SIZE ((DWORD) &(((_pinfo *)NULL)->hProcess) + sizeof (DWORD))
|
#define PINFO_REDIR_SIZE ((DWORD) &(((_pinfo *)NULL)->hProcess) + sizeof (DWORD))
|
||||||
|
|
||||||
|
/* Handle associated with initial Windows pid which started it all. */
|
||||||
|
HANDLE pid_handle;
|
||||||
|
|
||||||
/* Parent process id. */
|
/* Parent process id. */
|
||||||
pid_t ppid;
|
pid_t ppid;
|
||||||
|
|
||||||
|
|
|
@ -236,6 +236,7 @@ proc_exists (_pinfo *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
sigproc_printf ("it doesn't exist");
|
sigproc_printf ("it doesn't exist");
|
||||||
|
#if 0
|
||||||
/* If the parent pid does not exist, clean this process out of the pinfo
|
/* If the parent pid does not exist, clean this process out of the pinfo
|
||||||
* table. It must have died abnormally.
|
* table. It must have died abnormally.
|
||||||
*/
|
*/
|
||||||
|
@ -244,6 +245,7 @@ proc_exists (_pinfo *p)
|
||||||
p->hProcess = NULL;
|
p->hProcess = NULL;
|
||||||
p->process_state = PID_NOT_IN_USE;
|
p->process_state = PID_NOT_IN_USE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,11 +305,15 @@ proc_subproc (DWORD what, DWORD val)
|
||||||
pchildren[nchildren] = vchild;
|
pchildren[nchildren] = vchild;
|
||||||
hchildren[nchildren] = vchild->hProcess;
|
hchildren[nchildren] = vchild->hProcess;
|
||||||
ProtectHandle1 (vchild->hProcess, childhProc);
|
ProtectHandle1 (vchild->hProcess, childhProc);
|
||||||
|
nchildren++;
|
||||||
|
if (!DuplicateHandle (hMainProc, vchild->hProcess, hMainProc, &vchild->pid_handle,
|
||||||
|
0, 0, DUPLICATE_SAME_ACCESS))
|
||||||
|
system_printf ("Couldn't duplicate child handle for pid %d, %E", vchild->pid);
|
||||||
|
ProtectHandle1 (vchild->pid_handle, pid_handle);
|
||||||
sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
|
sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
|
||||||
vchild->pid, nchildren, vchild->dwProcessId,
|
vchild->pid, nchildren, vchild->dwProcessId,
|
||||||
vchild->hProcess);
|
vchild->hProcess);
|
||||||
|
|
||||||
nchildren++;
|
|
||||||
wake_wait_subproc ();
|
wake_wait_subproc ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -351,6 +357,38 @@ proc_subproc (DWORD what, DWORD val)
|
||||||
clearing = 0;
|
clearing = 0;
|
||||||
goto scan_wait;
|
goto scan_wait;
|
||||||
|
|
||||||
|
/* Handle a wait4() operation. Allocates an event for the calling
|
||||||
|
* thread which is signaled when the appropriate pid exits or stops.
|
||||||
|
* (usually called from the main thread)
|
||||||
|
*/
|
||||||
|
case PROC_WAIT:
|
||||||
|
wval->ev = NULL; // Don't know event flag yet
|
||||||
|
|
||||||
|
if (wval->pid <= 0)
|
||||||
|
child = NULL; // Not looking for a specific pid
|
||||||
|
else if (!mychild (wval->pid))
|
||||||
|
goto out; // invalid pid. flag no such child
|
||||||
|
|
||||||
|
wval->status = 0; // Don't know status yet
|
||||||
|
sigproc_printf ("wval->pid %d, wval->options %d", wval->pid, wval->options);
|
||||||
|
|
||||||
|
/* If the first time for this thread, create a new event, otherwise
|
||||||
|
* reset the event.
|
||||||
|
*/
|
||||||
|
if ((wval->ev = wval->thread_ev) == NULL)
|
||||||
|
{
|
||||||
|
wval->ev = wval->thread_ev = CreateEvent (&sec_none_nih, TRUE,
|
||||||
|
FALSE, NULL);
|
||||||
|
ProtectHandle (wval->ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetEvent (wval->ev);
|
||||||
|
w = waitq_head.next;
|
||||||
|
waitq_head.next = wval; /* Add at the beginning. */
|
||||||
|
wval->next = w; /* Link in rest of the list. */
|
||||||
|
clearing = 0;
|
||||||
|
goto scan_wait;
|
||||||
|
|
||||||
/* Clear all waiting threads. Called from exceptions.cc prior to
|
/* Clear all waiting threads. Called from exceptions.cc prior to
|
||||||
* the main thread's dispatch to a signal handler function.
|
* the main thread's dispatch to a signal handler function.
|
||||||
* (called from wait_sig thread)
|
* (called from wait_sig thread)
|
||||||
|
@ -371,12 +409,13 @@ proc_subproc (DWORD what, DWORD val)
|
||||||
{
|
{
|
||||||
if ((potential_match = checkstate (w)) > 0)
|
if ((potential_match = checkstate (w)) > 0)
|
||||||
sigproc_printf ("released waiting thread");
|
sigproc_printf ("released waiting thread");
|
||||||
else if (!clearing && potential_match < 0)
|
else if (!clearing && !(w->next->options & WNOHANG) && potential_match < 0)
|
||||||
sigproc_printf ("only found non-terminated children");
|
sigproc_printf ("only found non-terminated children");
|
||||||
else if (potential_match <= 0) // nothing matched
|
else if (potential_match <= 0) // nothing matched
|
||||||
{
|
{
|
||||||
sigproc_printf ("waiting thread found no children");
|
sigproc_printf ("waiting thread found no children");
|
||||||
HANDLE oldw = w->next->ev;
|
HANDLE oldw = w->next->ev;
|
||||||
|
w->next->pid = 0;
|
||||||
if (clearing)
|
if (clearing)
|
||||||
w->next->status = -1; /* flag that a signal was received */
|
w->next->status = -1; /* flag that a signal was received */
|
||||||
else
|
else
|
||||||
|
@ -397,75 +436,6 @@ proc_subproc (DWORD what, DWORD val)
|
||||||
sigproc_printf ("finished clearing");
|
sigproc_printf ("finished clearing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Handle a wait4() operation. Allocates an event for the calling
|
|
||||||
* thread which is signaled when the appropriate pid exits or stops.
|
|
||||||
* (usually called from the main thread)
|
|
||||||
*/
|
|
||||||
case PROC_WAIT:
|
|
||||||
wval->ev = NULL; // Don't know event flag yet
|
|
||||||
|
|
||||||
if (wval->pid <= 0)
|
|
||||||
child = NULL; // Not looking for a specific pid
|
|
||||||
else if (!mychild (wval->pid))
|
|
||||||
goto out; // invalid pid. flag no such child
|
|
||||||
|
|
||||||
wval->status = 0; // Don't know status yet
|
|
||||||
|
|
||||||
/* Put waitq structure at the end of a linked list. */
|
|
||||||
for (w = &waitq_head; w->next != NULL; w = w->next)
|
|
||||||
if (w->next == wval && (w->next = w->next->next) == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
wval->next = NULL; /* This will be last in the list */
|
|
||||||
sigproc_printf ("wval->pid %d, wval->options %d", wval->pid, wval->options);
|
|
||||||
|
|
||||||
/* If the first time for this thread, create a new event, otherwise
|
|
||||||
* reset the event.
|
|
||||||
*/
|
|
||||||
if ((wval->ev = wval->thread_ev) == NULL)
|
|
||||||
{
|
|
||||||
wval->ev = wval->thread_ev = CreateEvent (&sec_none_nih, TRUE,
|
|
||||||
FALSE, NULL);
|
|
||||||
ProtectHandle (wval->ev);
|
|
||||||
}
|
|
||||||
ResetEvent (wval->ev);
|
|
||||||
|
|
||||||
/* Scan list of children to see if any have died.
|
|
||||||
* If so, the event flag is set so that the wait* ()
|
|
||||||
* process will return immediately.
|
|
||||||
*
|
|
||||||
* If no children were found and the wait option was WNOHANG,
|
|
||||||
* then set the pid to 0 and remove the waitq value from
|
|
||||||
* consideration.
|
|
||||||
*/
|
|
||||||
w->next = wval; /* set at end of wait queue */
|
|
||||||
if ((potential_match = checkstate (w)) <= 0)
|
|
||||||
{
|
|
||||||
if (!potential_match)
|
|
||||||
{
|
|
||||||
w->next = NULL; // don't want to keep looking
|
|
||||||
wval->ev = NULL; // flag that there are no children
|
|
||||||
sigproc_printf ("no appropriate children, %p, %p",
|
|
||||||
wval->thread_ev, wval->ev);
|
|
||||||
}
|
|
||||||
else if (wval->options & WNOHANG)
|
|
||||||
{
|
|
||||||
w->next = NULL; // don't want to keep looking
|
|
||||||
wval->pid = 0; // didn't find a pid
|
|
||||||
if (!SetEvent (wval->ev)) // wake up wait4 () immediately
|
|
||||||
system_printf ("Couldn't wake up wait event, %E");
|
|
||||||
sigproc_printf ("WNOHANG and no terminated children, %p, %p",
|
|
||||||
wval->thread_ev, wval->ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (w->next != NULL)
|
|
||||||
sigproc_printf ("wait activated %p, %p", wval->thread_ev, wval->ev);
|
|
||||||
else if (wval->ev != NULL)
|
|
||||||
sigproc_printf ("wait activated %p. Reaped zombie.", wval->ev);
|
|
||||||
else
|
|
||||||
sigproc_printf ("wait not activated %p, %p", wval->thread_ev, wval->ev);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -513,7 +483,7 @@ proc_terminate (void)
|
||||||
if (zombies[i]->hProcess)
|
if (zombies[i]->hProcess)
|
||||||
{
|
{
|
||||||
ForceCloseHandle1 (zombies[i]->hProcess, childhProc);
|
ForceCloseHandle1 (zombies[i]->hProcess, childhProc);
|
||||||
zombies[i]->hProcess = NULL;
|
ForceCloseHandle1 (zombies[i]->pid_handle, pid_handle);
|
||||||
}
|
}
|
||||||
zombies[i]->process_state = PID_NOT_IN_USE; /* CGF FIXME - still needed? */
|
zombies[i]->process_state = PID_NOT_IN_USE; /* CGF FIXME - still needed? */
|
||||||
zombies[i].release(); // FIXME: this breaks older gccs for some reason
|
zombies[i].release(); // FIXME: this breaks older gccs for some reason
|
||||||
|
@ -530,7 +500,6 @@ proc_terminate (void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
|
ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
|
||||||
pchildren[i]->hProcess = NULL;
|
|
||||||
if (!proc_exists (pchildren[i]))
|
if (!proc_exists (pchildren[i]))
|
||||||
{
|
{
|
||||||
sigproc_printf ("%d(%d) doesn't exist", pchildren[i]->pid,
|
sigproc_printf ("%d(%d) doesn't exist", pchildren[i]->pid,
|
||||||
|
@ -937,21 +906,22 @@ init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
|
||||||
* terminated.
|
* terminated.
|
||||||
*/
|
*/
|
||||||
static int __stdcall
|
static int __stdcall
|
||||||
checkstate (waitq *w)
|
checkstate (waitq *parent_w)
|
||||||
{
|
{
|
||||||
int i, x, potential_match = 0;
|
int potential_match = 0;
|
||||||
_pinfo *child;
|
|
||||||
|
|
||||||
sigproc_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
|
sigproc_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
|
||||||
|
|
||||||
/* Check already dead processes first to see if they match the criteria
|
/* Check already dead processes first to see if they match the criteria
|
||||||
* given in w->next.
|
* given in w->next.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < nzombies; i++)
|
for (int i = 0; i < nzombies; i++)
|
||||||
if ((x = stopped_or_terminated (w, child = zombies[i])) < 0)
|
switch (stopped_or_terminated (parent_w, zombies[i]))
|
||||||
potential_match = -1;
|
|
||||||
else if (x > 0)
|
|
||||||
{
|
{
|
||||||
|
case -1:
|
||||||
|
potential_match = -1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
remove_zombie (i);
|
remove_zombie (i);
|
||||||
potential_match = 1;
|
potential_match = 1;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -960,13 +930,15 @@ checkstate (waitq *w)
|
||||||
sigproc_printf ("checking alive children");
|
sigproc_printf ("checking alive children");
|
||||||
|
|
||||||
/* No dead terminated children matched. Check for stopped children. */
|
/* No dead terminated children matched. Check for stopped children. */
|
||||||
for (i = 0; i < nchildren; i++)
|
for (int i = 0; i < nchildren; i++)
|
||||||
if ((x = stopped_or_terminated (w, pchildren[i])) < 0)
|
switch (stopped_or_terminated (parent_w, pchildren[i]))
|
||||||
potential_match = -1;
|
|
||||||
else if (x > 0)
|
|
||||||
{
|
{
|
||||||
potential_match = 1;
|
case -1:
|
||||||
|
potential_match = -1;
|
||||||
break;
|
break;
|
||||||
|
case 1:
|
||||||
|
potential_match = 1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -1074,10 +1046,15 @@ static void __stdcall
|
||||||
remove_zombie (int ci)
|
remove_zombie (int ci)
|
||||||
{
|
{
|
||||||
sigproc_printf ("removing %d, pid %d, nzombies %d", ci, zombies[ci]->pid,
|
sigproc_printf ("removing %d, pid %d, nzombies %d", ci, zombies[ci]->pid,
|
||||||
nzombies);
|
nzombies);
|
||||||
|
|
||||||
if (zombies[ci])
|
if (zombies[ci])
|
||||||
zombies[ci].release ();
|
{
|
||||||
|
ForceCloseHandle1 (zombies[ci]->hProcess, childhProc);
|
||||||
|
ForceCloseHandle1 (zombies[ci]->pid_handle, pid_handle);
|
||||||
|
zombies[ci]->process_state = PID_NOT_IN_USE; /* a reaped child */
|
||||||
|
zombies[ci].release ();
|
||||||
|
}
|
||||||
|
|
||||||
if (ci < --nzombies)
|
if (ci < --nzombies)
|
||||||
zombies[ci] = zombies[nzombies];
|
zombies[ci] = zombies[nzombies];
|
||||||
|
@ -1146,9 +1123,6 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child)
|
||||||
add_rusage ((struct rusage *) w->rusage, &child->rusage_children);
|
add_rusage ((struct rusage *) w->rusage, &child->rusage_children);
|
||||||
add_rusage ((struct rusage *) w->rusage, &child->rusage_self);
|
add_rusage ((struct rusage *) w->rusage, &child->rusage_self);
|
||||||
}
|
}
|
||||||
ForceCloseHandle1 (child->hProcess, childhProc);
|
|
||||||
child->hProcess = NULL;
|
|
||||||
child->process_state = PID_NOT_IN_USE; /* a reaped child */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetEvent (w->ev)) /* wake up wait4 () immediately */
|
if (!SetEvent (w->ev)) /* wake up wait4 () immediately */
|
||||||
|
|
|
@ -687,14 +687,11 @@ skip_arg_parsing:
|
||||||
|
|
||||||
/* We print the original program name here so the user can see that too. */
|
/* We print the original program name here so the user can see that too. */
|
||||||
syscall_printf ("%d = spawn_guts (%s, %.132s)",
|
syscall_printf ("%d = spawn_guts (%s, %.132s)",
|
||||||
rc ? cygpid : (unsigned int) -1,
|
rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf);
|
||||||
prog_arg, one_line.buf);
|
|
||||||
|
|
||||||
MALLOC_CHECK;
|
|
||||||
/* Name the handle similarly to proc_subproc. */
|
/* Name the handle similarly to proc_subproc. */
|
||||||
ProtectHandle1 (pi.hProcess, childhProc);
|
ProtectHandle1 (pi.hProcess, childhProc);
|
||||||
ProtectHandle (pi.hThread);
|
ProtectHandle (pi.hThread);
|
||||||
MALLOC_CHECK;
|
|
||||||
|
|
||||||
if (mode == _P_OVERLAY)
|
if (mode == _P_OVERLAY)
|
||||||
{
|
{
|
||||||
|
@ -785,20 +782,16 @@ skip_arg_parsing:
|
||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
sigproc_printf ("subprocess exited");
|
sigproc_printf ("subprocess exited");
|
||||||
if (!GetExitCodeProcess (pi.hProcess, &res))
|
DWORD exitcode;
|
||||||
res = 1;
|
if (!GetExitCodeProcess (pi.hProcess, &exitcode))
|
||||||
|
exitcode = 1;
|
||||||
|
res |= exitcode;
|
||||||
exited = TRUE;
|
exited = TRUE;
|
||||||
|
|
||||||
if (nwait <= 2 || mode != _P_OVERLAY)
|
if (nwait <= 2 || (res & EXIT_REPARENTING) || (mode != _P_OVERLAY && mode != _P_VFORK))
|
||||||
/* nothing to do */;
|
/* nothing to do */;
|
||||||
else if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
|
else if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
|
||||||
goto reparent;
|
goto reparent;
|
||||||
else if (!(res & EXIT_REPARENTING))
|
|
||||||
{
|
|
||||||
MALLOC_CHECK;
|
|
||||||
close_all_files ();
|
|
||||||
MALLOC_CHECK;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_OBJECT_0 + 1:
|
||||||
sigproc_printf ("signal arrived");
|
sigproc_printf ("signal arrived");
|
||||||
|
@ -809,7 +802,6 @@ skip_arg_parsing:
|
||||||
{
|
{
|
||||||
reparent:
|
reparent:
|
||||||
res |= EXIT_REPARENTING;
|
res |= EXIT_REPARENTING;
|
||||||
close_all_files ();
|
|
||||||
if (!parent_alive)
|
if (!parent_alive)
|
||||||
{
|
{
|
||||||
nwait = 1;
|
nwait = 1;
|
||||||
|
@ -848,33 +840,37 @@ skip_arg_parsing:
|
||||||
/* nothing */;
|
/* nothing */;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int rc;
|
int rc = 0;
|
||||||
HANDLE hP = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
|
HANDLE oldh = myself->hProcess;
|
||||||
parent->dwProcessId);
|
HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
|
||||||
sigproc_printf ("parent handle %p, pid %d", hP, parent->dwProcessId);
|
parent->dwProcessId);
|
||||||
if (hP == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
|
sigproc_printf ("parent handle %p, pid %d", h, parent->dwProcessId);
|
||||||
|
if (h == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
|
||||||
rc = 1;
|
rc = 1;
|
||||||
else if (hP)
|
else if (h)
|
||||||
{
|
{
|
||||||
ProtectHandle (hP);
|
ProtectHandle (h);
|
||||||
rc = DuplicateHandle (hMainProc, pi.hProcess, hP,
|
rc = DuplicateHandle (hMainProc, pi.hProcess,
|
||||||
&myself->hProcess, 0, FALSE,
|
h, &myself->hProcess, 0, FALSE,
|
||||||
DUPLICATE_SAME_ACCESS);
|
DUPLICATE_SAME_ACCESS);
|
||||||
sigproc_printf ("Dup hP %d", rc);
|
sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
|
||||||
ForceCloseHandle (hP);
|
rc, oldh, myself->hProcess);
|
||||||
|
ForceCloseHandle (h);
|
||||||
}
|
}
|
||||||
if (!res)
|
if (!rc)
|
||||||
{
|
{
|
||||||
system_printf ("Reparent failed, parent handle %p, %E", hP);
|
system_printf ("Reparent failed, parent handle %p, %E", h);
|
||||||
system_printf ("my dwProcessId %d, myself->dwProcessId %d",
|
system_printf ("my dwProcessId %d, myself->dwProcessId %d",
|
||||||
GetCurrentProcessId(), myself->dwProcessId);
|
GetCurrentProcessId(), myself->dwProcessId);
|
||||||
system_printf ("myself->process_state %x",
|
system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess);
|
||||||
myself->process_state);
|
|
||||||
system_printf ("myself->hProcess %x", myself->hProcess);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ForceCloseHandle1 (hExeced, childhProc);
|
if (hExeced)
|
||||||
hExeced = INVALID_HANDLE_VALUE;
|
{
|
||||||
|
ForceCloseHandle1 (hExeced, childhProc);
|
||||||
|
hExeced = INVALID_HANDLE_VALUE;
|
||||||
|
close_all_files ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (exited)
|
else if (exited)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue