]> granicus.if.org Git - postgresql/blob - src/port/kill.c
Add support for optional_argument to our own getopt_long() implementation.
[postgresql] / src / port / kill.c
1 /*-------------------------------------------------------------------------
2  *
3  * kill.c
4  *        kill()
5  *
6  * Copyright (c) 1996-2014, 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
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