diff options
author | pgen <p.gen.progs@gmail.com> | 2019-03-27 23:13:57 +0100 |
---|---|---|
committer | pgen <p.gen.progs@gmail.com> | 2019-03-30 11:39:02 +0100 |
commit | 80a48ad3ca40991bb67d9e3029417398157a1435 (patch) | |
tree | 4bf282e098f55432834c3018ed2a0671dd5483f9 | |
parent | 410b1aa7250168942019385db95088fca1aba46b (diff) |
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
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | smenu.c | 48 |
2 files changed, 36 insertions, 15 deletions
@@ -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. @@ -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. */ /* """"""""""""""""""""""""""""""""""""""""""""""""""""" */ |