* child_info.h: Bump magic number.
(class child_info): Add an element. * cygheap.cc (init_cheap): Allocate cygwin heap in shared memory area. (cygheap_fixup_in_child): Map cygwin heap, passed from parent via shared memory into correct address. (cygheap_setup_for_child): New function. * cygheap.h: Declare new functions. * dcrt0.cc (dll_crt0_1): Accomodate new cygheap_fixup_in_child arguments. Avoid protecting subproc_ready unless it is spawn/nowait. * fork.cc (fork_parent): Use new cygheap_setup_for_child function to setup cygwin heap info. Close passed cygheap shared memory handle. * spawn.cc (spawn_guts): Ditto. Also, reorganize to avoid synchronization between parent and child in non-P_OVERLAY case. * sigproc.cc (wait_sig): Only signal subproc_ready when execing.
This commit is contained in:
@ -327,8 +327,14 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
|
||||
else
|
||||
chtype = PROC_EXEC;
|
||||
|
||||
HANDLE spr = CreateEvent (&sec_all, TRUE, FALSE, NULL);
|
||||
ProtectHandle (spr);
|
||||
HANDLE spr;
|
||||
if (mode != _P_OVERLAY)
|
||||
spr = NULL;
|
||||
else
|
||||
{
|
||||
spr = CreateEvent (&sec_all, TRUE, FALSE, NULL);
|
||||
ProtectHandle (spr);
|
||||
}
|
||||
|
||||
init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr);
|
||||
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &ciresrv.parent, 0, 1,
|
||||
@ -572,8 +578,7 @@ skip_arg_parsing:
|
||||
else
|
||||
envblock = winenv (envp, 0);
|
||||
|
||||
ciresrv.cygheap = cygheap;
|
||||
ciresrv.cygheap_max = cygheap_max;
|
||||
cygheap_setup_for_child (&ciresrv);
|
||||
|
||||
/* Preallocated buffer for `sec_user' call */
|
||||
char sa_buf[1024];
|
||||
@ -669,6 +674,7 @@ skip_arg_parsing:
|
||||
MALLOC_CHECK;
|
||||
if (envblock)
|
||||
free (envblock);
|
||||
ForceCloseHandle1 (ciresrv.cygheap_h, passed_cygheap_h);
|
||||
MALLOC_CHECK;
|
||||
|
||||
/* Set errno now so that debugging messages from it appear before our
|
||||
@ -741,88 +747,83 @@ skip_arg_parsing:
|
||||
DWORD res;
|
||||
BOOL exited;
|
||||
|
||||
HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
|
||||
int nwait = 3;
|
||||
bool saw_signal = 0;
|
||||
|
||||
res = 0;
|
||||
exited = FALSE;
|
||||
MALLOC_CHECK;
|
||||
for (int i = 0; i < 100; i++)
|
||||
if (mode == _P_OVERLAY)
|
||||
{
|
||||
switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, INFINITE))
|
||||
int nwait = 3;
|
||||
HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
sigproc_printf ("subprocess exited");
|
||||
DWORD exitcode;
|
||||
if (!GetExitCodeProcess (pi.hProcess, &exitcode))
|
||||
exitcode = 1;
|
||||
res |= exitcode;
|
||||
exited = TRUE;
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
sigproc_printf ("signal arrived");
|
||||
reset_signal_arrived ();
|
||||
saw_signal = 1;
|
||||
continue;
|
||||
case WAIT_OBJECT_0 + 2:
|
||||
if (mode == _P_OVERLAY)
|
||||
switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
sigproc_printf ("subprocess exited");
|
||||
DWORD exitcode;
|
||||
if (!GetExitCodeProcess (pi.hProcess, &exitcode))
|
||||
exitcode = 1;
|
||||
res |= exitcode;
|
||||
exited = TRUE;
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
sigproc_printf ("signal arrived");
|
||||
reset_signal_arrived ();
|
||||
continue;
|
||||
case WAIT_OBJECT_0 + 2:
|
||||
if (myself->ppid_handle)
|
||||
res |= EXIT_REPARENTING;
|
||||
if (!my_parent_is_alive ())
|
||||
{
|
||||
nwait = 1;
|
||||
nwait = 2;
|
||||
sigproc_terminate ();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case WAIT_FAILED:
|
||||
system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E",
|
||||
nwait, myself->pid, myself->dwProcessId);
|
||||
system_printf ("waitbuf[0] %p %d", waitbuf[0],
|
||||
WaitForSingleObject (waitbuf[0], 0));
|
||||
system_printf ("waitbuf[1] %p = %d", waitbuf[1],
|
||||
WaitForSingleObject (waitbuf[1], 0));
|
||||
system_printf ("waitbuf[w] %p = %d", waitbuf[2],
|
||||
WaitForSingleObject (waitbuf[2], 0));
|
||||
set_errno (ECHILD);
|
||||
try_to_debug ();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case WAIT_FAILED:
|
||||
system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E",
|
||||
nwait, myself->pid, myself->dwProcessId);
|
||||
system_printf ("waitbuf[0] %p %d", waitbuf[0],
|
||||
WaitForSingleObject (waitbuf[0], 0));
|
||||
system_printf ("waitbuf[1] %p = %d", waitbuf[1],
|
||||
WaitForSingleObject (waitbuf[1], 0));
|
||||
system_printf ("waitbuf[w] %p = %d", waitbuf[2],
|
||||
WaitForSingleObject (waitbuf[2], 0));
|
||||
set_errno (ECHILD);
|
||||
try_to_debug ();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ForceCloseHandle (spr);
|
||||
ForceCloseHandle (spr);
|
||||
|
||||
sigproc_printf ("res = %x", res);
|
||||
sigproc_printf ("res = %x", res);
|
||||
|
||||
if (mode == _P_OVERLAY && (res & EXIT_REPARENTING))
|
||||
{
|
||||
/* Try to reparent child process.
|
||||
* Make handles to child available to parent process and exit with
|
||||
* EXIT_REPARENTING status. Wait() syscall in parent will then wait
|
||||
* for newly created child.
|
||||
*/
|
||||
HANDLE oldh = myself->hProcess;
|
||||
HANDLE h = myself->ppid_handle;
|
||||
sigproc_printf ("parent handle %p", h);
|
||||
int rc = DuplicateHandle (hMainProc, pi.hProcess, h, &myself->hProcess,
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
|
||||
rc, oldh, myself->hProcess);
|
||||
if (!rc && my_parent_is_alive ())
|
||||
if (res & EXIT_REPARENTING)
|
||||
{
|
||||
system_printf ("Reparent failed, parent handle %p, %E", h);
|
||||
system_printf ("my dwProcessId %d, myself->dwProcessId %d",
|
||||
GetCurrentProcessId (), myself->dwProcessId);
|
||||
system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess);
|
||||
/* Try to reparent child process.
|
||||
* Make handles to child available to parent process and exit with
|
||||
* EXIT_REPARENTING status. Wait() syscall in parent will then wait
|
||||
* for newly created child.
|
||||
*/
|
||||
HANDLE oldh = myself->hProcess;
|
||||
HANDLE h = myself->ppid_handle;
|
||||
sigproc_printf ("parent handle %p", h);
|
||||
int rc = DuplicateHandle (hMainProc, pi.hProcess, h, &myself->hProcess,
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
|
||||
rc, oldh, myself->hProcess);
|
||||
if (!rc && my_parent_is_alive ())
|
||||
{
|
||||
system_printf ("Reparent failed, parent handle %p, %E", h);
|
||||
system_printf ("my dwProcessId %d, myself->dwProcessId %d",
|
||||
GetCurrentProcessId (), myself->dwProcessId);
|
||||
system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (saw_signal && mode != _P_OVERLAY)
|
||||
thisframe.call_signal_handler ();
|
||||
}
|
||||
|
||||
MALLOC_CHECK;
|
||||
|
||||
|
Reference in New Issue
Block a user