diff options
Diffstat (limited to 'tests/server/util.c')
-rw-r--r-- | tests/server/util.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/tests/server/util.c b/tests/server/util.c index 24f9497ae..5dd4e0a7f 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -509,3 +509,142 @@ long timediff(struct timeval newer, struct timeval older) return (long)(newer.tv_sec-older.tv_sec)*1000+ (long)(newer.tv_usec-older.tv_usec)/1000; } + +/* do-nothing macro replacement for systems which lack siginterrupt() */ + +#ifndef HAVE_SIGINTERRUPT +#define siginterrupt(x,y) do {} while(0) +#endif + +/* vars used to keep around previous signal handlers */ + +typedef RETSIGTYPE (*SIGHANDLER_T)(int); + +#ifdef SIGHUP +static SIGHANDLER_T old_sighup_handler = SIG_ERR; +#endif + +#ifdef SIGPIPE +static SIGHANDLER_T old_sigpipe_handler = SIG_ERR; +#endif + +#ifdef SIGALRM +static SIGHANDLER_T old_sigalrm_handler = SIG_ERR; +#endif + +#ifdef SIGINT +static SIGHANDLER_T old_sigint_handler = SIG_ERR; +#endif + +#ifdef SIGTERM +static SIGHANDLER_T old_sigterm_handler = SIG_ERR; +#endif + +#if defined(SIGBREAK) && defined(WIN32) +static SIGHANDLER_T old_sigbreak_handler = SIG_ERR; +#endif + +/* var which if set indicates that the program should finish execution */ +volatile int got_exit_signal = 0; + +/* if next is set indicates the first signal handled in exit_signal_handler */ +volatile int exit_signal = 0; + +/* signal handler that will be triggered to indicate that the program + * should finish its execution in a controlled manner as soon as possible. + * The first time this is called it will set got_exit_signal to one and + * store in exit_signal the signal that triggered its execution. + */ +static RETSIGTYPE exit_signal_handler(int signum) +{ + int old_errno = errno; + logmsg("exit_signal_handler: %d", signum); + if(got_exit_signal == 0) { + got_exit_signal = 1; + exit_signal = signum; + } + (void)signal(signum, exit_signal_handler); + errno = old_errno; +} + +void install_signal_handlers(bool keep_sigalrm) +{ +#ifdef SIGHUP + /* ignore SIGHUP signal */ + old_sighup_handler = signal(SIGHUP, SIG_IGN); + if(old_sighup_handler == SIG_ERR) + logmsg("cannot install SIGHUP handler: %s", strerror(errno)); +#endif +#ifdef SIGPIPE + /* ignore SIGPIPE signal */ + old_sigpipe_handler = signal(SIGPIPE, SIG_IGN); + if(old_sigpipe_handler == SIG_ERR) + logmsg("cannot install SIGPIPE handler: %s", strerror(errno)); +#endif +#ifdef SIGALRM + if(!keep_sigalrm) { + /* ignore SIGALRM signal */ + old_sigalrm_handler = signal(SIGALRM, SIG_IGN); + if(old_sigalrm_handler == SIG_ERR) + logmsg("cannot install SIGALRM handler: %s", strerror(errno)); + } +#else + (void)keep_sigalrm; +#endif +#ifdef SIGINT + /* handle SIGINT signal with our exit_signal_handler */ + old_sigint_handler = signal(SIGINT, exit_signal_handler); + if(old_sigint_handler == SIG_ERR) + logmsg("cannot install SIGINT handler: %s", strerror(errno)); + else + siginterrupt(SIGINT, 1); +#endif +#ifdef SIGTERM + /* handle SIGTERM signal with our exit_signal_handler */ + old_sigterm_handler = signal(SIGTERM, exit_signal_handler); + if(old_sigterm_handler == SIG_ERR) + logmsg("cannot install SIGTERM handler: %s", strerror(errno)); + else + siginterrupt(SIGTERM, 1); +#endif +#if defined(SIGBREAK) && defined(WIN32) + /* handle SIGBREAK signal with our exit_signal_handler */ + old_sigbreak_handler = signal(SIGBREAK, exit_signal_handler); + if(old_sigbreak_handler == SIG_ERR) + logmsg("cannot install SIGBREAK handler: %s", strerror(errno)); + else + siginterrupt(SIGBREAK, 1); +#endif +} + +void restore_signal_handlers(bool keep_sigalrm) +{ +#ifdef SIGHUP + if(SIG_ERR != old_sighup_handler) + (void)signal(SIGHUP, old_sighup_handler); +#endif +#ifdef SIGPIPE + if(SIG_ERR != old_sigpipe_handler) + (void)signal(SIGPIPE, old_sigpipe_handler); +#endif +#ifdef SIGALRM + if(!keep_sigalrm) { + if(SIG_ERR != old_sigalrm_handler) + (void)signal(SIGALRM, old_sigalrm_handler); + } +#else + (void)keep_sigalrm; +#endif +#ifdef SIGINT + if(SIG_ERR != old_sigint_handler) + (void)signal(SIGINT, old_sigint_handler); +#endif +#ifdef SIGTERM + if(SIG_ERR != old_sigterm_handler) + (void)signal(SIGTERM, old_sigterm_handler); +#endif +#if defined(SIGBREAK) && defined(WIN32) + if(SIG_ERR != old_sigbreak_handler) + (void)signal(SIGBREAK, old_sigbreak_handler); +#endif +} |