diff options
author | ajs <ajs> | 2005-01-12 18:27:27 +0100 |
---|---|---|
committer | ajs <ajs> | 2005-01-12 18:27:27 +0100 |
commit | 40abf2392ba9f14935dab556f43e674cb5c47cf3 (patch) | |
tree | 3c5ff5794940f408b411c5d0204e27dac1014378 /lib/sigevent.c | |
parent | 2005-01-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu> (diff) | |
download | frr-40abf2392ba9f14935dab556f43e674cb5c47cf3.tar.xz frr-40abf2392ba9f14935dab556f43e674cb5c47cf3.zip |
2005-01-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* configure.ac: Test for header file <ucontext.h> (for use in
signal processing).
* sigevent.c: (trap_default_signals) Use the SA_SIGINFO flag to
pass additional siginfo_t and ucontext_t arguments to core_handler
and exit_handler.
(core_handler,exit_handler) Now invoked with 3 arguments (using
SA_SIGINFO). Pass additional info to zlog_signal.
(program_counter) New function to find program counter in ucontext_t,
needs to be enhanced to support more platforms (currently works only
on Linux/x86).
* log.h: Change the zlog_signal prototype to add new arguments
siginfo_t * and program_counter.
* log.c: (zlog_signal) Add new arguments siginfo and program_counter.
Include si_addr and program counter (if non-NULL) in message.
And remove #ifdef HAVE_GLIBC_BACKTRACE around hex_append, since
that is now used to render the si_addr and PC pointers.
Diffstat (limited to '')
-rw-r--r-- | lib/sigevent.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/lib/sigevent.c b/lib/sigevent.c index 5ac226a4c..7acdad290 100644 --- a/lib/sigevent.c +++ b/lib/sigevent.c @@ -23,6 +23,15 @@ #include <sigevent.h> #include <log.h> +#ifdef HAVE_UCONTEXT_H +#ifdef GNU_LINUX +/* get REG_EIP from ucontext.h */ +#define __USE_GNU +#endif /* GNU_LINUX */ +#include <ucontext.h> +#endif /* HAVE_UCONTEXT_H */ + + /* master signals descriptor struct */ struct quagga_sigevent_master_t { @@ -124,7 +133,7 @@ quagga_signal_timer (struct thread *t) #endif /* SIGEVENT_SCHEDULE_THREAD */ /* Initialization of signal handles. */ -/* Signale wrapper. */ +/* Signal wrapper. */ static int signal_set (int signo) { @@ -152,17 +161,33 @@ signal_set (int signo) return 0; } +/* XXX This function should be enhanced to support more platforms + (it currently works only on Linux/x86). */ +static void * +program_counter(void *context) +{ +#ifdef HAVE_UCONTEXT_H +#ifdef GNU_LINUX +#ifdef REG_EIP + if (context) + return (void *)(((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]); +#endif /* REG_EIP */ +#endif /* GNU_LINUX */ +#endif /* HAVE_UCONTEXT_H */ + return NULL; +} + static void -exit_handler(int signo) +exit_handler(int signo, siginfo_t *siginfo, void *context) { - zlog_signal(signo,"exiting..."); + zlog_signal(signo, "exiting...", siginfo, program_counter(context)); _exit(128+signo); } static void -core_handler(int signo) +core_handler(int signo, siginfo_t *siginfo, void *context) { - zlog_signal(signo,"aborting..."); + zlog_signal(signo, "aborting...", siginfo, program_counter(context)); abort(); } @@ -211,11 +236,11 @@ trap_default_signals(void) static const struct { const int *sigs; u_int nsigs; - void (*handler)(int); + void (*handler)(int signo, siginfo_t *info, void *context); } sigmap[] = { - { core_signals, sizeof(core_signals)/sizeof(core_signals[0]),core_handler }, - { exit_signals, sizeof(exit_signals)/sizeof(exit_signals[0]),exit_handler }, - { ignore_signals, sizeof(ignore_signals)/sizeof(ignore_signals[0]),SIG_IGN}, + { core_signals, sizeof(core_signals)/sizeof(core_signals[0]), core_handler}, + { exit_signals, sizeof(exit_signals)/sizeof(exit_signals[0]), exit_handler}, + { ignore_signals, sizeof(ignore_signals)/sizeof(ignore_signals[0]), NULL}, }; u_int i; @@ -230,9 +255,18 @@ trap_default_signals(void) (oact.sa_handler == SIG_DFL)) { struct sigaction act; - act.sa_handler = sigmap[i].handler; sigfillset (&act.sa_mask); - act.sa_flags = 0; + if (sigmap[i].handler == NULL) + { + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + } + else + { + /* Request extra arguments to signal handler. */ + act.sa_sigaction = sigmap[i].handler; + act.sa_flags = SA_SIGINFO; + } if (sigaction(sigmap[i].sigs[j],&act,NULL) < 0) zlog_warn("Unable to set signal handler for signal %d: %s", sigmap[i].sigs[j],safe_strerror(errno)); |