1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1999-2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8/* 9 * Kill - 10 * Simulate Unix kill on Windows/NT and Windows/9X. 11 * This good enough to support the Berkeley DB test suite, 12 * but may be missing some favorite features. 13 * 14 * Would have used MKS kill, but it didn't seem to work well 15 * on Win/9X. Cygnus kill works within the Gnu/Cygnus environment 16 * (where processes are given small pids, with presumably a translation 17 * table between small pids and actual process handles), but our test 18 * environment, via Tcl, does not use the Cygnus environment. 19 * 20 * Compile this and install it as c:/tools/kill.exe (or as indicated 21 * by build_windows/include.tcl ). 22 */ 23 24#include <windows.h> 25#include <stdio.h> 26#include <stdlib.h> 27#include <limits.h> 28 29/* 30 * Like atol, with specified base. Would use stdlib, but 31 * strtol("0xFFFF1234", NULL, 16) returns 0x7FFFFFFF and 32 * strtol("4294712487", NULL, 16) returns 0x7FFFFFFF w/ VC++ 33 */ 34long 35myatol(char *s, int base) 36{ 37 long result = 0; 38 char ch; 39 int sign = 1; /* + */ 40 if (base == 0) 41 base = 10; 42 if (base != 10 && base != 16) 43 return LONG_MAX; 44 while ((ch = *s++) != '\0') { 45 if (ch == '-') { 46 sign = -sign; 47 } 48 else if (ch >= '0' && ch <= '9') { 49 result = result * base + (ch - '0'); 50 } 51 else if (ch == 'x' || ch == 'X') { 52 /* Allow leading 0x..., and switch to base 16 */ 53 base = 16; 54 } 55 else if (base == 16 && ch >= 'a' && ch <= 'f') { 56 result = result * base + (ch - 'a' + 10); 57 } 58 else if (base == 16 && ch >= 'A' && ch <= 'F') { 59 result = result * base + (ch - 'A' + 10); 60 } 61 else { 62 if (sign > 1) 63 return LONG_MAX; 64 else 65 return LONG_MIN; 66 } 67 } 68 return sign * result; 69} 70 71void 72usage_exit() 73{ 74 fprintf(stderr, "Usage: kill [ -sig ] pid\n"); 75 fprintf(stderr, " for win32, sig must be or 0, 15 (TERM)\n"); 76 exit(EXIT_FAILURE); 77} 78 79int 80main(int argc, char **argv) 81{ 82 HANDLE hProcess ; 83 DWORD accessflag; 84 long pid; 85 int sig = 15; 86 87 if (argc > 2) { 88 if (argv[1][0] != '-') 89 usage_exit(); 90 91 if (strcmp(argv[1], "-TERM") == 0) 92 sig = 15; 93 else { 94 /* currently sig is more or less ignored, 95 * we only care if it is zero or not 96 */ 97 sig = atoi(&argv[1][1]); 98 if (sig < 0) 99 usage_exit(); 100 } 101 argc--; 102 argv++; 103 } 104 if (argc < 2) 105 usage_exit(); 106 107 pid = myatol(argv[1], 10); 108 /*printf("pid = %ld (0x%lx) (command line %s)\n", pid, pid, argv[1]);*/ 109 if (pid == LONG_MAX || pid == LONG_MIN) 110 usage_exit(); 111 112 if (sig == 0) 113 accessflag = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ; 114 else 115 accessflag = STANDARD_RIGHTS_REQUIRED | PROCESS_TERMINATE; 116 hProcess = OpenProcess(accessflag, FALSE, pid); 117 if (hProcess == NULL) { 118 fprintf(stderr, "dbkill: %s: no such process\n", argv[1]); 119 exit(EXIT_FAILURE); 120 } 121 if (sig == 0) 122 exit(EXIT_SUCCESS); 123 if (!TerminateProcess(hProcess, 99)) { 124 DWORD err = GetLastError(); 125 fprintf(stderr, 126 "dbkill: cannot kill process: error %d (0x%lx)\n", err, err); 127 exit(EXIT_FAILURE); 128 } 129 return EXIT_SUCCESS; 130} 131