1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
/* signals.c -- general signals interface for nmh
*
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
* complete copyright information.
*/
#include "h/mh.h"
#include <signal.h>
#include "signals.h"
#include "m_mktemp.h"
/*
* A version of the function `signal' that uses reliable
* signals, if the machine supports them. Also, (assuming
* OS support), it restarts interrupted system calls for all
* signals except SIGALRM.
*
* Since we are now assuming POSIX signal support everywhere, we always
* use reliable signals.
*/
SIGNAL_HANDLER
SIGNAL (int sig, SIGNAL_HANDLER func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sig == SIGALRM) {
# ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT; /* SunOS */
# endif
} else {
# ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, BSD4.4 */
# endif
}
if (sigaction(sig, &act, &oact) < 0)
return SIG_ERR;
return oact.sa_handler;
}
/*
* A version of the function `signal' that will set
* the handler of `sig' to `func' if the signal is
* not currently set to SIG_IGN. Also uses reliable
* signals if available.
*/
SIGNAL_HANDLER
SIGNAL2 (int sig, SIGNAL_HANDLER func)
{
struct sigaction act, oact;
if (sigaction(sig, NULL, &oact) < 0)
return SIG_ERR;
if (oact.sa_handler != SIG_IGN) {
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sig == SIGALRM) {
# ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT; /* SunOS */
# endif
} else {
# ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, BSD4.4 */
# endif
}
if (sigaction(sig, &act, &oact) < 0)
return SIG_ERR;
}
return oact.sa_handler;
}
/*
* For use by nmh_init().
*/
int
setup_signal_handlers(void)
{
/*
* Catch HUP, INT, QUIT, and TERM so that we can clean up tmp
* files when the user terminates the process early. And also a
* few other common signals that can be thrown due to bugs, stack
* overflow, etc.
*/
if (SIGNAL(SIGHUP, remove_registered_files) == SIG_ERR ||
SIGNAL(SIGINT, remove_registered_files) == SIG_ERR ||
SIGNAL(SIGQUIT, remove_registered_files) == SIG_ERR ||
SIGNAL(SIGTERM, remove_registered_files) == SIG_ERR ||
SIGNAL(SIGILL, remove_registered_files) == SIG_ERR ||
# ifdef SIGBUS
SIGNAL(SIGBUS, remove_registered_files) == SIG_ERR ||
# endif
SIGNAL(SIGSEGV, remove_registered_files) == SIG_ERR) {
return NOTOK;
}
return OK;
}
|