OSDN Git Service

* pinfo.cc (winpids:add): New method.
authorcgf <cgf>
Sun, 5 Nov 2000 06:42:23 +0000 (06:42 +0000)
committercgf <cgf>
Sun, 5 Nov 2000 06:42:23 +0000 (06:42 +0000)
(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.

winsup/cygwin/ChangeLog
winsup/cygwin/external.cc
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h
winsup/cygwin/signal.cc

index f841d45..58236d4 100644 (file)
@@ -1,3 +1,17 @@
+Sun Nov  5 01:34:51 2000  Christopher Faylor <cgf@cygnus.com>
+
+       * 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 <cgf@cygnus.com>
 
        * exceptions.cc (handle_sigsuspend): Record frame here for signalling.
index 0623911..0199aed 100644 (file)
@@ -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);
index 5b825e1..c2932fc 100644 (file)
@@ -282,7 +282,6 @@ cygwin_winpid_to_pid (int winpid)
 
 #include <tlhelp32.h>
 
-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);
+    }
 }
index 0620047..b078c9b 100644 (file)
@@ -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
index bfac33c..242b2fb 100644 (file)
@@ -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;