mirror of
https://github.com/postgres/postgres.git
synced 2025-05-08 07:21:33 +03:00
98 lines
1.9 KiB
C
98 lines
1.9 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* kill.c
|
|
* kill()
|
|
*
|
|
* Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
|
*
|
|
* This is a replacement version of kill for Win32 which sends
|
|
* signals that the backend can recognize.
|
|
*
|
|
* IDENTIFICATION
|
|
* src/port/kill.c
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "c.h"
|
|
|
|
#ifdef WIN32
|
|
/* signal sending */
|
|
int
|
|
pgkill(int pid, int sig)
|
|
{
|
|
char pipename[128];
|
|
BYTE sigData = sig;
|
|
BYTE sigRet = 0;
|
|
DWORD bytes;
|
|
|
|
/* we allow signal 0 here, but it will be ignored in pg_queue_signal */
|
|
if (sig >= PG_SIGNAL_COUNT || sig < 0)
|
|
{
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
if (pid <= 0)
|
|
{
|
|
/* No support for process groups */
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
/* special case for SIGKILL: just ask the system to terminate the target */
|
|
if (sig == SIGKILL)
|
|
{
|
|
HANDLE prochandle;
|
|
|
|
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;
|
|
}
|
|
snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\pgsignal_%u", pid);
|
|
|
|
if (CallNamedPipe(pipename, &sigData, 1, &sigRet, 1, &bytes, 1000))
|
|
{
|
|
if (bytes != 1 || sigRet != sig)
|
|
{
|
|
errno = ESRCH;
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
#endif
|