Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-11-15 09:27:48 +0300
committerChristopher Faylor <me@cgf.cx>2000-11-15 09:27:48 +0300
commit84aeff4126777c437a15c052f08be026f384ab70 (patch)
tree0d8fdcaf5f04948137e352b0f8b1e31e78925122 /winsup/cygwin/fork.cc
parentfb0a87573362f64e9c26036f8c887c930fa9ca6a (diff)
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.
Diffstat (limited to 'winsup/cygwin/fork.cc')
-rw-r--r--winsup/cygwin/fork.cc87
1 files changed, 71 insertions, 16 deletions
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 10c20040e..e3ac40475 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -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