summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/pinfo.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2012-09-17 20:07:49 +0000
committerChristopher Faylor <me@cgf.cx>2012-09-17 20:07:49 +0000
commitee705c1dcbf4576fc15ac5ed46426c859f08e686 (patch)
treee1518936b58d065b529db42adb642b0cdd740f53 /winsup/cygwin/pinfo.cc
parenta271d2e310db161cce61e6a780ec467bf4d1d744 (diff)
downloadcygnal-ee705c1dcbf4576fc15ac5ed46426c859f08e686.tar.gz
cygnal-ee705c1dcbf4576fc15ac5ed46426c859f08e686.tar.bz2
cygnal-ee705c1dcbf4576fc15ac5ed46426c859f08e686.zip
* pinfo.cc (pinfo::init): Detect potential race where short block has been
retrieved but PID_EXECED flag is not set.
Diffstat (limited to 'winsup/cygwin/pinfo.cc')
-rw-r--r--winsup/cygwin/pinfo.cc9
1 files changed, 9 insertions, 0 deletions
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index e8d156e04..de3620fdb 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -299,6 +299,15 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0)
bool created = shloc != SH_JUSTOPEN;
+ /* Detect situation where a transitional memory block is being retrieved.
+ If the block has been allocated with PINFO_REDIR_SIZE but not yet
+ updated with a PID_EXECED state then we'll retry. */
+ MEMORY_BASIC_INFORMATION mbi;
+ if (!created && procinfo->exists ()
+ && VirtualQuery (procinfo, &mbi, sizeof (mbi))
+ && mbi.RegionSize < sizeof (_pinfo))
+ goto loop;
+
if (!created && createit && (procinfo->process_state & PID_REAPED))
{
memset (procinfo, 0, sizeof (*procinfo));