2004-05-27 15:08:57 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* kill.c
|
|
|
|
* kill()
|
|
|
|
*
|
2018-01-03 05:30:12 +01:00
|
|
|
* Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
2004-05-27 15:08:57 +02:00
|
|
|
*
|
|
|
|
* This is a replacement version of kill for Win32 which sends
|
|
|
|
* signals that the backend can recognize.
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/port/kill.c
|
2004-05-27 15:08:57 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2004-06-24 20:53:48 +02:00
|
|
|
#include "c.h"
|
2004-05-27 15:08:57 +02:00
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
/* signal sending */
|
|
|
|
int
|
|
|
|
pgkill(int pid, int sig)
|
|
|
|
{
|
|
|
|
char pipename[128];
|
|
|
|
BYTE sigData = sig;
|
|
|
|
BYTE sigRet = 0;
|
|
|
|
DWORD bytes;
|
|
|
|
|
2004-08-27 20:31:48 +02:00
|
|
|
/* we allow signal 0 here, but it will be ignored in pg_queue_signal */
|
|
|
|
if (sig >= PG_SIGNAL_COUNT || sig < 0)
|
2004-05-27 15:08:57 +02:00
|
|
|
{
|
|
|
|
errno = EINVAL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (pid <= 0)
|
|
|
|
{
|
|
|
|
/* No support for process groups */
|
|
|
|
errno = EINVAL;
|
|
|
|
return -1;
|
|
|
|
}
|
Send SIGKILL to children if they don't die quickly in immediate shutdown
On immediate shutdown, or during a restart-after-crash sequence,
postmaster used to send SIGQUIT (and then abandon ship if shutdown); but
this is not a good strategy if backends don't die because of that
signal. (This might happen, for example, if a backend gets tangled
trying to malloc() due to gettext(), as in an example illustrated by
MauMau.) This causes problems when later trying to restart the server,
because some processes are still attached to the shared memory segment.
Instead of just abandoning such backends to their fates, we now have
postmaster hang around for a little while longer, send a SIGKILL after
some reasonable waiting period, and then exit. This makes immediate
shutdown more reliable.
There is disagreement on whether it's best for postmaster to exit after
sending SIGKILL, or to stick around until all children have reported
death. If this controversy is resolved differently than what this patch
implements, it's an easy change to make.
Bug reported by MauMau in message 20DAEA8949EC4E2289C6E8E58560DEC0@maumau
MauMau and Álvaro Herrera
2013-06-28 23:20:53 +02:00
|
|
|
|
|
|
|
/* special case for SIGKILL: just ask the system to terminate the target */
|
|
|
|
if (sig == SIGKILL)
|
|
|
|
{
|
2014-05-06 18:12:18 +02:00
|
|
|
HANDLE prochandle;
|
Send SIGKILL to children if they don't die quickly in immediate shutdown
On immediate shutdown, or during a restart-after-crash sequence,
postmaster used to send SIGQUIT (and then abandon ship if shutdown); but
this is not a good strategy if backends don't die because of that
signal. (This might happen, for example, if a backend gets tangled
trying to malloc() due to gettext(), as in an example illustrated by
MauMau.) This causes problems when later trying to restart the server,
because some processes are still attached to the shared memory segment.
Instead of just abandoning such backends to their fates, we now have
postmaster hang around for a little while longer, send a SIGKILL after
some reasonable waiting period, and then exit. This makes immediate
shutdown more reliable.
There is disagreement on whether it's best for postmaster to exit after
sending SIGKILL, or to stick around until all children have reported
death. If this controversy is resolved differently than what this patch
implements, it's an easy change to make.
Bug reported by MauMau in message 20DAEA8949EC4E2289C6E8E58560DEC0@maumau
MauMau and Álvaro Herrera
2013-06-28 23:20:53 +02:00
|
|
|
|
|
|
|
if ((prochandle = OpenProcess(PROCESS_TERMINATE, FALSE, (DWORD) pid)) == NULL)
|
|
|
|
{
|
|
|
|
errno = ESRCH;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!TerminateProcess(prochandle, 255))
|
|
|
|
{
|
|
|
|
_dosmaperr(GetLastError());
|
|
|
|
CloseHandle(prochandle);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
CloseHandle(prochandle);
|
|
|
|
return 0;
|
|
|
|
}
|
2007-10-23 19:58:01 +02:00
|
|
|
snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\pgsignal_%u", pid);
|
2009-02-15 14:58:18 +01:00
|
|
|
|
2010-01-31 18:18:28 +01:00
|
|
|
if (CallNamedPipe(pipename, &sigData, 1, &sigRet, 1, &bytes, 1000))
|
2004-05-27 15:08:57 +02:00
|
|
|
{
|
2010-01-31 18:18:28 +01:00
|
|
|
if (bytes != 1 || sigRet != sig)
|
2009-02-15 14:58:18 +01:00
|
|
|
{
|
2010-01-31 18:18:28 +01:00
|
|
|
errno = ESRCH;
|
|
|
|
return -1;
|
2009-02-15 14:58:18 +01:00
|
|
|
}
|
2010-01-31 18:18:28 +01:00
|
|
|
return 0;
|
2004-05-27 15:08:57 +02:00
|
|
|
}
|
|
|
|
|
2014-07-23 06:35:13 +02:00
|
|
|
switch (GetLastError())
|
|
|
|
{
|
|
|
|
case ERROR_BROKEN_PIPE:
|
|
|
|
case ERROR_BAD_PIPE:
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These arise transiently as a process is exiting. Treat them
|
|
|
|
* like POSIX treats a zombie process, reporting success.
|
|
|
|
*/
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case ERROR_FILE_NOT_FOUND:
|
|
|
|
/* pipe fully gone, so treat the process as gone */
|
|
|
|
errno = ESRCH;
|
|
|
|
return -1;
|
|
|
|
case ERROR_ACCESS_DENIED:
|
|
|
|
errno = EPERM;
|
|
|
|
return -1;
|
|
|
|
default:
|
|
|
|
errno = EINVAL; /* unexpected */
|
|
|
|
return -1;
|
|
|
|
}
|
2004-05-27 15:08:57 +02:00
|
|
|
}
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2004-05-27 15:08:57 +02:00
|
|
|
#endif
|