diff options
Diffstat (limited to 'winsup/cygwin/pinfo.cc')
-rw-r--r-- | winsup/cygwin/pinfo.cc | 413 |
1 files changed, 0 insertions, 413 deletions
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc deleted file mode 100644 index 789a47920..000000000 --- a/winsup/cygwin/pinfo.cc +++ /dev/null @@ -1,413 +0,0 @@ -/* pinfo.cc: process table support - - Copyright 1996, 1997, 1998, 2000 Cygnus Solutions. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include <stdlib.h> -#include <time.h> -#include <errno.h> -#include <limits.h> -#include "winsup.h" - -/* The first pid used; also the lowest value allowed. */ -#define PBASE 1000 - -static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0}; - -pinfo NO_COPY *myself = (pinfo *)&pinfo_dummy; // Avoid myself != NULL checks - -/* Initialize the process table. - This is done once when the dll is first loaded. */ - -void -pinfo_list::init (void) -{ - next_pid = PBASE; /* Next pid to try to allocate. */ - - /* We assume the shared data area is already initialized to zeros. - Note that SIG_DFL is zero. */ -} - -pinfo * __stdcall -set_myself (pinfo *p) -{ - myself = p; - if (!p) - return NULL; - - myself->start_time = time (NULL); /* Register our starting time. */ - - char buf[30]; - __small_sprintf (buf, "cYg%8x %x %x", _STRACE_INTERFACE_ACTIVATE_ADDR, - &strace_active); - OutputDebugString (buf); - return myself; -} - -/* Initialize the process table entry for the current task. - This is not called for fork'd tasks, only exec'd ones. */ -void __stdcall -pinfo_init (LPBYTE info) -{ - if (info != NULL) - { - /* The process was execed. Reuse entry from the original - owner of this pid. */ - environ_init (); /* Needs myself but affects calls below */ - - /* spawn has already set up a pid structure for us so we'll use that */ - - myself->process_state |= PID_CYGPARENT; - - /* Inherit file descriptor information from parent in info. - */ - LPBYTE b = dtable.de_linearize_fd_array (info); - extern char title_buf[]; - if (b && *b) - old_title = strcpy (title_buf, (char *)b); - } - else - { - /* Invent our own pid. */ - - if (!set_myself (cygwin_shared->p.allocate_pid ())) - api_fatal ("No more processes"); - - (void) GetModuleFileName (NULL, myself->progname, - sizeof(myself->progname)); - myself->ppid = myself->pgid = myself->sid = myself->pid; - myself->ctty = -1; - myself->uid = USHRT_MAX; - - environ_init (); /* call after myself has been set up */ - } - - debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid); -} - -/* [] operator. This is the mechanism for table lookups. */ -/* Returns the index into the pinfo_list table for pid arg */ - -pinfo * -pinfo_list::operator[] (pid_t pid) -{ - if (pid <= 0) - return NULL; - - pinfo *p = vec + (pid % size ()); - - if (p->pid != pid || p->process_state == PID_NOT_IN_USE) - return NULL; - else - return p; -} - -struct sigaction& -pinfo::getsig(int sig) -{ -#ifdef _MT_SAFE - if ( thread2signal ) - return thread2signal->sigs[sig]; - return sigs[sig]; -#else - return sigs[sig]; -#endif -}; - -sigset_t& -pinfo::getsigmask () -{ -#ifdef _MT_SAFE - if ( thread2signal ) - return *thread2signal->sigmask; - return sig_mask; -#else - return sig_mask; -#endif -}; - -void -pinfo::setsigmask (sigset_t _mask) -{ -#ifdef _MT_SAFE - if ( thread2signal ) - *(thread2signal->sigmask) = _mask; - sig_mask=_mask; -#else - sig_mask=_mask; -#endif -} - -LONG * -pinfo::getsigtodo(int sig) -{ -#ifdef _MT_SAFE - if ( thread2signal ) - return thread2signal->sigtodo + __SIGOFFSET + sig; - return _sigtodo + __SIGOFFSET + sig; -#else - return _sigtodo + __SIGOFFSET + sig; -#endif -} - -extern HANDLE hMainThread; - -HANDLE -pinfo::getthread2signal() -{ -#ifdef _MT_SAFE - if ( thread2signal ) - return thread2signal->win32_obj_id; - return hMainThread; -#else - return hMainThread; -#endif -} - -void -pinfo::setthread2signal(void *_thr) -{ -#ifdef _MT_SAFE - // assert has myself lock - thread2signal=(ThreadItem*)_thr; -#else -#endif -} - -void -pinfo::copysigs(pinfo *_other) -{ - sigs = _other->sigs; -} - -pinfo * __stdcall -procinfo (int pid) -{ - return cygwin_shared->p[pid]; -} - -#ifdef DEBUGGING -/* - * Code to lock/unlock the process table. - */ - -int __stdcall -lpfu (const char *func, int ln, DWORD timeout) -{ - int rc; - DWORD t; - - debug_printf ("timeout %d, pinfo_mutex %p", timeout, pinfo_mutex); - t = (timeout == INFINITE) ? 10000 : timeout; - SetLastError(0); - while ((rc = WaitForSingleObject (pinfo_mutex, t)) != WAIT_OBJECT_0) - { - if (rc == WAIT_ABANDONED_0) - break; - system_printf ("%s:%d having problems getting lock", func, ln); - system_printf ("*** %s, rc %d, %E", cygwin_shared->p.lock_info, rc); - if (t == timeout) - break; - } - - __small_sprintf (cygwin_shared->p.lock_info, "%s(%d), pid %d ", func, ln, - (user_data && myself) ? (int)myself->dwProcessId : -1); - return rc; -} - -void -unlock_pinfo (void) -{ - - debug_printf ("handle %d", pinfo_mutex); - - if (!cygwin_shared->p.lock_info[0]) - system_printf ("lock_info not set?"); - else - strcat (cygwin_shared->p.lock_info, " unlocked"); - if (!ReleaseMutex (pinfo_mutex)) - system_printf ("ReleaseMutext (pinfo_mutex<%p>) failed, %E", pinfo_mutex); -} -#else -/* - * Code to lock/unlock the process table. - */ - -int __stdcall -lock_pinfo_for_update (DWORD timeout) -{ - DWORD rc; - DWORD t; - - debug_printf ("timeout %d, pinfo_mutex %p", timeout, pinfo_mutex); - t = (timeout == INFINITE) ? 10000 : timeout; - SetLastError(0); - while ((rc = WaitForSingleObject (pinfo_mutex, t)) != WAIT_OBJECT_0) - { - if (rc == WAIT_ABANDONED_0) - break; - system_printf ("rc %d, pinfo_mutex %p, %E", pinfo_mutex, rc); - if (t == timeout) - break; - if (rc == WAIT_FAILED) - /* sigh, must be properly fixed up later. */ - return rc; - Sleep(10); /* to prevent 100% CPU in those rare cases */ - } - - return (int)rc; -} - -void -unlock_pinfo (void) -{ - - debug_printf ("handle %d", pinfo_mutex); - - ReleaseMutex (pinfo_mutex); -} -#endif - - -/* Allocate a process table entry by finding an empty slot in the - fixed-size process table. We could use a linked list, but this - would probably be too slow. - - Try to allocate next_pid, incrementing next_pid and trying again - up to size() times at which point we reach the conclusion that - table is full. Eventually at this point we would grow the table - by size() and start over. If we find a pid to use, - - If all else fails, sweep through the loop looking for processes that - may have died abnormally without registering themselves as "dead". - Clear out these pinfo structures. Then scan the table again. - - Note that the process table is in the shared data space and thus - is susceptible to corruption. The amount of time spent scanning the - table is presumably quite small compared with the total time to - create a process. -*/ - -pinfo * -pinfo_list::allocate_pid (void) -{ - - pinfo *newp; - - lock_pinfo_for_update (INFINITE); - for (int tries = 0; ; tries++) - { - for (int i = next_pid; i < (next_pid + size ()); i++) - { - /* i mod size() gives place to check */ - newp = vec + (i % size()); - if (newp->process_state == PID_NOT_IN_USE) - { - debug_printf ("found empty slot %d for pid %d", - (i % size ()), i); - next_pid = i; - goto gotit; - } - } - - if (tries > 0) - break; - - /* try once to remove bogus dead processes */ - debug_printf ("clearing out deadwood"); - for (newp = vec; newp < vec + size(); newp++) - proc_exists (newp); - } - - /* The process table is full. */ - debug_printf ("process table is full"); - unlock_pinfo (); - - return NULL; - -gotit: - - /* Set new pid based on the position of this element in the pinfo list */ - newp->pid = next_pid; - - /* Determine next slot to consider, wrapping if we hit the end of - * the array. Since allocation involves looping through size () pids, - * don't allow next_pid to be greater than SHRT_MAX - size (). - */ - if (next_pid < (SHRT_MAX - size ())) - next_pid++; - else - next_pid = PBASE; - - newp->process_state = PID_IN_USE; - unlock_pinfo (); - - memset (newp, 0, PINFO_ZERO); - debug_printf ("pid %d, state %x", newp->pid, newp->process_state); - return newp; -} - -void -pinfo::record_death (int lock) -{ - int unlock = lock ? 0 : lock_pinfo_for_update (999); - if (dwProcessId == GetCurrentProcessId () && !my_parent_is_alive ()) - { - process_state = PID_NOT_IN_USE; - hProcess = NULL; - } - - if (unlock) - unlock_pinfo (); -} - -/* DOCTOOL-START - -<sect1 id="func-cygwin-winpid-to-pid"> - <title>cygwin_winpid_to_pid</title> - - <funcsynopsis> - <funcdef>extern "C" pid_t - <function>cygwin_winpid_to_pid</function> - </funcdef> - <paramdef>int <parameter>winpid</parameter></paramdef> - </funcsynopsis> - - <para>Given a windows pid, converts to the corresponding Cygwin -pid, if any. Returns -1 if windows pid does not correspond to -a cygwin pid.</para> - <example> - <title>Example use of cygwin_winpid_to_pid</title> - <programlisting> - extern "C" cygwin_winpid_to_pid (int winpid); - pid_t mypid; - mypid = cygwin_winpid_to_pid (windows_pid); - </programlisting> - </example> -</sect1> - - DOCTOOL-END */ - -extern "C" pid_t -cygwin_winpid_to_pid (int winpid) -{ - for (int i = 0; i < cygwin_shared->p.size (); i++) - { - pinfo *p = &cygwin_shared->p.vec[i]; - - if (p->process_state == PID_NOT_IN_USE) - continue; - - /* FIXME: signed vs unsigned comparison: winpid can be < 0 !!! */ - if (p->dwProcessId == (DWORD)winpid) - return p->pid; - } - - set_errno (ESRCH); - return (pid_t) -1; -} |