/* * Signal compat. * * Copyright (c) 2009 Marko Kreen * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include /* * alarm() for win32 */ #ifdef WIN32 struct AlarmCtx { struct sigaction sa; HANDLE event; HANDLE thread; int secs; }; static volatile struct AlarmCtx actx; static DWORD WINAPI w32_alarm_thread(LPVOID arg) { DWORD wres; unsigned msecs; loop: if (actx.secs > 0) { msecs = actx.secs * 1000; } else { msecs = INFINITE; } wres = WaitForSingleObject(actx.event, msecs); if (wres == WAIT_OBJECT_0) { goto loop; } else if (wres == WAIT_TIMEOUT) { actx.secs = 0; if (actx.sa.sa_handler) actx.sa.sa_handler(SIGALRM); goto loop; } else { Sleep(1000); goto loop; } return 0; } unsigned int alarm(unsigned int secs) { actx.secs = secs; /* create event */ if (!actx.event) { actx.event = CreateEvent(NULL, FALSE, FALSE, NULL); if (!actx.event) return 0; } /* create or notify thread */ if (!actx.thread) { actx.thread = CreateThread(NULL, 0, w32_alarm_thread, NULL, 0, NULL); } else { SetEvent(actx.event); } return 0; } #endif #ifndef HAVE_SIGACTION int sigaction(int sig, const struct sigaction *sa, struct sigaction *old) { #ifdef WIN32 if (sig == SIGALRM) { if (old) *old = actx.sa; if (sa) actx.sa = *sa; else actx.sa.sa_handler = NULL; return 0; } #endif old->sa_handler = signal(sig, sa->sa_handler); if (old->sa_handler == SIG_ERR) return -1; return 0; } #endif #ifdef WIN32 /* Only sig=0 is supported, to detect if process is running (ESRCH->not) */ int kill(int pid, int sig) { HANDLE hProcess; DWORD exitCode; int ret = 0; /* handle only sig == 0 */ if (sig != 0) { errno = EINVAL; return -1; } hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (hProcess == NULL) { if (GetLastError() == ERROR_INVALID_PARAMETER) ret = ESRCH; else ret = EPERM; } else { /* OpenProcess may succed for exited processes */ if (GetExitCodeProcess(hProcess, &exitCode)) { if (exitCode != STILL_ACTIVE) ret = ESRCH; } CloseHandle(hProcess); } if (ret) { errno = ret; return -1; } else return 0; } #endif