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>2005-12-12 21:43:31 +0300
committerChristopher Faylor <me@cgf.cx>2005-12-12 21:43:31 +0300
commit363934dc9b9327460fefc113a3797e7e51ea2c18 (patch)
tree240bbce2428abbce4c633f33a879b4a5baba1994 /winsup/cygwin/pinfo.cc
parent9941f8525d6a586843662352f28409efa18942c8 (diff)
* pinfo.cc (size_copied): New convenience macro.
(winpids::add): Alias the element that we are working on for slightly better clarity. Honor the "make_copy" flag. (winpids::release): Free and zero procinfo field if it was allocated via malloc. (winpids::~winpids): Free copied array. * pinfo.h (class pinfo): Make winpids class a friend. (winpids::make_copy): New field. (winpids::copied): New array. (winpids::reset): Reset npids after releasing pinfos or suffer a memory leak. (winpids::winpids): Try harder to allocate all fields in the class.
Diffstat (limited to 'winsup/cygwin/pinfo.cc')
-rw-r--r--winsup/cygwin/pinfo.cc42
1 files changed, 34 insertions, 8 deletions
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index fb3c9da14..4e8f1a899 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -1089,6 +1089,7 @@ cygwin_winpid_to_pid (int winpid)
#define slop_pidlist 200
#define size_pidlist(i) (sizeof (pidlist[0]) * ((i) + 1))
#define size_pinfolist(i) (sizeof (pinfolist[0]) * ((i) + 1))
+#define size_copied(i) (sizeof (copied[0]) * ((i) + 1))
inline void
winpids::add (DWORD& nelem, bool winpid, DWORD pid)
@@ -1097,34 +1098,51 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid)
if (nelem >= npidlist)
{
npidlist += slop_pidlist;
+ copied = (bool *) realloc (copied, size_copied (npidlist + 1));
pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist + 1));
pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (npidlist + 1));
}
- pinfolist[nelem].init (cygpid, PID_NOREDIR | pinfo_access, NULL);
+ pinfo& p = pinfolist[nelem];
+
+ p.init (cygpid, PID_NOREDIR | pinfo_access, NULL);
if (winpid)
goto out;
- if (!pinfolist[nelem])
+ if (!p)
{
if (!pinfo_access)
return;
- pinfolist[nelem].init (cygpid, PID_NOREDIR, NULL);
- if (!pinfolist[nelem])
+ p.init (cygpid, PID_NOREDIR, NULL);
+ if (!p)
return;
}
/* 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 (pinfolist[i]->pid == p->pid)
{
- if ((_pinfo *) pinfolist[nelem] != (_pinfo *) myself)
- pinfolist[nelem].release ();
+ if ((_pinfo *) p != (_pinfo *) myself)
+ p.release ();
return;
}
out:
+ copied[nelem] = false;
+ if (make_copy)
+ {
+ _pinfo *pnew = (_pinfo *) malloc (sizeof (*p.procinfo));
+ if (pnew)
+ {
+ copied[nelem] = true;
+ *pnew = *p.procinfo;
+ if ((_pinfo *) p != (_pinfo *) myself)
+ p.release ();
+ p.procinfo = pnew;
+ p.destroy = false;
+ }
+ }
pidlist[nelem++] = pid;
}
@@ -1219,9 +1237,16 @@ winpids::enum_init (bool winpid)
void
winpids::release ()
{
+ _pinfo *p;
for (unsigned i = 0; i < npids; i++)
if (pinfolist[i] && (_pinfo *) pinfolist[i] != (_pinfo *) myself)
- pinfolist[i].release ();
+ if (!copied[i])
+ pinfolist[i].release ();
+ else if ((p = pinfolist[i].procinfo))
+ {
+ pinfolist[i].procinfo = NULL;
+ free (p);
+ }
}
winpids::~winpids ()
@@ -1229,6 +1254,7 @@ winpids::~winpids ()
if (npidlist)
{
release ();
+ free (copied);
free (pidlist);
free (pinfolist);
}