* 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.
This commit is contained in:
		| @@ -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> | Thu Jul 27 22:54:28 2000  Jason Tishler <jt@dothill.com> | ||||||
|  |  | ||||||
| 	* utils/mount.cc (main): Add --show-cygdrive-prefixes option. | 	* 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> | 2000-06-07  Kazuhiro Fujieda <fujieda@jaist.ac.jp> | ||||||
|  |  | ||||||
|         mount.cc (error): New function to report an error and exit. | 	* mount.cc (error): New function to report an error and exit. | ||||||
|         umount.cc (error): Ditto. | 	* umount.cc (error): Ditto. | ||||||
|         (remove_all_automounts): Check return status of cygwin_umount. | 	(remove_all_automounts): Check return status of cygwin_umount. | ||||||
|         (remove_all_user_mounts): Ditto. | 	(remove_all_user_mounts): Ditto. | ||||||
|         (remove_all_system_mounts): Ditto. | 	(remove_all_system_mounts): Ditto. | ||||||
|  |  | ||||||
| 2000-06-05  DJ Delorie  <dj@cygnus.com> | 2000-06-05  DJ Delorie  <dj@cygnus.com> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* kill.cc | /* kill.cc | ||||||
|  |  | ||||||
|    Copyright 1996, 1997, 1998 Cygnus Solutions. |    Copyright 1996, 1997, 1998, 1999, 2000 Red Hat, Inc. | ||||||
|  |  | ||||||
| This file is part of Cygwin. | This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -13,50 +13,72 @@ details. */ | |||||||
| #include <signal.h> | #include <signal.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <time.h> | #include <time.h> | ||||||
|  | #include <errno.h> | ||||||
|  | #include <windows.h> | ||||||
|  |  | ||||||
| static void usage (void); | static void usage (void); | ||||||
| static int getsig (char *); | static int __stdcall getsig (char *); | ||||||
| int a = _timezone; | static void __stdcall forcekill (int, int); | ||||||
|  |  | ||||||
| int | int | ||||||
| main (int ac, char **av) | main (int argc, char **argv) | ||||||
| { | { | ||||||
|   int sig = SIGTERM; |   int sig = SIGTERM; | ||||||
|  |   int force = 0; | ||||||
|  |   int gotsig = 0; | ||||||
|  |  | ||||||
|   if (ac == 1) |   if (argc == 1) | ||||||
|     usage (); |     usage (); | ||||||
|  |  | ||||||
|   if (*(++av)[0] == '-') |   while (*(++argv)[0] == '-') | ||||||
|     if (strcmp(*av + 1, "0") != 0) |     if (strcmp (*argv + 1, "f") == 0) | ||||||
|       sig = getsig (*av++ + 1); |       force = 1; | ||||||
|  |     else if (gotsig) | ||||||
|  |       break; | ||||||
|  |     else if (strcmp(*argv + 1, "0") != 0) | ||||||
|  |       { | ||||||
|  | 	sig = getsig (*argv++ + 1); | ||||||
|  | 	gotsig = 1; | ||||||
|  |       } | ||||||
|     else |     else | ||||||
|       { |       { | ||||||
| 	av++; | 	argv++; | ||||||
| 	sig = 0; | 	sig = 0; | ||||||
| 	goto sig0; | 	goto sig0; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|   if (sig <= 0 || sig > NSIG) |   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); |       exit (1); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| sig0: | sig0: | ||||||
|   while (*av != NULL) |   while (*argv != NULL) | ||||||
|     { |     { | ||||||
|       char *p; |       char *p; | ||||||
|       int pid = strtol (*av, &p, 10); |       int pid = strtol (*argv, &p, 10); | ||||||
|       if (*p != '\0') |       if (*p != '\0') | ||||||
| 	fprintf (stderr, "kill: illegal pid: %s\n", *av); | 	fprintf (stderr, "kill: illegal pid: %s\n", *argv); | ||||||
|       else |       else | ||||||
| 	{ | 	{ | ||||||
|  | #if 0 | ||||||
| 	  printf ("Sending %s(%d) signal to pid %d\n", | 	  printf ("Sending %s(%d) signal to pid %d\n", | ||||||
| 		  strsignal (sig), sig, pid); | 		  strsignal (sig), sig, pid); | ||||||
|  | #endif | ||||||
| 	  if (kill (pid, sig)) | 	  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; |   return 0; | ||||||
| } | } | ||||||
| @@ -83,3 +105,13 @@ getsig (char *in_sig) | |||||||
|     } |     } | ||||||
|   return (strtosigno (sig) ?: atoi (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); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* ps.cc | /* ps.cc | ||||||
|  |  | ||||||
|    Copyright 1996, 1997, 1998 Cygnus Solutions. |    Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions. | ||||||
|  |  | ||||||
| This file is part of Cygwin. | This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -16,6 +16,114 @@ details. */ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <pwd.h> | #include <pwd.h> | ||||||
| #include <sys/cygwin.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 * | static char * | ||||||
| start_time (external_pinfo *child) | start_time (external_pinfo *child) | ||||||
| @@ -36,11 +144,33 @@ start_time (external_pinfo *child) | |||||||
|   return stime; |   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 | int | ||||||
| main (int argc, char *argv[]) | main (int argc, char *argv[]) | ||||||
| { | { | ||||||
|   external_pinfo *p; |   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 *dtitle = "  PID TTY     STIME COMMAND\n"; | ||||||
|   const char *dfmt   = "%5d%4d%10s %s\n"; |   const char *dfmt   = "%5d%4d%10s %s\n"; | ||||||
|   const char *ftitle = "     UID   PID  PPID TTY     STIME COMMAND\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"; |   const char *lfmt   = "%c %5d %5d %5d %8u %4d %3d %8s %s\n"; | ||||||
|   char ch; |   char ch; | ||||||
|  |  | ||||||
|   aflag = lflag = fflag = 0; |   aflag = lflag = fflag = sflag = 0; | ||||||
|   uid = getuid (); |   uid = getuid (); | ||||||
|  |   lflag = 1; | ||||||
|  |  | ||||||
|   while ((ch = getopt (argc, argv, "aelfu:")) != -1) |   while ((ch = getopt (argc, argv, "aelfsu:W")) != -1) | ||||||
|     switch (ch) |     switch (ch) | ||||||
|       { |       { | ||||||
|       case 'a': |       case 'a': | ||||||
| @@ -65,6 +196,9 @@ main (int argc, char *argv[]) | |||||||
|       case 'l': |       case 'l': | ||||||
|         lflag = 1; |         lflag = 1; | ||||||
|         break; |         break; | ||||||
|  |       case 's': | ||||||
|  | 	sflag = 1; | ||||||
|  | 	break; | ||||||
|       case 'u': |       case 'u': | ||||||
|         uid = atoi (optarg); |         uid = atoi (optarg); | ||||||
|         if (uid == 0) |         if (uid == 0) | ||||||
| @@ -80,27 +214,36 @@ main (int argc, char *argv[]) | |||||||
|               } |               } | ||||||
|           } |           } | ||||||
|         break; |         break; | ||||||
|  |       case 'W': | ||||||
|  | 	query = CW_GETPINFO_FULL; | ||||||
|  | 	aflag = 1; | ||||||
|  | 	break; | ||||||
|  |  | ||||||
|       default: |       default: | ||||||
|         fprintf (stderr, "Usage %s [-aefl] [-u uid]\n", argv[0]); |         fprintf (stderr, "Usage %s [-aefl] [-u uid]\n", argv[0]); | ||||||
|         fprintf (stderr, "-f = show process uids, ppids\n"); |         fprintf (stderr, "-f = show process uids, ppids\n"); | ||||||
|         fprintf (stderr, "-l = show process uids, ppids, pgids, winpids\n"); |         fprintf (stderr, "-l = show process uids, ppids, pgids, winpids\n"); | ||||||
|         fprintf (stderr, "-u uid = list processes owned by uid\n"); |         fprintf (stderr, "-u uid = list processes owned by uid\n"); | ||||||
|         fprintf (stderr, "-a, -e = show processes of all users\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); |         exit (1); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|   if (lflag) |   if (sflag) | ||||||
|     printf (ltitle); |     printf (dtitle); | ||||||
|   else if (fflag) |   else if (fflag) | ||||||
|     printf (ftitle); |     printf (ftitle); | ||||||
|   else |   else if (lflag) | ||||||
|     printf (dtitle); |     printf (ltitle); | ||||||
|  |  | ||||||
|   (void) cygwin_internal (CW_LOCK_PINFO, 1000); |   (void) cygwin_internal (CW_LOCK_PINFO, 1000); | ||||||
|  |  | ||||||
|  |   if (query == CW_GETPINFO_FULL && !init_win ()) | ||||||
|  |     query = CW_GETPINFO; | ||||||
|  |  | ||||||
|   for (int pid = 0; |   for (int pid = 0; | ||||||
|        (p = (external_pinfo *) cygwin_internal (CW_GETPINFO, |        (p = (external_pinfo *) cygwin_internal (query, pid | CW_NEXTPID)); | ||||||
| 						  pid | CW_NEXTPID)); |  | ||||||
|        pid = p->pid) |        pid = p->pid) | ||||||
|     { |     { | ||||||
|       if (p->process_state == PID_NOT_IN_USE) |       if (p->process_state == PID_NOT_IN_USE) | ||||||
| @@ -118,8 +261,30 @@ main (int argc, char *argv[]) | |||||||
|       char pname[MAX_PATH]; |       char pname[MAX_PATH]; | ||||||
|       if (p->process_state & PID_ZOMBIE) |       if (p->process_state & PID_ZOMBIE) | ||||||
|         strcpy (pname, "<defunct>"); |         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 |       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]; |       char uname[128]; | ||||||
|  |  | ||||||
| @@ -133,13 +298,13 @@ main (int argc, char *argv[]) | |||||||
|             sprintf (uname, "%d", p->uid); |             sprintf (uname, "%d", p->uid); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|       if (lflag) |       if (sflag) | ||||||
|         printf (lfmt, status, p->pid, p->ppid, p->pgid, |         printf (dfmt, p->pid, p->ctty, start_time (p), pname); | ||||||
|               p->dwProcessId, p->uid, p->ctty, start_time (p), pname); |  | ||||||
|       else if (fflag) |       else if (fflag) | ||||||
|         printf (ffmt, uname, p->pid, p->ppid, p->ctty, start_time (p), pname); |         printf (ffmt, uname, p->pid, p->ppid, p->ctty, start_time (p), pname); | ||||||
|       else |       else if (lflag) | ||||||
|         printf (dfmt, p->pid, p->ctty, start_time (p), pname); |         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); |   (void) cygwin_internal (CW_UNLOCK_PINFO); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user