summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpgen <p.gen.progs@gmail.com>2019-03-27 23:13:57 +0100
committerpgen <p.gen.progs@gmail.com>2019-03-30 11:39:02 +0100
commit80a48ad3ca40991bb67d9e3029417398157a1435 (patch)
tree4bf282e098f55432834c3018ed2a0671dd5483f9
parent410b1aa7250168942019385db95088fca1aba46b (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--TODO3
-rw-r--r--smenu.c48
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. */
/* """"""""""""""""""""""""""""""""""""""""""""""""""""" */