X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fsig-monitor.c;h=9e13fa13fc8956b5d1ec16ac46bbe2c9634ef103;hb=refs%2Fheads%2Fsandbox%2FDDTLK%2Fpakage;hp=f5762bcc280e2bf2c21a2e068bb18c89ae2b0702;hpb=b7254323f35a172543ead20235bf77dd5408ccd8;p=src%2Fapp-framework-binder.git diff --git a/src/sig-monitor.c b/src/sig-monitor.c index f5762bcc..9e13fa13 100644 --- a/src/sig-monitor.c +++ b/src/sig-monitor.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 "IoT.bzh" + * Copyright (C) 2017, 2018 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -43,6 +43,9 @@ static _Thread_local timer_t thread_timerid; /* internal signal lists */ static int sigerr[] = { SIG_FOR_TIMER, SIGSEGV, SIGFPE, SIGILL, SIGBUS, 0 }; static int sigterm[] = { SIGINT, SIGABRT, SIGTERM, 0 }; +static int exiting = 0; +static int enabled = 0; + /* * Dumps the current stack */ @@ -183,6 +186,25 @@ static int install(void (*handler)(int), int *signals) return result; } +/* + * rescue exit + */ +static void on_rescue_exit(int signum) +{ + ERROR("Rescue exit for signal %d: %s", signum, strsignal(signum)); + _exit(exiting); +} + +/* + * Do a safe exit + */ +static void safe_exit(int code) +{ + install(on_rescue_exit, sigerr); + install(on_rescue_exit, sigterm); + exiting = code; + exit(code); +} /* Handles signals that terminate the process */ static void on_signal_terminate (int signum) @@ -192,7 +214,7 @@ static void on_signal_terminate (int signum) if (signum == SIGABRT) safe_dumpstack(3, signum); } - exit(1); + safe_exit(1); } /* Handles monitored signals that can be continued */ @@ -212,12 +234,28 @@ static void on_signal_error(int signum) longjmp(*error_handler, signum); ERROR("Unmonitored signal %d received: %s", signum, strsignal(signum)); - exit(2); + safe_exit(2); } -int sig_monitor_init() +void sig_monitor_disable() { - return (install(on_signal_error, sigerr) & install(on_signal_terminate, sigterm)) - 1; + enabled = 0; + install(SIG_DFL, sigerr); + install(SIG_DFL, sigterm); +} + +int sig_monitor_enable() +{ + enabled = install(on_signal_error, sigerr) && install(on_signal_terminate, sigterm); + if (enabled) + return 0; + sig_monitor_disable(); + return -1; +} + +int sig_monitor_init(int enable) +{ + return enable ? sig_monitor_enable() : (sig_monitor_disable(), 0); } int sig_monitor_init_timeouts() @@ -230,7 +268,7 @@ void sig_monitor_clean_timeouts() timeout_delete(); } -void sig_monitor(int timeout, void (*function)(int sig, void*), void *arg) +static void monitor(int timeout, void (*function)(int sig, void*), void *arg) { volatile int signum, signum2; sigjmp_buf jmpbuf, *older; @@ -239,17 +277,30 @@ void sig_monitor(int timeout, void (*function)(int sig, void*), void *arg) signum = setjmp(jmpbuf); if (signum == 0) { error_handler = &jmpbuf; - if (timeout) + if (timeout) { + timeout_create(); timeout_arm(timeout); + } function(0, arg); } else { signum2 = setjmp(jmpbuf); if (signum2 == 0) function(signum, arg); } - error_handler = older; if (timeout) timeout_disarm(); + error_handler = older; } +void sig_monitor(int timeout, void (*function)(int sig, void*), void *arg) +{ + if (enabled) + monitor(timeout, function, arg); + else + function(0, arg); +} +void sig_monitor_dumpstack() +{ + return dumpstack(1, 0); +}