From 80a48ad3ca40991bb67d9e3029417398157a1435 Mon Sep 17 00:00:00 2001 From: pgen Date: Wed, 27 Mar 2019 23:13:57 +0100 Subject: Take care of non async-signal safe functions The signal handler must not contain non async-signal safe functions in it, even if the program exits after having calling one of them. Closes properly the issue #13 --- TODO | 3 --- smenu.c | 48 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/TODO b/TODO index d25354a..bffdbf6 100644 --- a/TODO +++ b/TODO @@ -2,6 +2,3 @@ # ========================================. I: Improve configure.ac I: Improve the checking of system/library calls returns -I: Cleanup the code and split it into several files -I: Make sure that no async-signal-safe functions are - used in the signal handler. diff --git a/smenu.c b/smenu.c index a8c938b..ce05b95 100644 --- a/smenu.c +++ b/smenu.c @@ -123,6 +123,9 @@ volatile sig_atomic_t got_winch_alrm = 0; volatile sig_atomic_t got_help_alrm = 0; volatile sig_atomic_t got_daccess_alrm = 0; volatile sig_atomic_t got_timeout_tick = 0; +volatile sig_atomic_t got_sigsegv = 0; +volatile sig_atomic_t got_sigterm = 0; +volatile sig_atomic_t got_sighup = 0; /* Variables used when a timeout is set (option -x) */ /* """""""""""""""""""""""""""""""""""""""""""""""" */ @@ -3847,21 +3850,16 @@ sig_handler(int s) /* Standard termination signals */ /* """""""""""""""""""""""""""" */ case SIGSEGV: - fputs("SIGSEGV received!\n", stderr); - tputs(TPARM1(carriage_return), 1, outch); - tputs(TPARM1(cursor_visible), 1, outch); - restore_term(fileno(stdin)); - - exit(EXIT_FAILURE); + got_sigsegv = 1; + break; case SIGTERM: - case SIGHUP: - fputs("Interrupted!\n", stderr); - tputs(TPARM1(carriage_return), 1, outch); - tputs(TPARM1(cursor_visible), 1, outch); - restore_term(fileno(stdin)); + got_sigterm = 1; + break; - exit(EXIT_FAILURE); + case SIGHUP: + got_sighup = 1; + break; /* Terminal resize */ /* """"""""""""""" */ @@ -8676,6 +8674,32 @@ main(int argc, char * argv[]) { int sc = 0; /* scancode */ + /* Manage a segmentation fault by exiting with failure and restoring */ + /* the terminal and the cursor. */ + /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (got_sigsegv) + { + fputs("SIGSEGV received!\n", stderr); + tputs(TPARM1(carriage_return), 1, outch); + tputs(TPARM1(cursor_normal), 1, outch); + restore_term(fileno(stdin)); + + exit(EXIT_FAILURE); + } + + /* Manage the hangup and termination signal by exiting with failure */ + /* and restoring the terminal and the cursor. */ + /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (got_sigterm || got_sighup) + { + fputs("Interrupted!\n", stderr); + tputs(TPARM1(carriage_return), 1, outch); + tputs(TPARM1(cursor_normal), 1, outch); + restore_term(fileno(stdin)); + + exit(EXIT_FAILURE); + } + /* If this alarm is triggered, then redisplay the window */ /* to remove the help message and disable this timer. */ /* """"""""""""""""""""""""""""""""""""""""""""""""""""" */ -- cgit v1.2.3