diff --git a/src/nnn.c b/src/nnn.c index 85042015..9fdb103d 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -372,14 +372,8 @@ static regex_t archive_re; #endif /* Retain old signal handlers */ -#ifdef __linux__ -static sighandler_t oldsighup; /* old value of hangup signal */ -static sighandler_t oldsigtstp; /* old value of SIGTSTP */ -#else -/* note: no sig_t on Solaris-derivs */ -static void (*oldsighup)(int); -static void (*oldsigtstp)(int); -#endif +static struct sigaction oldsighup; +static struct sigaction oldsigtstp; /* For use in functions which are isolated and don't return the buffer */ static char g_buf[CMD_LEN_MAX] __attribute__ ((aligned)); @@ -704,6 +698,13 @@ static void sigint_handler(int UNUSED(sig)) g_states |= STATE_INTERRUPTED; } +static void clean_exit_sighandler(int UNUSED(sig)) +{ + exitcurses(); + /* This triggers cleanup() thanks to atexit() */ + exit(EXIT_SUCCESS); +} + static char *xitoa(uint val) { static char ascbuf[32] = {0}; @@ -1579,11 +1580,12 @@ static pid_t xfork(uchar flag) { int status; pid_t p = fork(); + struct sigaction dfl_act = {.sa_handler = SIG_DFL}; if (p > 0) { /* the parent ignores the interrupt, quit and hangup signals */ - oldsighup = signal(SIGHUP, SIG_IGN); - oldsigtstp = signal(SIGTSTP, SIG_DFL); + sigaction(SIGHUP, &(struct sigaction){.sa_handler = SIG_IGN}, &oldsighup); + sigaction(SIGTSTP, &dfl_act, &oldsigtstp); } else if (p == 0) { /* We create a grandchild to detach */ if (flag & F_NOWAIT) { @@ -1592,10 +1594,10 @@ static pid_t xfork(uchar flag) if (p > 0) _exit(EXIT_SUCCESS); else if (p == 0) { - signal(SIGHUP, SIG_DFL); - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGTSTP, SIG_DFL); + sigaction(SIGHUP, &dfl_act, NULL); + sigaction(SIGINT, &dfl_act, NULL); + sigaction(SIGQUIT, &dfl_act, NULL); + sigaction(SIGTSTP, &dfl_act, NULL); setsid(); return p; @@ -1606,10 +1608,10 @@ static pid_t xfork(uchar flag) } /* so they can be used to stop the child */ - signal(SIGHUP, SIG_DFL); - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGTSTP, SIG_DFL); + sigaction(SIGHUP, &dfl_act, NULL); + sigaction(SIGINT, &dfl_act, NULL); + sigaction(SIGQUIT, &dfl_act, NULL); + sigaction(SIGTSTP, &dfl_act, NULL); } /* This is the parent waiting for the child to create grandchild*/ @@ -1637,8 +1639,8 @@ static int join(pid_t p, uchar flag) } /* restore parent's signal handling */ - signal(SIGHUP, oldsighup); - signal(SIGTSTP, oldsigtstp); + sigaction(SIGHUP, &oldsighup, NULL); + sigaction(SIGTSTP, &oldsigtstp, NULL); return status; } @@ -7196,7 +7198,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - signal(SIGPIPE, SIG_IGN); + sigaction(SIGPIPE, &(struct sigaction){.sa_handler = SIG_IGN}, NULL); } #endif @@ -7232,7 +7234,20 @@ int main(int argc, char *argv[]) xerror(); return EXIT_FAILURE; } - signal(SIGQUIT, SIG_IGN); + + act.sa_handler = clean_exit_sighandler; + + if (sigaction(SIGTERM, &act, NULL) < 0 || sigaction(SIGHUP, &act, NULL) < 0) { + xerror(); + return EXIT_FAILURE; + } + + act.sa_handler = SIG_IGN; + + if (sigaction(SIGQUIT, &act, NULL) < 0) { + xerror(); + return EXIT_FAILURE; + } #ifndef NOLOCALE /* Set locale */