Throughout use myself->ppid_handle rather than parent_alive.

* child_info.h (child_info): Eliminate parent_alive.
* dcrt0.cc (dll_crt0_1): Call fork_init for debugging pid creation.
* fork.cc (fork_child): Reflect change to fixup_mmaps_after_fork arguments.
(slow_pid_reuse): New function to grab last 'n' pids to prevent pid reuse.
(fork_parent): Move last_fork_proc into slow_pid_reuse.  Handle fork_pids
debugging.  Eliminate unnecessary call to set_child_mmap_ptr.
(fork_init): New debugging function.
* mmap.cc (fixup_mmaps_after_fork): Renamed from recreate_mmaps_after_fork.
Rely on copied data after a fork.
(set_child_mmap_ptr): Eliminate.
* pinfo.h (_pinfo): Eliminate parent_alive, mmap_ptr and reflect above changes.
* spawn.cc (spawn_guts): Eliminate vestiges of "old way" of sending new hProc
to parent process.
This commit is contained in:
Christopher Faylor
2000-11-15 06:27:48 +00:00
parent fb0a875733
commit 84aeff4126
13 changed files with 144 additions and 119 deletions

View File

@ -29,6 +29,12 @@ details. */
#include "dll_init.h"
#include "security.h"
#ifdef DEBUGGING
static int npid = 0;
static int npid_max = 0;
static pid_t fork_pids[100] = {0};
#endif
DWORD NO_COPY chunksize = 0;
/* Timeout to wait for child to start, parent to init child, etc. */
/* FIXME: Once things stabilize, bump up to a few minutes. */
@ -289,7 +295,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
(void) ForceCloseHandle (child_proc_info->subproc_ready);
(void) ForceCloseHandle (child_proc_info->forker_finished);
if (recreate_mmaps_after_fork (myself->mmap_ptr))
if (fixup_mmaps_after_fork ())
api_fatal ("recreate_mmaps_after_fork_failed");
/* Set thread local stuff to zero. Under Windows 95/98 this is sometimes
@ -305,17 +311,40 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
return 0;
}
static void
slow_pid_reuse (HANDLE h)
{
static NO_COPY HANDLE last_fork_procs[64];
static NO_COPY unsigned nfork_procs = 0;
if (nfork_procs > (sizeof (last_fork_procs) / sizeof (last_fork_procs [0])))
nfork_procs = 0;
/* Keep a list of handles to forked processes sitting around to prevent
Windows from reusing the same pid n times in a row. Having the same pids
close in succesion confuses bash. Keeping a handle open will stop
windows from reusing the same pid. */
if (last_fork_procs[nfork_procs])
CloseHandle (last_fork_procs[nfork_procs]);
if (!DuplicateHandle (hMainProc, h, hMainProc, &last_fork_procs[nfork_procs],
0, FALSE, DUPLICATE_SAME_ACCESS))
{
last_fork_procs[nfork_procs] = NULL;
system_printf ("couldn't create last_fork_proc, %E");
}
nfork_procs++;
}
static int __stdcall
fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls, child_info_fork &ch)
fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll,
bool& load_dlls, child_info_fork &ch)
{
HANDLE subproc_ready, forker_finished;
DWORD rc;
PROCESS_INFORMATION pi = {0, NULL, 0, 0};
static NO_COPY HANDLE last_fork_proc = NULL;
subproc_init ();
#ifdef DEBUGGING
#ifdef DEBUGGING_NOTNEEDED
/* The ProtectHandle call allocates memory so we need to make sure
that enough is set aside here so that the sbrk pointer does not
move when ProtectHandle is called after the child is started.
@ -348,6 +377,8 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
if (fdtab.need_fixup_before ())
c_flags |= CREATE_SUSPENDED;
/* Create an inheritable handle to pass to the child process. This will
allow the child to duplicate handles from the parent to itself. */
hParent = NULL;
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, 1,
DUPLICATE_SAME_ACCESS))
@ -407,6 +438,23 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
ch.parent = hParent;
ch.cygheap = cygheap;
ch.cygheap_max = cygheap_max;
#ifdef DEBUGGING
if (npid_max)
{
for (int pass = 0; pass < 2; pass++)
{
pid_t pid;
while ((pid = fork_pids[npid++]))
if (!pinfo (pid))
{
ch.cygpid = pid;
goto out;
}
npid = 0;
}
}
out:
#endif
char sa_buf[1024];
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
@ -418,7 +466,7 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
TRUE, /* inherit handles from parent */
c_flags,
NULL, /* environment filled in later */
0, /* use current drive/directory */
0, /* use current drive/directory */
&si,
&pi);
@ -444,7 +492,11 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
ResumeThread (pi.hThread);
}
#ifdef DEBUGGING
pinfo forked ((ch.cygpid != 1 ? ch.cygpid : cygwin_pid (pi.dwProcessId)), 1);
#else
pinfo forked (cygwin_pid (pi.dwProcessId), 1);
#endif
/* Initialize things that are done later in dll_crt0_1 that aren't done
for the forkee. */
@ -459,22 +511,12 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
be called in subproc handling. */
ProtectHandle1 (pi.hProcess, childhProc);
/* Keep a handle to the current forked process sitting around to prevent
Windows from reusing the same pid twice in a row. Having the same pid
twice in a row confuses bash. So, after every CreateProcess, we can safely
remove the old pid and save a handle to the newly created process. Keeping
a handle open will stop windows from reusing the same pid. */
if (last_fork_proc)
CloseHandle (last_fork_proc);
if (!DuplicateHandle (hMainProc, pi.hProcess, hMainProc, &last_fork_proc,
0, FALSE, DUPLICATE_SAME_ACCESS))
system_printf ("couldn't create last_fork_proc, %E");
slow_pid_reuse (pi.hProcess);
/* Fill in fields in the child's process table entry. */
forked->hProcess = pi.hProcess;
forked->dwProcessId = pi.dwProcessId;
forked->copysigs(myself);
set_child_mmap_ptr (forked);
forked.remember ();
/* Wait for subproc to initialize itself. */
@ -602,6 +644,19 @@ fork ()
syscall_printf ("%d = fork()", res);
return res;
}
#ifdef DEBUGGING
void
fork_init ()
{
char buf[1024];
if (!GetEnvironmentVariable ("CYGWIN_FORK_PIDS", buf, 1024))
return;
pid_t pid;
char *p, *pe;
for (p = buf; (pid = strtol (p, &pe, 10)); p = pe)
fork_pids[npid_max++] = pid;
}
#endif /*DEBUGGING*/
#ifdef NEWVFORK
/* Dummy function to force second assignment below to actually be