diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index f841d4504..58236d49f 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +Sun Nov 5 01:34:51 2000 Christopher Faylor + + * pinfo.cc (winpids:add): New method. + (winpids::enumNT): New method renamed from EnumProcessesNT. + Use add method to add elements to the lists. + (winpids::enum9x): New method renamed from EnumProcesses9x. + Use add method to add elements to the lists. + (winpids::enum_init): Accept 'winpid' parameter to control whether + to add all windows pids to the list. + (winpids::release): New method. + * pinfo.h (winpids): Reflect above changes. + * signal.cc (kill_pgrp): Ditto. + * external.cc (fillout_pinfo): Ditto. + Sat Nov 4 22:07:03 2000 Christopher Faylor * exceptions.cc (handle_sigsuspend): Record frame here for signalling. diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index 0623911d5..0199aedd3 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -32,23 +32,22 @@ fillout_pinfo (pid_t pid, int winpid) static winpids pids (0); if (!pids.npids || !nextpid) - pids.init (); + pids.init (winpid); static unsigned int i = 0; if (!pid) i = 0; memset (&ep, 0, sizeof ep); - for (; i < pids.npids;) + while (i < pids.npids) { - DWORD thispid = pids[i++]; - if (!thispid) - continue; - pinfo p (thispid, PID_NOREDIR); + DWORD thispid = pids.winpid (i); + _pinfo *p = pids[i]; + i++; if (!p) { - if (!winpid || (!nextpid && thispid != (DWORD) pid)) + if (!nextpid && thispid != (DWORD) pid) continue; ep.pid = thispid; ep.dwProcessId = cygwin_pid (thispid); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 5b825e1a5..c2932fc98 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -282,7 +282,6 @@ cygwin_winpid_to_pid (int winpid) #include -typedef DWORD (WINAPI * ENUMPROCESSES) (DWORD* &, DWORD &); typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD, DWORD); typedef BOOL (WINAPI * PROCESSWALK) (HANDLE, LPPROCESSENTRY32); typedef BOOL (WINAPI * CLOSESNAPSHOT) (HANDLE); @@ -290,15 +289,43 @@ typedef BOOL (WINAPI * CLOSESNAPSHOT) (HANDLE); static NO_COPY CREATESNAPSHOT myCreateToolhelp32Snapshot = NULL; static NO_COPY PROCESSWALK myProcess32First = NULL; static NO_COPY PROCESSWALK myProcess32Next = NULL; -static DWORD WINAPI enum_init (DWORD* &, DWORD&); - -static NO_COPY ENUMPROCESSES myEnumProcesses = enum_init; #define slop_pidlist 200 #define size_pidlist(i) (sizeof (pidlist[0]) * ((i) + 1)) +#define size_pinfolist(i) (sizeof (pinfolist[0]) * ((i) + 1)) -static DWORD WINAPI -EnumProcessesNT (DWORD* &pidlist, DWORD &npidlist) +inline void +winpids::add (DWORD& nelem, bool winpid, DWORD pid) +{ + pid_t cygpid = cygwin_pid (pid); + if (nelem >= npidlist) + { + npidlist += slop_pidlist; + pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist)); + pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (npidlist)); + } + + pinfolist[nelem].init (cygpid, PID_NOREDIR); + if (winpid) + /* nothing to do */; + else if (!pinfolist[nelem]) + return; + else + /* Scan list of previously recorded pids to make sure that this pid hasn't + shown up before. This can happen when a process execs. */ + for (unsigned i = 0; i < nelem; i++) + if (pinfolist[i]->pid == pinfolist[nelem]->pid ) + { + if ((_pinfo *) pinfolist[nelem] != (_pinfo *) myself) + pinfolist[nelem].release (); + return; + } + + pidlist[nelem++] = pid; +} + +DWORD +winpids::enumNT (bool winpid) { static DWORD szprocs = 0; static SYSTEM_PROCESSES *procs; @@ -328,24 +355,17 @@ EnumProcessesNT (DWORD* &pidlist, DWORD &npidlist) for (;;) { if (px->ProcessId) - { - if (nelem >= npidlist) - { - npidlist += slop_pidlist; - pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist)); - } - pidlist[nelem++] = cygwin_pid (px->ProcessId); - if (!px->NextEntryDelta) - break; - } + add (nelem, winpid, px->ProcessId); + if (!px->NextEntryDelta) + break; px = (SYSTEM_PROCESSES *) ((char *) px + px->NextEntryDelta); } return nelem; } -static DWORD WINAPI -EnumProcesses9x (DWORD* &pidlist, DWORD &npidlist) +DWORD +winpids::enum9x (bool winpid) { DWORD nelem = 0; @@ -362,14 +382,8 @@ EnumProcesses9x (DWORD* &pidlist, DWORD &npidlist) if (myProcess32First(h, &proc)) do { - if (!proc.th32ProcessID) - continue; - if (nelem >= npidlist) - { - npidlist += slop_pidlist; - pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist)); - } - pidlist[nelem++] = cygwin_pid (proc.th32ProcessID); + if (proc.th32ProcessID) + add (nelem, winpid, proc.th32ProcessID); } while (myProcess32Next (h, &proc)); @@ -378,18 +392,18 @@ EnumProcesses9x (DWORD* &pidlist, DWORD &npidlist) } void -winpids::init () +winpids::init (bool winpid) { - npids = myEnumProcesses (pidlist, npidlist); + npids = (this->*enum_processes) (winpid); pidlist[npids] = 0; } -static DWORD WINAPI -enum_init (DWORD* &pidlist, DWORD& npidlist) +DWORD +winpids::enum_init (bool winpid) { HINSTANCE h; if (os_being_run == winNT) - myEnumProcesses = EnumProcessesNT; + enum_processes = &winpids::enumNT; else { h = GetModuleHandle("kernel32.dll"); @@ -405,8 +419,26 @@ enum_init (DWORD* &pidlist, DWORD& npidlist) return 0; } - myEnumProcesses = EnumProcesses9x; + enum_processes = &winpids::enum9x; } - return myEnumProcesses (pidlist, npidlist); + return (this->*enum_processes) (winpid); +} + +void +winpids::release () +{ + for (unsigned i = 0; i < npids; i++) + if (pinfolist[i] && (_pinfo *) pinfolist[i] != (_pinfo *) myself) + pinfolist[i].release (); +} + +winpids::~winpids () +{ + if (npidlist) + { + release (); + free (pidlist); + free (pinfolist); + } } diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 0620047ab..b078c9bb1 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -188,13 +188,23 @@ class winpids { DWORD *pidlist; DWORD npidlist; + pinfo *pinfolist; + DWORD (winpids::* enum_processes) (bool winpid); + DWORD enum_init (bool winpid); + DWORD enumNT (bool winpid); + DWORD enum9x (bool winpid); + void add (DWORD& nelem, bool, DWORD pid); public: DWORD npids; - void reset () { npids = 0; } - winpids (int) { reset (); } - winpids (): pidlist (NULL), npidlist (0) { init (); }; - void init (); - int operator [] (int i) const {return pidlist[i];} + inline void reset () { npids = 0; release (); } + void init (bool winpid); + winpids (int): enum_processes (&winpids::enum_init) { reset (); } + winpids (): pidlist (NULL), npidlist (0), pinfolist (NULL), + enum_processes (&winpids::enum_init), npids (0) { init (0); } + inline DWORD& winpid (int i) const {return pidlist[i];} + inline _pinfo *operator [] (int i) const {return (_pinfo *) pinfolist[i];} + ~winpids (); + void release (); }; extern __inline pid_t diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index bfac33c9f..242b2fb5d 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -207,7 +207,7 @@ kill_pgrp (pid_t pid, int sig) winpids pids; for (unsigned i = 0; i < pids.npids; i++) { - pinfo p (pids[i], PID_NOREDIR); + _pinfo *p = pids[i]; if (!proc_exists (p)) continue;