* include/cygwin/version.h: Bump DLL minor version number to 5 due to all of
the changes below. Redefine process structure to avoid a fixed size table. Redefine pinfo/_pinfo classes. Use these throughout. * dcrt0.cc (dll_crt0_1): Accomodate set_myself argument change. (__api_fatal): Accomodate _pinfo::record_death argument change. * exceptions.cc (really_exit): Ditto. (sig_handle_tty_stop): Use pinfo constructor to access process info. (events_init): Don't create pinfo_mutex since it is no longer required. * external.cc (fillout_pinfo): Use winpids class to iterate over all system pids. (cygwin_internal): lock_pinfo_for_update and unlock_pinfo are now noops. * fhandler_termios.cc (fhandler_termios::set_ctty): Use pinfo constructor to access process info. * fork.cc (fork): Reorganize to initialize child info after the child has started since that is when we know the child's winpid, which is necessary to allocate the pinfo shared memory. * mmap.cc (recreate_mmaps_after_fork): Change arg type to _pinfo. * pinfo.cc: Rename pinfo methods to _pinfo throughout. Eliminate pinfo_list stuff. (set_myself): Accept a pid argument now. Call pinfo initializer to initialize myself. Detect when this is an "execed" process and create an "indirect" pid block. (pinfo_init): Accomodate set_myself arg change. (procinfo): Remove. (pinfo::lock_pinfo): Remove. (pinfo::unlock_pinfo): Remove. (pinfo::init): New method. Allocates shared memory space for process pinfo structure. (pinfo::record_death): Don't call locking functions. (cygwin_winpid_to_pid): Simplify by using new pinfo constructor. (EnumProcessesW95): New function for iterating over processes on Windows 95. (winpids::winpids): New constructor for winpids class. Sets up a list of process ids. (enum_init): Initialize w95/wnt pid enumerators. * shared.cc (shared-info::initialize): Remove pid initialization. * shared.h: Move pinfo stuff into pinfo.h. (class shared_info): Remove pinfo_list element. * signal.cc (kill_worker): Use pinfo constructor to access process info. (kill_pgrp): Ditto. Use winpids methods to access list of processes. * sigproc.cc: Throughout, modify to use _pinfo where appropriate. (proc_exists (pid_t)): New function. Determines if a process exists based on the pid. (proc_exists (_pinfo *p): Use new proc_exists function above. (proc_subproc): Copy pinfo stuff around rather than _pinfo pointers. Try to be careful about releasing shared memory when we don't need it anymore. Remove pinfo locks. (remove_zombies): Remove pinfo memory when zombie is going away. * sigproc.h: Reflect _pinfo/pinfo changes in sigproc.cc. * spawn.cc (spawn_guts): Eliminate pinfo *child argument. Reorganize to only initialize child pinfo after process has been started and we know the windows pid. (_spawnve): Reflect spawn_guts changes. * syscalls.cc (setpgid): Use pinfo constructor to access process info. (getpgid): Ditto. (internal_getlogin): Use _pinfo. * winsup.h: Eliminate pinfo_mutex. Eliminate spawn_guts declaration since it is static now. Reflect set_myself argument change. * include/sys/cygwin.h: Add some PID_* enums to accomodate new pinfo stuff. * include/cygwin/version.h: Update minor version for cygdrive changes below.
This commit is contained in:
@@ -90,8 +90,8 @@ Static HANDLE wait_sig_inited = NULL; // Control synchronization of
|
||||
*/
|
||||
Static HANDLE events[PSIZE + 1] = {0}; // All my children's handles++
|
||||
#define hchildren (events + 1) // Where the children handles begin
|
||||
Static pinfo *pchildren[PSIZE] = {NULL};// All my children info
|
||||
Static pinfo *zombies[PSIZE] = {NULL}; // All my deceased children info
|
||||
Static pinfo pchildren[PSIZE] = {pinfo ()};// All my children info
|
||||
Static pinfo zombies[PSIZE] = {pinfo ()}; // All my deceased children info
|
||||
Static int nchildren = 0; // Number of active children
|
||||
Static int nzombies = 0; // Number of deceased children
|
||||
|
||||
@@ -108,11 +108,11 @@ int NO_COPY pending_signals = 0; // TRUE if signals pending
|
||||
*/
|
||||
static int __stdcall checkstate (waitq *);
|
||||
static __inline__ BOOL get_proc_lock (DWORD, DWORD);
|
||||
static HANDLE __stdcall getsem (pinfo *, const char *, int, int);
|
||||
static HANDLE __stdcall getsem (_pinfo *, const char *, int, int);
|
||||
static void __stdcall remove_child (int);
|
||||
static void __stdcall remove_zombie (int);
|
||||
static DWORD WINAPI wait_sig (VOID *arg);
|
||||
static int __stdcall stopped_or_terminated (waitq *, pinfo *);
|
||||
static int __stdcall stopped_or_terminated (waitq *, _pinfo *);
|
||||
static DWORD WINAPI wait_subproc (VOID *);
|
||||
|
||||
/* Determine if the parent process is alive.
|
||||
@@ -168,7 +168,7 @@ wait_for_me ()
|
||||
}
|
||||
|
||||
static BOOL __stdcall
|
||||
proc_can_be_signalled (pinfo *p)
|
||||
proc_can_be_signalled (_pinfo *p)
|
||||
{
|
||||
if (p == myself_nowait || p == myself_nowait_nonmain || p == myself)
|
||||
{
|
||||
@@ -181,11 +181,18 @@ proc_can_be_signalled (pinfo *p)
|
||||
(PID_ACTIVE | PID_IN_USE));
|
||||
}
|
||||
|
||||
BOOL __stdcall
|
||||
proc_exists (pid_t pid)
|
||||
{
|
||||
pinfo p (pid);
|
||||
return proc_exists (p);
|
||||
}
|
||||
|
||||
/* Test to determine if a process really exists and is processing
|
||||
* signals.
|
||||
*/
|
||||
BOOL __stdcall
|
||||
proc_exists (pinfo *p)
|
||||
proc_exists (_pinfo *p)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
@@ -225,7 +232,7 @@ proc_exists (pinfo *p)
|
||||
/* If the parent pid does not exist, clean this process out of the pinfo
|
||||
* table. It must have died abnormally.
|
||||
*/
|
||||
if ((p->pid == p->ppid) || (p->ppid == 1) || !proc_exists (procinfo (p->ppid)))
|
||||
if ((p->pid == p->ppid) || (p->ppid == 1) || !proc_exists (p->ppid))
|
||||
{
|
||||
p->hProcess = NULL;
|
||||
p->process_state = PID_NOT_IN_USE;
|
||||
@@ -235,14 +242,14 @@ proc_exists (pinfo *p)
|
||||
|
||||
/* Handle all subprocess requests
|
||||
*/
|
||||
#define vchild ((pinfo *) val)
|
||||
#define vchild (*((pinfo *) val))
|
||||
int __stdcall
|
||||
proc_subproc (DWORD what, DWORD val)
|
||||
{
|
||||
int rc = 1;
|
||||
int potential_match;
|
||||
DWORD exitcode;
|
||||
pinfo *child;
|
||||
_pinfo *child;
|
||||
int clearing;
|
||||
waitq *w;
|
||||
|
||||
@@ -292,23 +299,22 @@ proc_subproc (DWORD what, DWORD val)
|
||||
*/
|
||||
case PROC_CHILDTERMINATED:
|
||||
rc = 0;
|
||||
child = pchildren[val];
|
||||
if (GetExitCodeProcess (hchildren[val], &exitcode) &&
|
||||
hchildren[val] != child->hProcess)
|
||||
hchildren[val] != pchildren[val]->hProcess)
|
||||
{
|
||||
sip_printf ("pid %d[%d], reparented old hProcess %p, new %p",
|
||||
child->pid, val, hchildren[val], child->hProcess);
|
||||
pchildren[val]->pid, val, hchildren[val], pchildren[val]->hProcess);
|
||||
ForceCloseHandle1 (hchildren[val], childhProc);
|
||||
hchildren[val] = child->hProcess; /* Filled out by child */
|
||||
ProtectHandle1 (child->hProcess, childhProc);
|
||||
hchildren[val] = pchildren[val]->hProcess; /* Filled out by child */
|
||||
ProtectHandle1 (pchildren[val]->hProcess, childhProc);
|
||||
break; // This was an exec()
|
||||
}
|
||||
|
||||
sip_printf ("pid %d[%d] terminated, handle %p, nchildren %d, nzombies %d",
|
||||
child->pid, val, hchildren[val], nchildren, nzombies);
|
||||
remove_child (val); // Remove from children arrays
|
||||
zombies[nzombies++] = child; // Add to zombie array
|
||||
child->process_state = PID_ZOMBIE;// Walking dead
|
||||
pchildren[val]->pid, val, hchildren[val], nchildren, nzombies);
|
||||
zombies[nzombies] = pchildren[val]; // Add to zombie array
|
||||
zombies[nzombies++]->process_state = PID_ZOMBIE;// Walking dead
|
||||
remove_child (val); // Remove from children array
|
||||
if (!proc_loop_wait) // Don't bother if wait_subproc is
|
||||
break; // exiting
|
||||
|
||||
@@ -381,7 +387,7 @@ proc_subproc (DWORD what, DWORD val)
|
||||
|
||||
if (wval->pid <= 0)
|
||||
child = NULL; // Not looking for a specific pid
|
||||
else if ((child = procinfo (wval->pid)) == NULL)
|
||||
else if (!proc_exists (wval->pid)) /* CGF FIXME -- test that this is one of mine */
|
||||
goto out; // invalid pid. flag no such child
|
||||
|
||||
wval->status = 0; // Don't know status yet
|
||||
@@ -480,50 +486,49 @@ proc_terminate (void)
|
||||
sync_proc_subproc->acquire(WPSP);
|
||||
(void) proc_subproc (PROC_CLEARWAIT, 1);
|
||||
|
||||
lock_pinfo_for_update (INFINITE);
|
||||
/* Clean out zombie processes from the pid list. */
|
||||
int i;
|
||||
for (i = 0; i < nzombies; i++)
|
||||
{
|
||||
pinfo *child;
|
||||
if ((child = zombies[i])->hProcess)
|
||||
if (zombies[i]->hProcess)
|
||||
{
|
||||
ForceCloseHandle1 (child->hProcess, childhProc);
|
||||
child->hProcess = NULL;
|
||||
ForceCloseHandle1 (zombies[i]->hProcess, childhProc);
|
||||
zombies[i]->hProcess = NULL;
|
||||
}
|
||||
child->process_state = PID_NOT_IN_USE;
|
||||
zombies[i]->process_state = PID_NOT_IN_USE; /* CGF FIXME - still needed? */
|
||||
zombies[i].release();
|
||||
}
|
||||
|
||||
/* Disassociate my subprocesses */
|
||||
for (i = 0; i < nchildren; i++)
|
||||
{
|
||||
pinfo *child;
|
||||
if ((child = pchildren[i])->process_state == PID_NOT_IN_USE)
|
||||
pinfo child; /* CGF FIXME */
|
||||
if (pchildren[i]->process_state == PID_NOT_IN_USE)
|
||||
continue; // Should never happen
|
||||
if (!child->hProcess)
|
||||
sip_printf ("%d(%d) hProcess cleared already?", child->pid,
|
||||
child->dwProcessId);
|
||||
if (!pchildren[i]->hProcess)
|
||||
sip_printf ("%d(%d) hProcess cleared already?", pchildren[i]->pid,
|
||||
pchildren[i]->dwProcessId);
|
||||
else
|
||||
{
|
||||
ForceCloseHandle1 (child->hProcess, childhProc);
|
||||
child->hProcess = NULL;
|
||||
if (!proc_exists (child))
|
||||
ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
|
||||
pchildren[i]->hProcess = NULL;
|
||||
if (!proc_exists (pchildren[i]))
|
||||
{
|
||||
sip_printf ("%d(%d) doesn't exist", child->pid,
|
||||
child->dwProcessId);
|
||||
child->process_state = PID_NOT_IN_USE; /* a reaped child */
|
||||
sip_printf ("%d(%d) doesn't exist", pchildren[i]->pid,
|
||||
pchildren[i]->dwProcessId);
|
||||
pchildren[i]->process_state = PID_NOT_IN_USE; /* a reaped child CGF FIXME -- still needed? */
|
||||
}
|
||||
else
|
||||
{
|
||||
sip_printf ("%d(%d) closing active child handle", child->pid,
|
||||
child->dwProcessId);
|
||||
child->ppid = 1;
|
||||
if (child->pgid == myself->pid)
|
||||
child->process_state |= PID_ORPHANED;
|
||||
sip_printf ("%d(%d) closing active child handle", pchildren[i]->pid,
|
||||
pchildren[i]->dwProcessId);
|
||||
pchildren[i]->ppid = 1;
|
||||
if (pchildren[i]->pgid == myself->pid)
|
||||
pchildren[i]->process_state |= PID_ORPHANED;
|
||||
}
|
||||
}
|
||||
pchildren[i].release ();
|
||||
}
|
||||
unlock_pinfo ();
|
||||
nchildren = nzombies = 0;
|
||||
|
||||
/* Attempt to close and release sync_proc_subproc in a
|
||||
@@ -706,7 +711,7 @@ sigproc_terminate (void)
|
||||
* completed before returning.
|
||||
*/
|
||||
int __stdcall
|
||||
sig_send (pinfo *p, int sig, DWORD ebp)
|
||||
sig_send (_pinfo *p, int sig, DWORD ebp)
|
||||
{
|
||||
int rc = 1;
|
||||
DWORD tid = GetCurrentThreadId ();
|
||||
@@ -717,7 +722,7 @@ sig_send (pinfo *p, int sig, DWORD ebp)
|
||||
sigframe thisframe;
|
||||
|
||||
if (p == myself_nowait_nonmain)
|
||||
p = (tid == mainthread.id) ? myself : myself_nowait;
|
||||
p = (tid == mainthread.id) ? (_pinfo *) myself : myself_nowait;
|
||||
if (!(its_me = (p == NULL || p == myself || p == myself_nowait)))
|
||||
wait_for_completion = FALSE;
|
||||
else
|
||||
@@ -888,7 +893,7 @@ subproc_init (void)
|
||||
by fork/spawn/exec. */
|
||||
|
||||
void __stdcall
|
||||
init_child_info (DWORD chtype, child_info *ch, int 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);
|
||||
@@ -912,7 +917,7 @@ static int __stdcall
|
||||
checkstate (waitq *w)
|
||||
{
|
||||
int i, x, potential_match = 0;
|
||||
pinfo *child;
|
||||
_pinfo *child;
|
||||
|
||||
sip_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
|
||||
|
||||
@@ -949,7 +954,7 @@ out:
|
||||
/* Get or create a process specific semaphore used in message passing.
|
||||
*/
|
||||
static HANDLE __stdcall
|
||||
getsem (pinfo *p, const char *str, int init, int max)
|
||||
getsem (_pinfo *p, const char *str, int init, int max)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
@@ -1047,6 +1052,10 @@ remove_zombie (int ci)
|
||||
{
|
||||
sip_printf ("removing %d, pid %d, nzombies %d", ci, zombies[ci]->pid,
|
||||
nzombies);
|
||||
|
||||
if (zombies[ci])
|
||||
zombies[ci].release ();
|
||||
|
||||
if (ci < --nzombies)
|
||||
zombies[ci] = zombies[nzombies];
|
||||
|
||||
@@ -1064,7 +1073,7 @@ remove_zombie (int ci)
|
||||
* 0 if child does not match parent_w->next criteria
|
||||
*/
|
||||
static int __stdcall
|
||||
stopped_or_terminated (waitq *parent_w, pinfo *child)
|
||||
stopped_or_terminated (waitq *parent_w, _pinfo *child)
|
||||
{
|
||||
int potential_match;
|
||||
waitq *w = parent_w->next;
|
||||
@@ -1096,7 +1105,7 @@ stopped_or_terminated (waitq *parent_w, pinfo *child)
|
||||
w->status = (child->stopsig << 8) | 0x7f;
|
||||
child->stopsig = 0;
|
||||
}
|
||||
else
|
||||
else /* Should only get here when child has been moved to the zombies array */
|
||||
{
|
||||
DWORD status;
|
||||
if (!GetExitCodeProcess (child->hProcess, &status))
|
||||
|
Reference in New Issue
Block a user