1 /*-------------------------------------------------------------------------
2 *
3 * kill.c
4 * kill()
5 *
6 * Copyright (c) 1996-2017, PostgreSQL Global Development Group
7 *
8 * This is a replacement version of kill for Win32 which sends
9 * signals that the backend can recognize.
10 *
11 * IDENTIFICATION
12 * src/port/kill.c
13 *
14 *-------------------------------------------------------------------------
15 */
16
17 #include "c.h"
18
19 #ifdef WIN32
20 /* signal sending */
21 int
pgkill(int pid,int sig)22 pgkill(int pid, int sig)
23 {
24 char pipename[128];
25 BYTE sigData = sig;
26 BYTE sigRet = 0;
27 DWORD bytes;
28
29 /* we allow signal 0 here, but it will be ignored in pg_queue_signal */
30 if (sig >= PG_SIGNAL_COUNT || sig < 0)
31 {
32 errno = EINVAL;
33 return -1;
34 }
35 if (pid <= 0)
36 {
37 /* No support for process groups */
38 errno = EINVAL;
39 return -1;
40 }
41
42 /* special case for SIGKILL: just ask the system to terminate the target */
43 if (sig == SIGKILL)
44 {
45 HANDLE prochandle;
46
47 if ((prochandle = OpenProcess(PROCESS_TERMINATE, FALSE, (DWORD) pid)) == NULL)
48 {
49 errno = ESRCH;
50 return -1;
51 }
52 if (!TerminateProcess(prochandle, 255))
53 {
54 _dosmaperr(GetLastError());
55 CloseHandle(prochandle);
56 return -1;
57 }
58 CloseHandle(prochandle);
59 return 0;
60 }
61 snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\pgsignal_%u", pid);
62
63 if (CallNamedPipe(pipename, &sigData, 1, &sigRet, 1, &bytes, 1000))
64 {
65 if (bytes != 1 || sigRet != sig)
66 {
67 errno = ESRCH;
68 return -1;
69 }
70 return 0;
71 }
72
73 switch (GetLastError())
74 {
75 case ERROR_BROKEN_PIPE:
76 case ERROR_BAD_PIPE:
77
78 /*
79 * These arise transiently as a process is exiting. Treat them
80 * like POSIX treats a zombie process, reporting success.
81 */
82 return 0;
83
84 case ERROR_FILE_NOT_FOUND:
85 /* pipe fully gone, so treat the process as gone */
86 errno = ESRCH;
87 return -1;
88 case ERROR_ACCESS_DENIED:
89 errno = EPERM;
90 return -1;
91 default:
92 errno = EINVAL; /* unexpected */
93 return -1;
94 }
95 }
96
97 #endif
98