summaryrefslogtreecommitdiff
path: root/lib/sigevent.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sigevent.c')
-rw-r--r--lib/sigevent.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/lib/sigevent.c b/lib/sigevent.c
index 09f07180ce..e8c722b987 100644
--- a/lib/sigevent.c
+++ b/lib/sigevent.c
@@ -13,10 +13,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING. If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
@@ -132,8 +131,9 @@ quagga_signal_timer (struct thread *t)
int i;
sigm = THREAD_ARG (t);
- sigm->t = thread_add_timer (sigm->t->master, quagga_signal_timer, &sigmaster,
- QUAGGA_SIGNAL_TIMER_INTERVAL);
+ sigm->t = NULL;
+ thread_add_timer(sigm->t->master, quagga_signal_timer, &sigmaster, QUAGGA_SIGNAL_TIMER_INTERVAL,
+ &sigm->t);
return quagga_sigevent_process ();
}
#endif /* SIGEVENT_SCHEDULE_THREAD */
@@ -233,6 +233,18 @@ core_handler(int signo
#endif
)
{
+ /* make sure we don't hang in here. default for SIGALRM is terminate.
+ * - if we're in backtrace for more than a second, abort. */
+ struct sigaction sa_default = { .sa_handler = SIG_DFL };
+ sigaction (SIGALRM, &sa_default, NULL);
+
+ sigset_t sigset;
+ sigemptyset (&sigset);
+ sigaddset (&sigset, SIGALRM);
+ sigprocmask (SIG_UNBLOCK, &sigset, NULL);
+
+ alarm (1);
+
zlog_signal(signo, "aborting..."
#ifdef SA_SIGINFO
, siginfo, program_counter(context)
@@ -327,6 +339,11 @@ trap_default_signals(void)
act.sa_handler = sigmap[i].handler;
act.sa_flags = 0;
#endif
+#ifdef SA_RESETHAND
+ /* don't try to print backtraces recursively */
+ if (sigmap[i].handler == core_handler)
+ act.sa_flags |= SA_RESETHAND;
+#endif
}
if (sigaction(sigmap[i].sigs[j],&act,NULL) < 0)
zlog_warn("Unable to set signal handler for signal %d: %s",
@@ -361,8 +378,8 @@ signal_init (struct thread_master *m, int sigc,
sigmaster.signals = signals;
#ifdef SIGEVENT_SCHEDULE_THREAD
- sigmaster.t =
- thread_add_timer (m, quagga_signal_timer, &sigmaster,
- QUAGGA_SIGNAL_TIMER_INTERVAL);
+ sigmaster.t = NULL;
+ thread_add_timer(m, quagga_signal_timer, &sigmaster, QUAGGA_SIGNAL_TIMER_INTERVAL,
+ &sigmaster.t);
#endif /* SIGEVENT_SCHEDULE_THREAD */
}