/*------------------------------------------------------------------------- * * kill.c * kill() * * Copyright (c) 1996-2024, 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