Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-07-29 20:26:37 +0400
committerChristopher Faylor <me@cgf.cx>2000-07-29 20:26:37 +0400
commitcc631726d3e1609570170564e442bf735b906448 (patch)
treeb4d9bef98c0e3bb59194e02c271e908023f1b3a2 /winsup/utils/ps.cc
parent84c7d4093270dc07de4531ab6648a12daaff77c3 (diff)
* 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.cc197
1 files changed, 181 insertions, 16 deletions
diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc
index cca56ac5f..593629c22 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);