diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-12-02 09:01:21 +0000 |
---|---|---|
committer | <> | 2014-12-04 16:11:25 +0000 |
commit | bdab5265fcbf3f472545073a23f8999749a9f2b9 (patch) | |
tree | c6018dd03dea906f8f1fb5f105f05b71a7dc250a /libntp/syssignal.c | |
download | ntp-dev-4.2.7p482.tar.gz |
Imported from /home/lorry/working-area/delta_ntp/ntp-dev-4.2.7p482.tar.gz.ntp-dev-4.2.7p482
Diffstat (limited to 'libntp/syssignal.c')
-rw-r--r-- | libntp/syssignal.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/libntp/syssignal.c b/libntp/syssignal.c new file mode 100644 index 0000000..5e496a9 --- /dev/null +++ b/libntp/syssignal.c @@ -0,0 +1,188 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <sys/types.h> +#include <signal.h> + +#include "ntp_syslog.h" +#include "ntp_stdlib.h" + +static ctrl_c_fn ctrl_c_hook; +#ifndef SYS_WINNT +RETSIGTYPE sigint_handler(int); +#else +BOOL WINAPI console_event_handler(DWORD); +#endif + + +#ifdef HAVE_SIGACTION + +# ifdef SA_RESTART +# define Z_SA_RESTART SA_RESTART +# else +# define Z_SA_RESTART 0 +# endif + +void +signal_no_reset( + int sig, + void (*func)(int) + ) +{ + int n; + struct sigaction vec; + struct sigaction ovec; + + ZERO(vec); + sigemptyset(&vec.sa_mask); + vec.sa_handler = func; + + /* Added for PPS clocks on Solaris 7 which get EINTR errors */ +# ifdef SIGPOLL + if (SIGPOLL == sig) + vec.sa_flags = Z_SA_RESTART; +# endif +# ifdef SIGIO + if (SIGIO == sig) + vec.sa_flags = Z_SA_RESTART; +# endif + + do + n = sigaction(sig, &vec, &ovec); + while (-1 == n && EINTR == errno); + if (-1 == n) { + perror("sigaction"); + exit(1); + } +} + +#elif HAVE_SIGVEC + +void +signal_no_reset( + int sig, + RETSIGTYPE (*func)(int) + ) +{ + struct sigvec sv; + int n; + + ZERO(sv); + sv.sv_handler = func; + n = sigvec(sig, &sv, (struct sigvec *)NULL); + if (-1 == n) { + perror("sigvec"); + exit(1); + } +} + +#elif HAVE_SIGSET + +void +signal_no_reset( + int sig, + RETSIGTYPE (*func)(int) + ) +{ + int n; + + n = sigset(sig, func); + if (-1 == n) { + perror("sigset"); + exit(1); + } +} + +#else + +/* Beware! This implementation resets the signal to SIG_DFL */ +void +signal_no_reset( + int sig, + RETSIGTYPE (*func)(int) + ) +{ +#ifndef SIG_ERR +# define SIG_ERR (-1) +#endif + if (SIG_ERR == signal(sig, func)) { + perror("signal"); + exit(1); + } +} + +#endif + +#ifndef SYS_WINNT +/* + * POSIX implementation of set_ctrl_c_hook() + */ +RETSIGTYPE +sigint_handler( + int signum + ) +{ + UNUSED_ARG(signum); + if (ctrl_c_hook != NULL) + (*ctrl_c_hook)(); +} + +void +set_ctrl_c_hook( + ctrl_c_fn c_hook + ) +{ + RETSIGTYPE (*handler)(int); + + if (NULL == c_hook) { + handler = SIG_DFL; + ctrl_c_hook = NULL; + } else { + handler = &sigint_handler; + ctrl_c_hook = c_hook; + } + signal_no_reset(SIGINT, handler); +} +#else /* SYS_WINNT follows */ +/* + * Windows implementation of set_ctrl_c_hook() + */ +BOOL WINAPI +console_event_handler( + DWORD dwCtrlType + ) +{ + BOOL handled; + + if (CTRL_C_EVENT == dwCtrlType && ctrl_c_hook != NULL) { + (*ctrl_c_hook)(); + handled = TRUE; + } else { + handled = FALSE; + } + + return handled; +} +void +set_ctrl_c_hook( + ctrl_c_fn c_hook + ) +{ + BOOL install; + + if (NULL == c_hook) { + ctrl_c_hook = NULL; + install = FALSE; + } else { + ctrl_c_hook = c_hook; + install = TRUE; + } + if (!SetConsoleCtrlHandler(&console_event_handler, install)) + msyslog(LOG_ERR, "Can't %s console control handler: %m", + (install) + ? "add" + : "remove"); +} +#endif /* SYS_WINNT */ |