diff options
author | Christopher Faylor <me@cgf.cx> | 2000-07-29 16:26:37 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-07-29 16:26:37 +0000 |
commit | cc631726d3e1609570170564e442bf735b906448 (patch) | |
tree | b4d9bef98c0e3bb59194e02c271e908023f1b3a2 /winsup/utils/ps.cc | |
parent | 84c7d4093270dc07de4531ab6648a12daaff77c3 (diff) | |
download | newlib-cc631726d3e1609570170564e442bf735b906448.zip newlib-cc631726d3e1609570170564e442bf735b906448.tar.gz newlib-cc631726d3e1609570170564e442bf735b906448.tar.bz2 |
* kill.cc (main): Add '-f' option to force termination of a process.
(forcekill): New function.
* ps.cc (main): Add '-W' option to list Windows pids as well as Cygwin pids.
(dummyprocessmodules): New function.
(GetModuleFileNameEx95): New function.
(init_win): New function.
(to_time_t): New function.
Diffstat (limited to 'winsup/utils/ps.cc')
-rw-r--r-- | winsup/utils/ps.cc | 197 |
1 files changed, 181 insertions, 16 deletions
diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc index cca56ac..593629c 100644 --- a/winsup/utils/ps.cc +++ b/winsup/utils/ps.cc @@ -1,6 +1,6 @@ /* ps.cc - Copyright 1996, 1997, 1998 Cygnus Solutions. + Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions. This file is part of Cygwin. @@ -16,6 +16,114 @@ details. */ #include <stdlib.h> #include <pwd.h> #include <sys/cygwin.h> +#include <tlhelp32.h> +#include <psapi.h> + +typedef BOOL (WINAPI *ENUMPROCESSMODULES)( + HANDLE hProcess, // handle to the process + HMODULE * lphModule, // array to receive the module handles + DWORD cb, // size of the array + LPDWORD lpcbNeeded // receives the number of bytes returned +); + +typedef DWORD (WINAPI *GETMODULEFILENAME)( + HANDLE hProcess, + HMODULE hModule, + LPTSTR lpstrFileName, + DWORD nSize +); + +typedef HANDLE (WINAPI *CREATESNAPSHOT)( + DWORD dwFlags, + DWORD th32ProcessID +); + +// Win95 functions +typedef BOOL (WINAPI *PROCESSWALK)( + HANDLE hSnapshot, + LPPROCESSENTRY32 lppe +); + +ENUMPROCESSMODULES myEnumProcessModules; +GETMODULEFILENAME myGetModuleFileNameEx; +CREATESNAPSHOT myCreateToolhelp32Snapshot; +PROCESSWALK myProcess32First; +PROCESSWALK myProcess32Next; + +static BOOL WINAPI dummyprocessmodules ( + HANDLE hProcess, // handle to the process + HMODULE * lphModule, // array to receive the module handles + DWORD cb, // size of the array + LPDWORD lpcbNeeded // receives the number of bytes returned +) +{ + lphModule[0] = (HMODULE) *lpcbNeeded; + *lpcbNeeded = 1; + return 1; +} + +static DWORD WINAPI GetModuleFileNameEx95 ( + HANDLE hProcess, + HMODULE hModule, + LPTSTR lpstrFileName, + DWORD n +) +{ + HANDLE h; + DWORD pid = (DWORD) hModule; + + h = myCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); + if (!h) + return 0; + + PROCESSENTRY32 proc; + proc.dwSize = sizeof (proc); + if (myProcess32First(h, &proc)) + do + if (proc.th32ProcessID == pid) + { + CloseHandle (h); + strcpy (lpstrFileName, proc.szExeFile); + return 1; + } + while (myProcess32Next (h, &proc)); + CloseHandle (h); + return 0; +} + +int +init_win () +{ + OSVERSIONINFO os_version_info; + + memset (&os_version_info, 0, sizeof os_version_info); + os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + GetVersionEx (&os_version_info); + + HMODULE h; + if (os_version_info.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + h = LoadLibrary ("psapi.dll"); + if (!h) + return 0; + myEnumProcessModules = (ENUMPROCESSMODULES) GetProcAddress (h, "EnumProcessModules"); + myGetModuleFileNameEx = (GETMODULEFILENAME) GetProcAddress (h, "GetModuleFileNameExA"); + if (!myEnumProcessModules || !myGetModuleFileNameEx) + return 0; + return 1; + } + + h = GetModuleHandle("KERNEL32.DLL"); + myCreateToolhelp32Snapshot = (CREATESNAPSHOT)GetProcAddress (h, "CreateToolhelp32Snapshot"); + myProcess32First = (PROCESSWALK)GetProcAddress (h, "Process32First"); + myProcess32Next = (PROCESSWALK)GetProcAddress (h, "Process32Next"); + if (!myCreateToolhelp32Snapshot || !myProcess32First || !myProcess32Next) + return 0; + + myEnumProcessModules = dummyprocessmodules; + myGetModuleFileNameEx = GetModuleFileNameEx95; + return 1; +} static char * start_time (external_pinfo *child) @@ -36,11 +144,33 @@ start_time (external_pinfo *child) return stime; } +#define FACTOR (0x19db1ded53ea710LL) +#define NSPERSEC 10000000LL + +/* Convert a Win32 time to "UNIX" format. */ +long __stdcall +to_time_t (FILETIME *ptr) +{ + /* A file time is the number of 100ns since jan 1 1601 + stuffed into two long words. + A time_t is the number of seconds since jan 1 1970. */ + + long rem; + long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned)ptr->dwLowDateTime); + x -= FACTOR; /* number of 100ns between 1601 and 1970 */ + rem = x % ((long long)NSPERSEC); + rem += (NSPERSEC / 2); + x /= (long long) NSPERSEC; /* number of 100ns in a second */ + x += (long long) (rem / NSPERSEC); + return x; +} + int main (int argc, char *argv[]) { external_pinfo *p; - int aflag, lflag, fflag, uid; + int aflag, lflag, fflag, sflag, uid; + cygwin_getinfo_types query = CW_GETPINFO; const char *dtitle = " PID TTY STIME COMMAND\n"; const char *dfmt = "%5d%4d%10s %s\n"; const char *ftitle = " UID PID PPID TTY STIME COMMAND\n"; @@ -49,10 +179,11 @@ main (int argc, char *argv[]) const char *lfmt = "%c %5d %5d %5d %8u %4d %3d %8s %s\n"; char ch; - aflag = lflag = fflag = 0; + aflag = lflag = fflag = sflag = 0; uid = getuid (); + lflag = 1; - while ((ch = getopt (argc, argv, "aelfu:")) != -1) + while ((ch = getopt (argc, argv, "aelfsu:W")) != -1) switch (ch) { case 'a': @@ -65,6 +196,9 @@ main (int argc, char *argv[]) case 'l': lflag = 1; break; + case 's': + sflag = 1; + break; case 'u': uid = atoi (optarg); if (uid == 0) @@ -80,27 +214,36 @@ main (int argc, char *argv[]) } } break; + case 'W': + query = CW_GETPINFO_FULL; + aflag = 1; + break; + default: fprintf (stderr, "Usage %s [-aefl] [-u uid]\n", argv[0]); fprintf (stderr, "-f = show process uids, ppids\n"); fprintf (stderr, "-l = show process uids, ppids, pgids, winpids\n"); fprintf (stderr, "-u uid = list processes owned by uid\n"); fprintf (stderr, "-a, -e = show processes of all users\n"); + fprintf (stderr, "-s = show process summary\n"); + fprintf (stderr, "-W = show windows as well as cygwin processes\n"); exit (1); } - if (lflag) - printf (ltitle); + if (sflag) + printf (dtitle); else if (fflag) printf (ftitle); - else - printf (dtitle); + else if (lflag) + printf (ltitle); (void) cygwin_internal (CW_LOCK_PINFO, 1000); + if (query == CW_GETPINFO_FULL && !init_win ()) + query = CW_GETPINFO; + for (int pid = 0; - (p = (external_pinfo *) cygwin_internal (CW_GETPINFO, - pid | CW_NEXTPID)); + (p = (external_pinfo *) cygwin_internal (query, pid | CW_NEXTPID)); pid = p->pid) { if (p->process_state == PID_NOT_IN_USE) @@ -118,8 +261,30 @@ main (int argc, char *argv[]) char pname[MAX_PATH]; if (p->process_state & PID_ZOMBIE) strcpy (pname, "<defunct>"); + else if (p->progname[0]) + { + char *s; + cygwin_conv_to_posix_path (p->progname, pname); + s = strchr (pname, '\0') - 4; + if (s > pname && strcasecmp (s, ".exe") == 0) + *s = '\0'; + } else - cygwin_conv_to_posix_path (p->progname, pname); + { + HANDLE h = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, p->dwProcessId); + if (!h) + continue; + HMODULE hm[1000]; + DWORD n = p->dwProcessId; + if (!myEnumProcessModules (h, hm, sizeof (hm), &n)) + n = 0; + if (!n || !myGetModuleFileNameEx (h, hm[0], pname, MAX_PATH)) + strcpy (pname, "*** unknown ***"); + FILETIME ct, et, kt, ut; + if (GetProcessTimes (h, &ct, &et, &kt, &ut)) + p->start_time = to_time_t (&ct); + CloseHandle (h); + } char uname[128]; @@ -133,13 +298,13 @@ main (int argc, char *argv[]) sprintf (uname, "%d", p->uid); } - if (lflag) - printf (lfmt, status, p->pid, p->ppid, p->pgid, - p->dwProcessId, p->uid, p->ctty, start_time (p), pname); + if (sflag) + printf (dfmt, p->pid, p->ctty, start_time (p), pname); else if (fflag) printf (ffmt, uname, p->pid, p->ppid, p->ctty, start_time (p), pname); - else - printf (dfmt, p->pid, p->ctty, start_time (p), pname); + else if (lflag) + printf (lfmt, status, p->pid, p->ppid, p->pgid, + p->dwProcessId, p->uid, p->ctty, start_time (p), pname); } (void) cygwin_internal (CW_UNLOCK_PINFO); |