1 /* pinfo.cc: process table support
3 Copyright 1996, 1997, 1998, 2000 Cygnus Solutions.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
20 static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0};
22 pinfo NO_COPY myself ((_pinfo *)&pinfo_dummy); // Avoid myself != NULL checks
23 static pinfo NO_COPY myself_identity ((_pinfo *)&pinfo_dummy);
25 /* Initialize the process table.
26 This is done once when the dll is first loaded. */
29 set_myself (pid_t pid)
31 DWORD winpid = GetCurrentProcessId ();
33 pid = cygwin_pid (winpid);
35 myself->dwProcessId = winpid;
36 myself->process_state |= PID_IN_USE;
37 myself->start_time = time (NULL); /* Register our starting time. */
38 pid_t myself_cyg_pid = cygwin_pid (myself->dwProcessId);
39 if (pid != myself_cyg_pid)
40 myself_identity.init (myself_cyg_pid, PID_EXECED);
43 __small_sprintf (buf, "cYg%8x %x", _STRACE_INTERFACE_ACTIVATE_ADDR,
45 OutputDebugString (buf);
47 (void) GetModuleFileName (NULL, myself->progname,
48 sizeof(myself->progname));
52 strace.prntf (1, NULL, "**********************************************");
53 strace.prntf (1, NULL, "Program name: %s", myself->progname);
54 strace.prntf (1, NULL, "App version: %d.%d, api: %d.%d",
55 user_data->dll_major, user_data->dll_minor,
56 user_data->api_major, user_data->api_minor);
57 strace.prntf (1, NULL, "DLL version: %d.%d, api: %d.%d",
58 cygwin_version.dll_major, cygwin_version.dll_minor,
59 cygwin_version.api_major, cygwin_version.api_minor);
60 strace.prntf (1, NULL, "DLL build: %s", cygwin_version.dll_build_date);
61 strace.prntf (1, NULL, "OS version: Windows %s", osname);
62 strace.prntf (1, NULL, "**********************************************");
68 /* Initialize the process table entry for the current task.
69 This is not called for fork'd tasks, only exec'd ones. */
71 pinfo_init (LPBYTE info)
75 /* The process was execed. Reuse entry from the original
77 environ_init (0); /* Needs myself but affects calls below */
79 /* spawn has already set up a pid structure for us so we'll use that */
81 myself->process_state |= PID_CYGPARENT;
83 /* Inherit file descriptor information from parent in info.
85 LPBYTE b = fdtab.de_linearize_fd_array (info);
86 extern char title_buf[];
88 old_title = strcpy (title_buf, (char *)b);
92 /* Invent our own pid. */
96 myself->pgid = myself->sid = myself->pid;
98 myself->uid = USHRT_MAX;
100 environ_init (0); /* call after myself has been set up */
103 debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid);
107 _pinfo::getsig(int sig)
111 return thread2signal->sigs[sig];
119 _pinfo::getsigmask ()
123 return *thread2signal->sigmask;
131 _pinfo::setsigmask (sigset_t _mask)
135 *(thread2signal->sigmask) = _mask;
143 _pinfo::getsigtodo(int sig)
147 return thread2signal->sigtodo + __SIGOFFSET + sig;
148 return _sigtodo + __SIGOFFSET + sig;
150 return _sigtodo + __SIGOFFSET + sig;
154 extern HANDLE hMainThread;
157 _pinfo::getthread2signal()
161 return thread2signal->win32_obj_id;
169 _pinfo::setthread2signal(void *_thr)
172 // assert has myself lock
173 thread2signal=(ThreadItem*)_thr;
179 _pinfo::copysigs(_pinfo *_other)
185 _pinfo::record_death ()
187 /* CGF FIXME - needed? */
188 if (dwProcessId == GetCurrentProcessId () && !my_parent_is_alive ())
190 process_state = PID_NOT_IN_USE;
196 pinfo::init (pid_t n, DWORD create)
198 if (n == myself->pid)
207 char mapname[MAX_PATH];
208 __small_sprintf (mapname, "cygpid.%x", n);
211 if (create & PID_EXECED)
212 mapsize = PINFO_REDIR_SIZE;
214 mapsize = sizeof (_pinfo);
218 /* CGF FIXME -- deal with inheritance after an exec */
219 h = OpenFileMappingA (FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapname);
224 h = CreateFileMapping ((HANDLE) 0xffffffff, &sec_none_nih,
225 PAGE_READWRITE, 0, mapsize, mapname);
226 created = h && GetLastError () != ERROR_ALREADY_EXISTS;
237 child = (_pinfo *) MapViewOfFile (h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
239 if (child->process_state & PID_EXECED)
241 pid_t realpid = child->pid;
244 api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n);
245 return init (realpid);
250 if (!(create & PID_EXECED))
254 child->pid = myself->pid;
255 child->process_state |= PID_IN_USE | PID_EXECED;
264 <sect1 id="func-cygwin-winpid-to-pid">
265 <title>cygwin_winpid_to_pid</title>
268 <funcdef>extern "C" pid_t
269 <function>cygwin_winpid_to_pid</function>
271 <paramdef>int <parameter>winpid</parameter></paramdef>
274 <para>Given a windows pid, converts to the corresponding Cygwin
275 pid, if any. Returns -1 if windows pid does not correspond to
278 <title>Example use of cygwin_winpid_to_pid</title>
280 extern "C" cygwin_winpid_to_pid (int winpid);
282 mypid = cygwin_winpid_to_pid (windows_pid);
290 cygwin_winpid_to_pid (int winpid)
300 #include <tlhelp32.h>
303 typedef BOOL (WINAPI * ENUMPROCESSES) (DWORD *, DWORD, DWORD *);
304 typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD, DWORD);
305 typedef BOOL (WINAPI * PROCESSWALK) (HANDLE, LPPROCESSENTRY32);
306 typedef BOOL (WINAPI * CLOSESNAPSHOT) (HANDLE);
308 static NO_COPY CREATESNAPSHOT myCreateToolhelp32Snapshot = NULL;
309 static NO_COPY PROCESSWALK myProcess32First = NULL;
310 static NO_COPY PROCESSWALK myProcess32Next = NULL;
311 static BOOL WINAPI enum_init (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded);
313 static NO_COPY ENUMPROCESSES myEnumProcesses = enum_init;
316 EnumProcessesW95 (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded)
321 h = myCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
327 proc.dwSize = sizeof (proc);
328 if (myProcess32First(h, &proc))
330 lpidProcess[i++] = cygwin_pid (proc.th32ProcessID);
331 while (myProcess32Next (h, &proc));
335 *cbneeded = i * sizeof (DWORD);
343 if (!myEnumProcesses (pidlist, sizeof (pidlist) / sizeof (pidlist[0]), &n))
346 npids = n / sizeof (pidlist[0]);
352 enum_init (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded)
355 if (os_being_run == winNT)
357 h = LoadLibrary ("psapi.dll");
360 myEnumProcesses = (ENUMPROCESSES) GetProcAddress (h, "EnumProcesses");
361 if (!myEnumProcesses)
366 h = GetModuleHandle("kernel32.dll");
367 myCreateToolhelp32Snapshot = (CREATESNAPSHOT)
368 GetProcAddress(h, "CreateToolhelp32Snapshot");
369 myProcess32First = (PROCESSWALK)
370 GetProcAddress(h, "Process32First");
371 myProcess32Next = (PROCESSWALK)
372 GetProcAddress(h, "Process32Next");
373 if (!myCreateToolhelp32Snapshot || !myProcess32First || !myProcess32Next)
376 myEnumProcesses = EnumProcessesW95;
379 return myEnumProcesses (lpidProcess, cb, cbneeded);