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
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.
-rw-r--r--winsup/utils/ChangeLog21
-rw-r--r--winsup/utils/kill.cc62
-rw-r--r--winsup/utils/ps.cc197
3 files changed, 244 insertions, 36 deletions
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index ca99cb47a..71738b218 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -1,3 +1,14 @@
+Sat Jul 29 00:44:46 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * 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.
+
Thu Jul 27 22:54:28 2000 Jason Tishler <jt@dothill.com>
* utils/mount.cc (main): Add --show-cygdrive-prefixes option.
@@ -31,11 +42,11 @@ Sat Jun 24 23:16:33 2000 Christopher Faylor <cgf@cygnus.com>
2000-06-07 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
- mount.cc (error): New function to report an error and exit.
- umount.cc (error): Ditto.
- (remove_all_automounts): Check return status of cygwin_umount.
- (remove_all_user_mounts): Ditto.
- (remove_all_system_mounts): Ditto.
+ * mount.cc (error): New function to report an error and exit.
+ * umount.cc (error): Ditto.
+ (remove_all_automounts): Check return status of cygwin_umount.
+ (remove_all_user_mounts): Ditto.
+ (remove_all_system_mounts): Ditto.
2000-06-05 DJ Delorie <dj@cygnus.com>
diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc
index 611887896..a7913e43c 100644
--- a/winsup/utils/kill.cc
+++ b/winsup/utils/kill.cc
@@ -1,6 +1,6 @@
/* kill.cc
- Copyright 1996, 1997, 1998 Cygnus Solutions.
+ Copyright 1996, 1997, 1998, 1999, 2000 Red Hat, Inc.
This file is part of Cygwin.
@@ -13,50 +13,72 @@ details. */
#include <signal.h>
#include <string.h>
#include <time.h>
+#include <errno.h>
+#include <windows.h>
static void usage (void);
-static int getsig (char *);
-int a = _timezone;
+static int __stdcall getsig (char *);
+static void __stdcall forcekill (int, int);
int
-main (int ac, char **av)
+main (int argc, char **argv)
{
int sig = SIGTERM;
+ int force = 0;
+ int gotsig = 0;
- if (ac == 1)
+ if (argc == 1)
usage ();
- if (*(++av)[0] == '-')
- if (strcmp(*av + 1, "0") != 0)
- sig = getsig (*av++ + 1);
+ while (*(++argv)[0] == '-')
+ if (strcmp (*argv + 1, "f") == 0)
+ force = 1;
+ else if (gotsig)
+ break;
+ else if (strcmp(*argv + 1, "0") != 0)
+ {
+ sig = getsig (*argv++ + 1);
+ gotsig = 1;
+ }
else
{
- av++;
+ argv++;
sig = 0;
goto sig0;
}
if (sig <= 0 || sig > NSIG)
{
- fprintf (stderr, "kill: unknown signal: %s\n", av[-1]);
+ fprintf (stderr, "kill: unknown signal: %s\n", argv[-1]);
exit (1);
}
sig0:
- while (*av != NULL)
+ while (*argv != NULL)
{
char *p;
- int pid = strtol (*av, &p, 10);
+ int pid = strtol (*argv, &p, 10);
if (*p != '\0')
- fprintf (stderr, "kill: illegal pid: %s\n", *av);
+ fprintf (stderr, "kill: illegal pid: %s\n", *argv);
else
{
+#if 0
printf ("Sending %s(%d) signal to pid %d\n",
strsignal (sig), sig, pid);
+#endif
if (kill (pid, sig))
- perror ("kill");
+ {
+ if (errno == ESRCH && force && sig != 0)
+ forcekill (pid, sig);
+ else
+ {
+ char buf[1000];
+ sprintf (buf, "kill %d", pid);
+ perror (buf);
+ }
+ }
}
- av++;
+ argv++;
}
return 0;
}
@@ -83,3 +105,13 @@ getsig (char *in_sig)
}
return (strtosigno (sig) ?: atoi (in_sig));
}
+
+static void __stdcall
+forcekill (int pid, int sig)
+{
+ HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, (DWORD) pid);
+ if (!h)
+ return;
+ TerminateProcess (h, sig << 8);
+ CloseHandle (h);
+}
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);