* cygheap.cc (cygheap_fixup_in_child): Don't page round cygheap copied from

parent.
* dcrt0.cc (do_exit): Don't cleanup pinfo on exit.  That happens automatically
now.
* exceptions.cc (signal_exit): Ditto.
* fork.cc (fork_parent): Use stack_here value passed in from fork().
(fork): Figure out top of stack here and pass it to fork_parent.
* pinfo.cc (_pinfo::record_death): Eliminate.
* pinfo.h (_pinfo): Ditto.
* sigproc.cc (proc_exists): Simplify.
(proc_terminate): Ditto.
(remove_zombie): Don't cleanup pinfo stuff.
(wait_sig): Send subproc_ready signal whether execed or spawned.
* spawn.cc (spawn_guts): Always create subproc_ready event.  Use it for both
exec and spawn.
(_spawnve): Send proper mode to spawn_guts when mode != _P_OVERLAY.
This commit is contained in:
Christopher Faylor
2000-10-14 05:52:38 +00:00
parent cbe4c8e234
commit aece55b982
9 changed files with 154 additions and 244 deletions

View File

@@ -158,21 +158,6 @@ handle (int n, int direction)
return fh->get_output_handle ();
}
/* Cover function for CreateProcess.
This function is used by both the routines that search $PATH and those
that do not. This should work out ok as according to the documentation,
CreateProcess only searches $PATH if PROG has no directory elements.
Spawning doesn't fit well with Posix's fork/exec (one can argue the merits
of either but that's beside the point). If we're exec'ing we want to
record the child pid for fork. If we're spawn'ing we don't want to do
this. It is up to the caller to handle both cases.
The result is the process id. The handle of the created process is
stored in H.
*/
HANDLE NO_COPY hExeced = NULL;
int
@@ -252,7 +237,7 @@ public:
int argc;
av (int ac, const char * const *av) : calloced (0), argc (ac)
{
argv = (char **) cmalloc (HEAP_1_ARGV, (argc + 1) * sizeof (char *));
argv = (char **) cmalloc (HEAP_1_ARGV, (argc + 5) * sizeof (char *));
memcpy (argv, av, (argc + 1) * sizeof (char *));
}
~av ()
@@ -348,16 +333,14 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
si.lpReserved2 = (LPBYTE) &ciresrv;
si.cbReserved2 = sizeof (ciresrv);
HANDLE spr = NULL;
DWORD chtype;
if (mode != _P_OVERLAY && mode != _P_VFORK)
chtype = PROC_SPAWN;
else
{
spr = CreateEvent(&sec_all, TRUE, FALSE, NULL);
ProtectHandle (spr);
chtype = PROC_EXEC;
}
chtype = PROC_EXEC;
HANDLE 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,
@@ -555,8 +538,6 @@ skip_arg_parsing:
si.hStdError = handle (2, 1); /* Get output handle */
si.cb = sizeof (si);
/* Pass fd table to a child */
syscall_printf ("spawn_guts (%s, %.132s)", (char *) real_path, one_line.buf);
int flags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED |
@@ -696,8 +677,6 @@ skip_arg_parsing:
if (mode == _P_OVERLAY)
{
strcpy (myself->progname, real_path);
// close_all_files ();
proc_terminate ();
hExeced = pi.hProcess;
myself->dwProcessId = pi.dwProcessId;
@@ -765,127 +744,123 @@ skip_arg_parsing:
CloseHandle (hToken);
DWORD res;
BOOL exited;
if (mode == _P_OVERLAY || mode == _P_VFORK)
HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
int nwait = 3;
res = 0;
exited = FALSE;
MALLOC_CHECK;
for (int i = 0; i < 100; i++)
{
BOOL exited;
HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
int nwait = 3;
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
res = 0;
exited = FALSE;
MALLOC_CHECK;
for (int i = 0; i < 100; i++)
switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, INFINITE))
{
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;
case WAIT_OBJECT_0:
sigproc_printf ("subprocess exited");
DWORD exitcode;
if (!GetExitCodeProcess (pi.hProcess, &exitcode))
exitcode = 1;
res |= exitcode;
exited = TRUE;
if (nwait <= 2 || (res & EXIT_REPARENTING) || (mode != _P_OVERLAY && mode != _P_VFORK))
/* nothing to do */;
else if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
goto reparent;
break;
case WAIT_OBJECT_0 + 1:
sigproc_printf ("signal arrived");
ResetEvent (signal_arrived);
continue;
case WAIT_OBJECT_0 + 2:
if (mode == _P_OVERLAY)
if (nwait > 2 && !(res & EXIT_REPARENTING) &&
(mode == _P_OVERLAY || mode == _P_VFORK))
res |= EXIT_REPARENTING;
break;
case WAIT_OBJECT_0 + 1:
sigproc_printf ("signal arrived");
ResetEvent (signal_arrived);
continue;
case WAIT_OBJECT_0 + 2:
if (mode == _P_OVERLAY)
{
res |= EXIT_REPARENTING;
if (!parent_alive)
{
reparent:
res |= EXIT_REPARENTING;
if (!parent_alive)
{
nwait = 1;
sigproc_terminate ();
continue;
}
nwait = 1;
sigproc_terminate ();
continue;
}
break;
case WAIT_FAILED:
DWORD r;
system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E",
nwait, myself->pid, myself->dwProcessId);
system_printf ("waitbuf[0] %p %d", waitbuf[0],
GetHandleInformation (waitbuf[0], &r));
system_printf ("waitbuf[1] %p = %d", waitbuf[1],
GetHandleInformation (waitbuf[1], &r));
set_errno (ECHILD);
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 (res & EXIT_REPARENTING)
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.
*/
pinfo parent (myself->ppid);
if (!parent)
/* nothing */;
else
{
/* 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.
*/
pinfo parent (myself->ppid);
if (!parent)
/* nothing */;
else
int rc = 0;
HANDLE oldh = myself->hProcess;
HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
parent->dwProcessId);
sigproc_printf ("parent handle %p, pid %d", h, parent->dwProcessId);
if (h == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
rc = 1;
else if (h)
{
int rc = 0;
HANDLE oldh = myself->hProcess;
HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
parent->dwProcessId);
sigproc_printf ("parent handle %p, pid %d", h, parent->dwProcessId);
if (h == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
rc = 1;
else if (h)
{
ProtectHandle (h);
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);
ForceCloseHandle (h);
}
if (!rc)
{
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);
}
ProtectHandle (h);
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);
ForceCloseHandle (h);
}
if (hExeced)
if (!rc)
{
ForceCloseHandle1 (hExeced, childhProc);
hExeced = INVALID_HANDLE_VALUE;
close_all_files ();
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);
}
}
else if (exited)
if (hExeced)
{
ForceCloseHandle1 (hExeced, childhProc);
hExeced = INVALID_HANDLE_VALUE; // stop do_exit from attempting to terminate child
hExeced = INVALID_HANDLE_VALUE;
}
MALLOC_CHECK;
if (mode == _P_OVERLAY)
ExitProcess (res);
}
else if (exited)
{
ForceCloseHandle1 (hExeced, childhProc);
hExeced = INVALID_HANDLE_VALUE; // stop do_exit from attempting to terminate child
}
MALLOC_CHECK;
switch (mode)
{
case _P_OVERLAY:
proc_terminate ();
ExitProcess (0);
break;
case _P_WAIT:
waitpid (cygpid, (int *) &res, 0);
break;
@@ -945,7 +920,7 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
case _P_WAIT:
case _P_DETACH:
subproc_init ();
ret = spawn_guts (hToken, path, argv, envp, 0);
ret = spawn_guts (hToken, path, argv, envp, mode);
if (vf && ret > 0)
{
vf->pid = ret;