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:
parent
fb0a875733
commit
84aeff4126
@ -1,3 +1,23 @@
|
|||||||
|
Wed Nov 15 01:20:24 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
Wed Nov 15 0:51:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
Wed Nov 15 0:51:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* cygheap.cc (cygheap_root::cygheap_root): New function.
|
* cygheap.cc (cygheap_root::cygheap_root): New function.
|
||||||
|
@ -36,7 +36,6 @@ public:
|
|||||||
HANDLE subproc_ready; // used for synchronization with parent
|
HANDLE subproc_ready; // used for synchronization with parent
|
||||||
HANDLE shared_h;
|
HANDLE shared_h;
|
||||||
HANDLE console_h;
|
HANDLE console_h;
|
||||||
HANDLE parent_alive; // handle of thread used to track children
|
|
||||||
HANDLE parent;
|
HANDLE parent;
|
||||||
HANDLE pppid_handle;
|
HANDLE pppid_handle;
|
||||||
init_cygheap *cygheap;
|
init_cygheap *cygheap;
|
||||||
|
@ -56,7 +56,6 @@ BOOL display_title = FALSE;
|
|||||||
BOOL strip_title_path = FALSE;
|
BOOL strip_title_path = FALSE;
|
||||||
BOOL allow_glob = TRUE;
|
BOOL allow_glob = TRUE;
|
||||||
|
|
||||||
HANDLE NO_COPY parent_alive = NULL;
|
|
||||||
int cygwin_finished_initializing = 0;
|
int cygwin_finished_initializing = 0;
|
||||||
|
|
||||||
/* Used in SIGTOMASK for generating a bit for insertion into a sigset_t.
|
/* Used in SIGTOMASK for generating a bit for insertion into a sigset_t.
|
||||||
@ -739,7 +738,6 @@ dll_crt0_1 ()
|
|||||||
cygcwd.init ();
|
cygcwd.init ();
|
||||||
|
|
||||||
cygbench ("pre-forkee");
|
cygbench ("pre-forkee");
|
||||||
|
|
||||||
if (user_data->forkee)
|
if (user_data->forkee)
|
||||||
{
|
{
|
||||||
/* If we've played with the stack, stacksize != 0. That means that
|
/* If we've played with the stack, stacksize != 0. That means that
|
||||||
@ -758,6 +756,13 @@ dll_crt0_1 ()
|
|||||||
longjmp (fork_info->jmp, fork_info->cygpid);
|
longjmp (fork_info->jmp, fork_info->cygpid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUGGING
|
||||||
|
{
|
||||||
|
extern void fork_init ();
|
||||||
|
fork_init ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialize our process table entry. */
|
/* Initialize our process table entry. */
|
||||||
pinfo_init (envp, envc);
|
pinfo_init (envp, envc);
|
||||||
|
|
||||||
@ -910,16 +915,6 @@ _dll_crt0 ()
|
|||||||
mypid = child_proc_info->cygpid;
|
mypid = child_proc_info->cygpid;
|
||||||
cygwin_shared_h = child_proc_info->shared_h;
|
cygwin_shared_h = child_proc_info->shared_h;
|
||||||
console_shared_h = child_proc_info->console_h;
|
console_shared_h = child_proc_info->console_h;
|
||||||
|
|
||||||
/* We don't want subprocesses to inherit this */
|
|
||||||
if (dynamically_loaded)
|
|
||||||
parent_alive = NULL;
|
|
||||||
else if (!DuplicateHandle (hMainProc, child_proc_info->parent_alive,
|
|
||||||
hMainProc, &parent_alive, 0, 0,
|
|
||||||
DUPLICATE_SAME_ACCESS
|
|
||||||
| DUPLICATE_CLOSE_SOURCE))
|
|
||||||
system_printf ("parent_alive DuplicateHandle failed, %E");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -92,7 +92,7 @@ stdio_init (void)
|
|||||||
Also, always set them even if we're to pick up our parent's fds
|
Also, always set them even if we're to pick up our parent's fds
|
||||||
in case they're missed. */
|
in case they're missed. */
|
||||||
|
|
||||||
if (!parent_alive && NOTSTATE(myself, PID_CYGPARENT))
|
if (!myself->ppid_handle && NOTSTATE(myself, PID_CYGPARENT))
|
||||||
{
|
{
|
||||||
HANDLE in = GetStdHandle (STD_INPUT_HANDLE);
|
HANDLE in = GetStdHandle (STD_INPUT_HANDLE);
|
||||||
HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
|
HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||||
|
@ -632,7 +632,7 @@ environ_init (char **envp, int envc)
|
|||||||
char *eq;
|
char *eq;
|
||||||
if ((eq = strchr (newp, '=')) == NULL)
|
if ((eq = strchr (newp, '=')) == NULL)
|
||||||
eq = strchr (newp, '\0');
|
eq = strchr (newp, '\0');
|
||||||
if (!parent_alive)
|
if (!myself->ppid_handle)
|
||||||
ucenv (newp, eq);
|
ucenv (newp, eq);
|
||||||
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
|
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
|
||||||
sawTERM = 1;
|
sawTERM = 1;
|
||||||
|
@ -891,8 +891,8 @@ sig_handle_tty_stop (int sig)
|
|||||||
pinfo parent (myself->ppid);
|
pinfo parent (myself->ppid);
|
||||||
sig_send (parent, __SIGCHILDSTOPPED);
|
sig_send (parent, __SIGCHILDSTOPPED);
|
||||||
}
|
}
|
||||||
sigproc_printf ("process %d stopped by signal %d, parent_alive %p",
|
sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p",
|
||||||
myself->pid, sig, parent_alive);
|
myself->pid, sig, myself->ppid_handle);
|
||||||
/* There is a small race here with the above two mutexes */
|
/* There is a small race here with the above two mutexes */
|
||||||
SuspendThread (hMainThread);
|
SuspendThread (hMainThread);
|
||||||
return;
|
return;
|
||||||
|
@ -29,6 +29,12 @@ details. */
|
|||||||
#include "dll_init.h"
|
#include "dll_init.h"
|
||||||
#include "security.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;
|
DWORD NO_COPY chunksize = 0;
|
||||||
/* Timeout to wait for child to start, parent to init child, etc. */
|
/* Timeout to wait for child to start, parent to init child, etc. */
|
||||||
/* FIXME: Once things stabilize, bump up to a few minutes. */
|
/* 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->subproc_ready);
|
||||||
(void) ForceCloseHandle (child_proc_info->forker_finished);
|
(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");
|
api_fatal ("recreate_mmaps_after_fork_failed");
|
||||||
|
|
||||||
/* Set thread local stuff to zero. Under Windows 95/98 this is sometimes
|
/* 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;
|
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
|
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;
|
HANDLE subproc_ready, forker_finished;
|
||||||
DWORD rc;
|
DWORD rc;
|
||||||
PROCESS_INFORMATION pi = {0, NULL, 0, 0};
|
PROCESS_INFORMATION pi = {0, NULL, 0, 0};
|
||||||
static NO_COPY HANDLE last_fork_proc = NULL;
|
|
||||||
|
|
||||||
subproc_init ();
|
subproc_init ();
|
||||||
|
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING_NOTNEEDED
|
||||||
/* The ProtectHandle call allocates memory so we need to make sure
|
/* The ProtectHandle call allocates memory so we need to make sure
|
||||||
that enough is set aside here so that the sbrk pointer does not
|
that enough is set aside here so that the sbrk pointer does not
|
||||||
move when ProtectHandle is called after the child is started.
|
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 ())
|
if (fdtab.need_fixup_before ())
|
||||||
c_flags |= CREATE_SUSPENDED;
|
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;
|
hParent = NULL;
|
||||||
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, 1,
|
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, 1,
|
||||||
DUPLICATE_SAME_ACCESS))
|
DUPLICATE_SAME_ACCESS))
|
||||||
@ -407,6 +438,23 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
|
|||||||
ch.parent = hParent;
|
ch.parent = hParent;
|
||||||
ch.cygheap = cygheap;
|
ch.cygheap = cygheap;
|
||||||
ch.cygheap_max = cygheap_max;
|
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];
|
char sa_buf[1024];
|
||||||
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
|
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
|
||||||
@ -444,7 +492,11 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
|
|||||||
ResumeThread (pi.hThread);
|
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);
|
pinfo forked (cygwin_pid (pi.dwProcessId), 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialize things that are done later in dll_crt0_1 that aren't done
|
/* Initialize things that are done later in dll_crt0_1 that aren't done
|
||||||
for the forkee. */
|
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. */
|
be called in subproc handling. */
|
||||||
ProtectHandle1 (pi.hProcess, childhProc);
|
ProtectHandle1 (pi.hProcess, childhProc);
|
||||||
|
|
||||||
/* Keep a handle to the current forked process sitting around to prevent
|
slow_pid_reuse (pi.hProcess);
|
||||||
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");
|
|
||||||
|
|
||||||
/* Fill in fields in the child's process table entry. */
|
/* Fill in fields in the child's process table entry. */
|
||||||
forked->hProcess = pi.hProcess;
|
forked->hProcess = pi.hProcess;
|
||||||
forked->dwProcessId = pi.dwProcessId;
|
forked->dwProcessId = pi.dwProcessId;
|
||||||
forked->copysigs(myself);
|
forked->copysigs(myself);
|
||||||
set_child_mmap_ptr (forked);
|
|
||||||
forked.remember ();
|
forked.remember ();
|
||||||
|
|
||||||
/* Wait for subproc to initialize itself. */
|
/* Wait for subproc to initialize itself. */
|
||||||
@ -602,6 +644,19 @@ fork ()
|
|||||||
syscall_printf ("%d = fork()", res);
|
syscall_printf ("%d = fork()", res);
|
||||||
return 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
|
#ifdef NEWVFORK
|
||||||
/* Dummy function to force second assignment below to actually be
|
/* Dummy function to force second assignment below to actually be
|
||||||
|
@ -156,7 +156,7 @@ map::erase (int i)
|
|||||||
* needs to be specially handled by the fork code.
|
* needs to be specially handled by the fork code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static NO_COPY map *mmapped_areas;
|
static map *mmapped_areas;
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
caddr_t
|
caddr_t
|
||||||
@ -185,11 +185,11 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mmapped_areas == 0)
|
if (mmapped_areas == NULL)
|
||||||
{
|
{
|
||||||
/* First mmap call, create STL map */
|
/* First mmap call, create STL map */
|
||||||
mmapped_areas = new map;
|
mmapped_areas = new map;
|
||||||
if (mmapped_areas == 0)
|
if (mmapped_areas == NULL)
|
||||||
{
|
{
|
||||||
set_errno (ENOMEM);
|
set_errno (ENOMEM);
|
||||||
syscall_printf ("-1 = mmap(): ENOMEM");
|
syscall_printf ("-1 = mmap(): ENOMEM");
|
||||||
@ -271,9 +271,9 @@ munmap (caddr_t addr, size_t len)
|
|||||||
|
|
||||||
SetResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
|
SetResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
|
||||||
/* Check if a mmap'ed area was ever created */
|
/* Check if a mmap'ed area was ever created */
|
||||||
if (mmapped_areas == 0)
|
if (mmapped_areas == NULL)
|
||||||
{
|
{
|
||||||
syscall_printf ("-1 = munmap(): mmapped_areas == 0");
|
syscall_printf ("-1 = munmap(): mmapped_areas == NULL");
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
|
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
|
||||||
return -1;
|
return -1;
|
||||||
@ -344,9 +344,9 @@ msync (caddr_t addr, size_t len, int flags)
|
|||||||
|
|
||||||
SetResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
|
SetResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
|
||||||
/* Check if a mmap'ed area was ever created */
|
/* Check if a mmap'ed area was ever created */
|
||||||
if (mmapped_areas == 0)
|
if (mmapped_areas == NULL)
|
||||||
{
|
{
|
||||||
syscall_printf ("-1 = msync(): mmapped_areas == 0");
|
syscall_printf ("-1 = msync(): mmapped_areas == NULL");
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
|
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
|
||||||
return -1;
|
return -1;
|
||||||
@ -549,31 +549,26 @@ mprotect (caddr_t addr, size_t len, int prot)
|
|||||||
/*
|
/*
|
||||||
* Call to re-create all the file mappings in a forked
|
* Call to re-create all the file mappings in a forked
|
||||||
* child. Called from the child in initialization. At this
|
* child. Called from the child in initialization. At this
|
||||||
* point we are passed a valid mmaped_areas map, and all the
|
* point we are passed a valid mmapped_areas map, and all the
|
||||||
* HANDLE's are valid for the child, but none of the
|
* HANDLE's are valid for the child, but none of the
|
||||||
* mapped areas are in our address space. We need to iterate
|
* mapped areas are in our address space. We need to iterate
|
||||||
* through the map, doing the MapViewOfFile calls.
|
* through the map, doing the MapViewOfFile calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
recreate_mmaps_after_fork (void *param)
|
fixup_mmaps_after_fork ()
|
||||||
{
|
{
|
||||||
map *areas = (map *)param;
|
|
||||||
void *base;
|
|
||||||
|
|
||||||
debug_printf ("recreate_mmaps_after_fork, mmapped_areas %p", areas);
|
debug_printf ("recreate_mmaps_after_fork, mmapped_areas %p", mmapped_areas);
|
||||||
|
|
||||||
/* Check if a mmapped area was ever created */
|
/* Check if a mmapped area was ever created */
|
||||||
if (areas == 0)
|
if (mmapped_areas == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Iterate through the map */
|
/* Iterate through the map */
|
||||||
|
for (int it = 0; it < mmapped_areas->nlists; ++it)
|
||||||
int it;
|
|
||||||
|
|
||||||
for (it = 0; it < areas->nlists; ++it)
|
|
||||||
{
|
{
|
||||||
list *l = areas->lists[it];
|
list *l = mmapped_areas->lists[it];
|
||||||
if (l != 0)
|
if (l != 0)
|
||||||
{
|
{
|
||||||
int li;
|
int li;
|
||||||
@ -586,7 +581,7 @@ recreate_mmaps_after_fork (void *param)
|
|||||||
rec.get_size (), rec.get_address ());
|
rec.get_size (), rec.get_address ());
|
||||||
|
|
||||||
/* Now re-create the MapViewOfFileEx call */
|
/* Now re-create the MapViewOfFileEx call */
|
||||||
base = MapViewOfFileEx (rec.get_handle (),
|
void *base = MapViewOfFileEx (rec.get_handle (),
|
||||||
rec.get_access (), 0,
|
rec.get_access (), 0,
|
||||||
rec.get_offset (),
|
rec.get_offset (),
|
||||||
rec.get_size (),
|
rec.get_size (),
|
||||||
@ -601,19 +596,6 @@ recreate_mmaps_after_fork (void *param)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now set our mmap record in case the child forks. */
|
|
||||||
mmapped_areas = areas;
|
|
||||||
|
|
||||||
debug_printf ("succeeded");
|
debug_printf ("succeeded");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set a child mmap ptr from our static one. Used to set child mmap
|
|
||||||
pointer for fork. */
|
|
||||||
|
|
||||||
void __stdcall
|
|
||||||
set_child_mmap_ptr (_pinfo *child)
|
|
||||||
{
|
|
||||||
child->mmap_ptr = (void *) mmapped_areas;
|
|
||||||
}
|
|
||||||
|
@ -59,8 +59,6 @@ public:
|
|||||||
/* Used to spawn a child for fork(), among other things. */
|
/* Used to spawn a child for fork(), among other things. */
|
||||||
char progname[MAX_PATH];
|
char progname[MAX_PATH];
|
||||||
|
|
||||||
HANDLE parent_alive;
|
|
||||||
|
|
||||||
/* User information.
|
/* User information.
|
||||||
The information is derived from the GetUserName system call,
|
The information is derived from the GetUserName system call,
|
||||||
with the name looked up in /etc/passwd and assigned a default value
|
with the name looked up in /etc/passwd and assigned a default value
|
||||||
@ -83,8 +81,6 @@ public:
|
|||||||
long start_time;
|
long start_time;
|
||||||
struct rusage rusage_self;
|
struct rusage rusage_self;
|
||||||
struct rusage rusage_children;
|
struct rusage rusage_children;
|
||||||
/* Pointer to mmap'ed areas for this process. Set up by fork. */
|
|
||||||
void *mmap_ptr;
|
|
||||||
|
|
||||||
/* Non-zero if process was stopped by a signal. */
|
/* Non-zero if process was stopped by a signal. */
|
||||||
char stopsig;
|
char stopsig;
|
||||||
@ -209,8 +205,7 @@ extern void __stdcall pinfo_fixup_after_fork ();
|
|||||||
extern HANDLE hexec_proc;
|
extern HANDLE hexec_proc;
|
||||||
|
|
||||||
/* For mmaps across fork(). */
|
/* For mmaps across fork(). */
|
||||||
int __stdcall recreate_mmaps_after_fork (void *);
|
int __stdcall fixup_mmaps_after_fork ();
|
||||||
void __stdcall set_child_mmap_ptr (_pinfo *);
|
|
||||||
|
|
||||||
void __stdcall fill_rusage (struct rusage *, HANDLE);
|
void __stdcall fill_rusage (struct rusage *, HANDLE);
|
||||||
void __stdcall add_rusage (struct rusage *, struct rusage *);
|
void __stdcall add_rusage (struct rusage *, struct rusage *);
|
||||||
|
@ -128,14 +128,14 @@ BOOL __stdcall
|
|||||||
my_parent_is_alive ()
|
my_parent_is_alive ()
|
||||||
{
|
{
|
||||||
DWORD res;
|
DWORD res;
|
||||||
if (!parent_alive)
|
if (!myself->ppid_handle)
|
||||||
{
|
{
|
||||||
debug_printf ("No parent_alive mutex");
|
debug_printf ("No myself->ppid_handle");
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
switch (res = WaitForSingleObject (parent_alive, 0))
|
switch (res = WaitForSingleObject (myself->ppid_handle, 0))
|
||||||
{
|
{
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
debug_printf ("parent dead.");
|
debug_printf ("parent dead.");
|
||||||
@ -149,8 +149,8 @@ my_parent_is_alive ()
|
|||||||
DWORD werr = GetLastError ();
|
DWORD werr = GetLastError ();
|
||||||
if (werr == ERROR_INVALID_HANDLE && i == 0)
|
if (werr == ERROR_INVALID_HANDLE && i == 0)
|
||||||
continue;
|
continue;
|
||||||
system_printf ("WFSO for parent_alive(%p) failed, error %d",
|
system_printf ("WFSO for myself->ppid_handle(%p) failed, error %d",
|
||||||
parent_alive, werr);
|
myself->ppid_handle, werr);
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -304,6 +304,8 @@ proc_subproc (DWORD what, DWORD val)
|
|||||||
hchildren[val] = hchildren[nchildren];
|
hchildren[val] = hchildren[nchildren];
|
||||||
pchildren[val] = pchildren[nchildren];
|
pchildren[val] = pchildren[nchildren];
|
||||||
}
|
}
|
||||||
|
/* Don't scan the wait queue yet. Caller will send SIGCHLD to this process.
|
||||||
|
This will cause an eventual scan of waiters. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* A child is in the stopped state. Scan wait() queue to see if anyone
|
/* A child is in the stopped state. Scan wait() queue to see if anyone
|
||||||
@ -816,7 +818,6 @@ subproc_init (void)
|
|||||||
void __stdcall
|
void __stdcall
|
||||||
init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
|
init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
|
||||||
{
|
{
|
||||||
subproc_init ();
|
|
||||||
memset (ch, 0, sizeof *ch);
|
memset (ch, 0, sizeof *ch);
|
||||||
ch->cb = sizeof *ch;
|
ch->cb = sizeof *ch;
|
||||||
ch->type = chtype;
|
ch->type = chtype;
|
||||||
@ -825,11 +826,6 @@ init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
|
|||||||
ch->console_h = console_shared_h;
|
ch->console_h = console_shared_h;
|
||||||
ch->subproc_ready = subproc_ready;
|
ch->subproc_ready = subproc_ready;
|
||||||
ch->pppid_handle = myself->ppid_handle;
|
ch->pppid_handle = myself->ppid_handle;
|
||||||
if (chtype != PROC_EXEC || !parent_alive)
|
|
||||||
ch->parent_alive = hwait_subproc;
|
|
||||||
else
|
|
||||||
DuplicateHandle (hMainProc, parent_alive, hMainProc, &ch->parent_alive,
|
|
||||||
0, 1, DUPLICATE_SAME_ACCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the state of all of our children to see if any are stopped or
|
/* Check the state of all of our children to see if any are stopped or
|
||||||
|
@ -78,9 +78,6 @@ public:
|
|||||||
extern sigthread mainthread;
|
extern sigthread mainthread;
|
||||||
extern HANDLE signal_arrived;
|
extern HANDLE signal_arrived;
|
||||||
|
|
||||||
/* non-NULL if this process is a child of a cygwin process */
|
|
||||||
extern HANDLE parent_alive;
|
|
||||||
|
|
||||||
BOOL __stdcall my_parent_is_alive ();
|
BOOL __stdcall my_parent_is_alive ();
|
||||||
extern "C" int __stdcall sig_dispatch_pending (int force = FALSE);
|
extern "C" int __stdcall sig_dispatch_pending (int force = FALSE);
|
||||||
extern "C" void __stdcall set_process_mask (sigset_t newmask);
|
extern "C" void __stdcall set_process_mask (sigset_t newmask);
|
||||||
|
@ -754,7 +754,7 @@ skip_arg_parsing:
|
|||||||
if (mode == _P_OVERLAY)
|
if (mode == _P_OVERLAY)
|
||||||
{
|
{
|
||||||
res |= EXIT_REPARENTING;
|
res |= EXIT_REPARENTING;
|
||||||
if (!parent_alive)
|
if (!my_parent_is_alive ())
|
||||||
{
|
{
|
||||||
nwait = 1;
|
nwait = 1;
|
||||||
sigproc_terminate ();
|
sigproc_terminate ();
|
||||||
@ -789,26 +789,14 @@ skip_arg_parsing:
|
|||||||
* EXIT_REPARENTING status. Wait() syscall in parent will then wait
|
* EXIT_REPARENTING status. Wait() syscall in parent will then wait
|
||||||
* for newly created child.
|
* for newly created child.
|
||||||
*/
|
*/
|
||||||
pinfo parent (myself->ppid);
|
|
||||||
if (!parent)
|
|
||||||
/* nothing */;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
HANDLE oldh = myself->hProcess;
|
HANDLE oldh = myself->hProcess;
|
||||||
HANDLE h = myself->ppid_handle;
|
HANDLE h = myself->ppid_handle;
|
||||||
sigproc_printf ("parent handle %p, pid %d", h, parent->dwProcessId);
|
sigproc_printf ("parent handle %p", h);
|
||||||
if (h == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
|
int rc = DuplicateHandle (hMainProc, pi.hProcess, h, &myself->hProcess,
|
||||||
rc = 0;
|
0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||||
else if (h)
|
|
||||||
{
|
|
||||||
rc = DuplicateHandle (hMainProc, pi.hProcess,
|
|
||||||
h, &myself->hProcess, 0, FALSE,
|
|
||||||
DUPLICATE_SAME_ACCESS);
|
|
||||||
sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
|
sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
|
||||||
rc, oldh, myself->hProcess);
|
rc, oldh, myself->hProcess);
|
||||||
}
|
if (!rc && my_parent_is_alive ())
|
||||||
if (!rc)
|
|
||||||
{
|
{
|
||||||
system_printf ("Reparent failed, parent handle %p, %E", h);
|
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",
|
||||||
@ -816,7 +804,6 @@ skip_arg_parsing:
|
|||||||
system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess);
|
system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
|
|
||||||
|
@ -52,7 +52,6 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
|||||||
HANDLE waitfor;
|
HANDLE waitfor;
|
||||||
sigframe thisframe (mainthread);
|
sigframe thisframe (mainthread);
|
||||||
|
|
||||||
sigproc_printf ("here");
|
|
||||||
if (options & ~(WNOHANG | WUNTRACED))
|
if (options & ~(WNOHANG | WUNTRACED))
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user