4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-01 03:50:28 +08:00

* external.cc (fillout_pinfo): Remove nonsensical loop.

* fork.cc (frok::parent): When initializing pinfo for child new PID_NEW flag +
actual defined constant rather than raw number.  Don't set start_time here.
* pinfo.cc (pinfo::thisproc): Use PID_NEW when initializing pinfo.  Avoid
checking h for NULL multiple times.  Don't set start_time here.
(pinfo_init): Aways set ppid last.  Tweak strace output.
(pinfo::init): Handle new PID_NEW flag.  Wait for shared memory to contain
useful information.  Set start_time if PID_NEW.
(_onreturn:h): Define as HANDLE rather than HANDLE *.
(_onreturn::~onreturn): Accommodate h definition change.
(_onreturn::no_close_handle): Rename from no_close_p_handle.  Take a pinfo arg
and set hProcess to h before zeroing.
(winpids::add): Don't open a handle to our own process.  Change logic
associated with when a handle gets closed.  Accommodate no_close_handle
changes.
(winpids::enum_processes): Simplify process enumeration loop.
(winpids::set): Eliminate ill-considered malloc locking.
* sigproc.cc (proc_subproc): Always set ppid last.
This commit is contained in:
Christopher Faylor 2013-12-18 03:58:11 +00:00
parent 1147c2111d
commit 13621d2ef8
6 changed files with 83 additions and 62 deletions

View File

@ -1,3 +1,25 @@
2013-12-17 Christopher Faylor <me.cygwin2013@cgf.cx>
* external.cc (fillout_pinfo): Remove nonsensical loop.
* fork.cc (frok::parent): When initializing pinfo for child new PID_NEW
flag + actual defined constant rather than raw number. Don't set
start_time here.
* pinfo.cc (pinfo::thisproc): Use PID_NEW when initializing pinfo.
Avoid checking h for NULL multiple times. Don't set start_time here.
(pinfo_init): Aways set ppid last. Tweak strace output.
(pinfo::init): Handle new PID_NEW flag. Wait for shared memory to
contain useful information. Set start_time if PID_NEW.
(_onreturn:h): Define as HANDLE rather than HANDLE *.
(_onreturn::~onreturn): Accommodate h definition change.
(_onreturn::no_close_handle): Rename from no_close_p_handle. Take a
pinfo arg and set hProcess to h before zeroing.
(winpids::add): Don't open a handle to our own process. Change logic
associated with when a handle gets closed. Accommodate no_close_handle
changes.
(winpids::enum_processes): Simplify process enumeration loop.
(winpids::set): Eliminate ill-considered malloc locking.
* sigproc.cc (proc_subproc): Always set ppid last.
2013-12-17 Christopher Faylor <me.cygwin2013@cgf.cx> 2013-12-17 Christopher Faylor <me.cygwin2013@cgf.cx>
* sigproc.cc (sig_send): Set PIPE_NOWAIT for pipes which are not us. * sigproc.cc (sig_send): Set PIPE_NOWAIT for pipes which are not us.

View File

@ -76,13 +76,6 @@ fillout_pinfo (pid_t pid, int winpid)
} }
else if (nextpid || p->pid == pid || (winpid && thispid == (DWORD) pid)) else if (nextpid || p->pid == pid || (winpid && thispid == (DWORD) pid))
{ {
/* It is possible that this pinfo is not completely set up yet. Wait
a while if so. */
for (int i = 0; i < 2000; i++)
if (p->start_time)
break;
else
Sleep (1);
ep.ctty = (p->ctty < 0 || iscons_dev (p->ctty)) ? p->ctty : device::minor (p->ctty); ep.ctty = (p->ctty < 0 || iscons_dev (p->ctty)) ? p->ctty : device::minor (p->ctty);
ep.pid = p->pid; ep.pid = p->pid;
ep.ppid = p->ppid; ep.ppid = p->ppid;

View File

@ -344,7 +344,6 @@ frok::parent (volatile char * volatile stack_here)
syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)", syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)",
myself->progname, myself->progname, c_flags, &si, &pi); myself->progname, myself->progname, c_flags, &si, &pi);
bool locked = __malloc_lock (); bool locked = __malloc_lock ();
time_t start_time = time (NULL);
/* Remove impersonation */ /* Remove impersonation */
cygheap->user.deimpersonate (); cygheap->user.deimpersonate ();
@ -412,7 +411,7 @@ frok::parent (volatile char * volatile stack_here)
fix_impersonation = false; fix_impersonation = false;
child_pid = cygwin_pid (pi.dwProcessId); child_pid = cygwin_pid (pi.dwProcessId);
child.init (child_pid, 1, NULL); child.init (child_pid, PID_IN_USE | PID_NEW, NULL);
if (!child) if (!child)
{ {
@ -421,7 +420,6 @@ frok::parent (volatile char * volatile stack_here)
goto cleanup; goto cleanup;
} }
child->start_time = start_time; /* Register child's starting time. */
child->nice = myself->nice; child->nice = myself->nice;
/* Initialize things that are done later in dll_crt0_1 that aren't done /* Initialize things that are done later in dll_crt0_1 that aren't done

View File

@ -220,7 +220,7 @@ enum
PID_MYSELF = 0x00200, /* Flag that pid is me. */ PID_MYSELF = 0x00200, /* Flag that pid is me. */
PID_NOCLDSTOP = 0x00400, /* Set if no SIGCHLD signal on stop. */ PID_NOCLDSTOP = 0x00400, /* Set if no SIGCHLD signal on stop. */
PID_INITIALIZING = 0x00800, /* Set until ready to receive signals. */ PID_INITIALIZING = 0x00800, /* Set until ready to receive signals. */
PID_UNUSED1 = 0x01000, /* Available. */ PID_NEW = 0x01000, /* Available. */
PID_ALLPIDS = 0x02000, /* used by pinfo scanner */ PID_ALLPIDS = 0x02000, /* used by pinfo scanner */
PID_EXECED = 0x04000, /* redirect to original pid info block */ PID_EXECED = 0x04000, /* redirect to original pid info block */
PID_NOREDIR = 0x08000, /* don't redirect if execed */ PID_NOREDIR = 0x08000, /* don't redirect if execed */

View File

@ -56,16 +56,21 @@ pinfo::thisproc (HANDLE h)
{ {
procinfo = NULL; procinfo = NULL;
DWORD flags = PID_IN_USE | PID_ACTIVE;
if (!h) if (!h)
cygheap->pid = cygwin_pid (myself_initial.pid); {
h = INVALID_HANDLE_VALUE;
cygheap->pid = cygwin_pid (myself_initial.pid);
flags |= PID_NEW;
}
init (cygheap->pid, PID_IN_USE, h ?: INVALID_HANDLE_VALUE); init (cygheap->pid, flags, h);
procinfo->process_state |= PID_IN_USE; procinfo->process_state |= PID_IN_USE;
procinfo->dwProcessId = myself_initial.pid; procinfo->dwProcessId = myself_initial.pid;
procinfo->sendsig = myself_initial.sendsig; procinfo->sendsig = myself_initial.sendsig;
wcscpy (procinfo->progname, myself_initial.progname); wcscpy (procinfo->progname, myself_initial.progname);
debug_printf ("myself dwProcessId %u", procinfo->dwProcessId); debug_printf ("myself dwProcessId %u", procinfo->dwProcessId);
if (h) if (h != INVALID_HANDLE_VALUE)
{ {
/* here if execed */ /* here if execed */
static pinfo NO_COPY myself_identity; static pinfo NO_COPY myself_identity;
@ -73,9 +78,6 @@ pinfo::thisproc (HANDLE h)
procinfo->exec_sendsig = NULL; procinfo->exec_sendsig = NULL;
procinfo->exec_dwProcessId = 0; procinfo->exec_dwProcessId = 0;
} }
else if (!child_proc_info) /* child_proc_info is only set when this process
was started by another cygwin process */
procinfo->start_time = time (NULL); /* Register our starting time. */
} }
/* Initialize the process table entry for the current task. /* Initialize the process table entry for the current task.
@ -94,20 +96,20 @@ pinfo_init (char **envp, int envc)
/* Invent our own pid. */ /* Invent our own pid. */
myself.thisproc (NULL); myself.thisproc (NULL);
myself->ppid = 1;
myself->pgid = myself->sid = myself->pid; myself->pgid = myself->sid = myself->pid;
myself->ctty = -1; myself->ctty = -1;
myself->uid = ILLEGAL_UID; myself->uid = ILLEGAL_UID;
myself->gid = UNKNOWN_GID; myself->gid = UNKNOWN_GID;
environ_init (NULL, 0); /* call after myself has been set up */ environ_init (NULL, 0); /* call after myself has been set up */
myself->nice = winprio_to_nice (GetPriorityClass (GetCurrentProcess ())); myself->nice = winprio_to_nice (GetPriorityClass (GetCurrentProcess ()));
myself->ppid = 1; /* always set last */
debug_printf ("Set nice to %d", myself->nice); debug_printf ("Set nice to %d", myself->nice);
} }
myself->process_state |= PID_ACTIVE; myself->process_state |= PID_ACTIVE;
myself->process_state &= ~(PID_INITIALIZING | PID_EXITED | PID_REAPED); myself->process_state &= ~(PID_INITIALIZING | PID_EXITED | PID_REAPED);
myself.preserve (); myself.preserve ();
debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid); debug_printf ("pid %d, pgid %d, process_state %y", myself->pid, myself->pgid, myself->process_state);
} }
DWORD DWORD
@ -314,11 +316,15 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0)
/* Detect situation where a transitional memory block is being retrieved. /* Detect situation where a transitional memory block is being retrieved.
If the block has been allocated with PINFO_REDIR_SIZE but not yet If the block has been allocated with PINFO_REDIR_SIZE but not yet
updated with a PID_EXECED state then we'll retry. */ updated with a PID_EXECED state then we'll retry. */
MEMORY_BASIC_INFORMATION mbi; if (!created && !(flag & PID_NEW))
if (!created && procinfo->exists () {
&& VirtualQuery (procinfo, &mbi, sizeof (mbi)) MEMORY_BASIC_INFORMATION mbi;
&& mbi.RegionSize < sizeof (_pinfo)) for (int i = 0; i < 1000 && !procinfo->ppid; i++)
goto loop; Sleep (0);
if (procinfo->exists () && VirtualQuery (procinfo, &mbi, sizeof (mbi))
&& mbi.RegionSize < sizeof (_pinfo))
goto loop;
}
if (!created && createit && (procinfo->process_state & PID_REAPED)) if (!created && createit && (procinfo->process_state & PID_REAPED))
{ {
@ -360,6 +366,8 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0)
goto loop; goto loop;
} }
if (flag & PID_NEW)
procinfo->start_time = time (NULL);
if (!created) if (!created)
/* nothing */; /* nothing */;
else if (!(flag & PID_EXECED)) else if (!(flag & PID_EXECED))
@ -1112,19 +1120,23 @@ cygwin_winpid_to_pid (int winpid)
#define size_pinfolist(i) (sizeof (pinfolist[0]) * ((i) + 1)) #define size_pinfolist(i) (sizeof (pinfolist[0]) * ((i) + 1))
class _onreturn class _onreturn
{ {
HANDLE *h; HANDLE h;
public: public:
~_onreturn () ~_onreturn ()
{ {
if (h && *h) if (h)
{ {
CloseHandle (*h); CloseHandle (h);
*h = NULL;
h = NULL;
} }
} }
void no_close_p_handle () {h = NULL;} void no_close_handle (pinfo& p)
_onreturn (HANDLE& _h): h (&_h) {} {
p.hProcess = h;
h = NULL;
}
_onreturn (): h (NULL) {}
void operator = (HANDLE h0) {h = h0;}
operator HANDLE () const {return h;}
}; };
inline void inline void
@ -1139,23 +1151,28 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid)
pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (npidlist + 1)); pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (npidlist + 1));
} }
_onreturn onreturn;
pinfo& p = pinfolist[nelem]; pinfo& p = pinfolist[nelem];
memset (&p, 0, sizeof (p)); memset (&p, 0, sizeof (p));
/* Open a process to prevent a subsequent exit from invalidating the
shared memory region. */
p.hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, false, pid);
_onreturn onreturn (p.hProcess);
/* If we couldn't open the process then we don't have rights to it and should
make a copy of the shared memory area if it exists (it may not). */
bool perform_copy; bool perform_copy;
if (!p.hProcess) if (cygpid == myself->pid)
perform_copy = true; {
p = myself;
perform_copy = false;
}
else else
perform_copy = make_copy; {
/* Open a process to prevent a subsequent exit from invalidating the
shared memory region. */
onreturn = OpenProcess (PROCESS_QUERY_INFORMATION, false, pid);
p.init (cygpid, PID_NOREDIR | pinfo_access, NULL); /* If we couldn't open the process then we don't have rights to it and should
make a copy of the shared memory area when it exists (it may not). */
perform_copy = onreturn ? make_copy : true;
p.init (cygpid, PID_NOREDIR | pinfo_access, NULL);
}
/* If we're just looking for winpids then don't do any special cygwin "stuff* */ /* If we're just looking for winpids then don't do any special cygwin "stuff* */
if (winpid) if (winpid)
@ -1170,7 +1187,7 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid)
p.init (cygpid, PID_NOREDIR, NULL); p.init (cygpid, PID_NOREDIR, NULL);
if (!p) if (!p)
return; return;
} }
/* Scan list of previously recorded pids to make sure that this pid hasn't /* Scan list of previously recorded pids to make sure that this pid hasn't
shown up before. This can happen when a process execs. */ shown up before. This can happen when a process execs. */
@ -1212,12 +1229,12 @@ out:
/* handle specially. Close the handle but (eventually) don't /* handle specially. Close the handle but (eventually) don't
deallocate procinfo in release call */; deallocate procinfo in release call */;
else if (!perform_copy) else if (!perform_copy)
onreturn.no_close_p_handle (); /* Don't close the handle until release */ onreturn.no_close_handle (p); /* Don't close the handle until release */
else else
{ {
_pinfo *pnew = (_pinfo *) malloc (sizeof (*p.procinfo)); _pinfo *pnew = (_pinfo *) malloc (sizeof (*p.procinfo));
if (!pnew) if (!pnew)
onreturn.no_close_p_handle (); onreturn.no_close_handle (p);
else else
{ {
*pnew = *p.procinfo; *pnew = *p.procinfo;
@ -1246,23 +1263,17 @@ winpids::enum_processes (bool winpid)
HANDLE dir = get_shared_parent_dir (); HANDLE dir = get_shared_parent_dir ();
BOOLEAN restart = TRUE; BOOLEAN restart = TRUE;
do while (NT_SUCCESS (NtQueryDirectoryObject (dir, &f, sizeof f, TRUE, restart,
&context, NULL)))
{ {
status = NtQueryDirectoryObject (dir, &f, sizeof f, TRUE, restart, restart = FALSE;
&context, NULL); f.dbi.ObjectName.Buffer[f.dbi.ObjectName.Length / sizeof (WCHAR)] = L'\0';
if (NT_SUCCESS (status)) if (wcsncmp (f.dbi.ObjectName.Buffer, L"cygpid.", 7) == 0)
{ {
restart = FALSE; DWORD pid = wcstoul (f.dbi.ObjectName.Buffer + 7, NULL, 10);
f.dbi.ObjectName.Buffer[f.dbi.ObjectName.Length / sizeof (WCHAR)] add (nelem, false, pid);
= L'\0';
if (wcsncmp (f.dbi.ObjectName.Buffer, L"cygpid.", 7) == 0)
{
DWORD pid = wcstoul (f.dbi.ObjectName.Buffer + 7, NULL, 10);
add (nelem, false, pid);
}
} }
} }
while (NT_SUCCESS (status));
cygwin_pid_nelem = nelem; cygwin_pid_nelem = nelem;
if (winpid) if (winpid)
@ -1332,18 +1343,15 @@ winpids::enum_processes (bool winpid)
px = (PSYSTEM_PROCESS_INFORMATION) ((char *) px + px->NextEntryOffset); px = (PSYSTEM_PROCESS_INFORMATION) ((char *) px + px->NextEntryOffset);
} }
} }
return nelem; return nelem;
} }
void void
winpids::set (bool winpid) winpids::set (bool winpid)
{ {
__malloc_lock ();
npids = enum_processes (winpid); npids = enum_processes (winpid);
if (pidlist) if (pidlist)
pidlist[npids] = 0; pidlist[npids] = 0;
__malloc_unlock ();
} }
DWORD DWORD

View File

@ -207,7 +207,6 @@ proc_subproc (DWORD what, uintptr_t val)
case PROC_DETACHED_CHILD: case PROC_DETACHED_CHILD:
if (vchild != myself) if (vchild != myself)
{ {
vchild->ppid = what == PROC_DETACHED_CHILD ? 1 : myself->pid;
vchild->uid = myself->uid; vchild->uid = myself->uid;
vchild->gid = myself->gid; vchild->gid = myself->gid;
vchild->pgid = myself->pgid; vchild->pgid = myself->pgid;
@ -215,6 +214,7 @@ proc_subproc (DWORD what, uintptr_t val)
vchild->ctty = myself->ctty; vchild->ctty = myself->ctty;
vchild->cygstarted = true; vchild->cygstarted = true;
vchild->process_state |= PID_INITIALIZING; vchild->process_state |= PID_INITIALIZING;
vchild->ppid = what == PROC_DETACHED_CHILD ? 1 : myself->pid; /* always set last */
} }
if (what == PROC_DETACHED_CHILD) if (what == PROC_DETACHED_CHILD)
break; break;