Add BSD license file
[platform/upstream/db4.git] / build_windows / dbkill.cpp
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  */
34 long
35 myatol(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
71 void
72 usage_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
79 int
80 main(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 }