Signed-off-by: Andrew Gregory <[email protected]>
---
 src/pacman/pacman.c     |  1 +
 src/pacman/sighandler.c | 44 +++++++++++++++++++++++++++-----------------
 src/pacman/sighandler.h |  1 +
 3 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index e1f9039..6a0eb97 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -1091,6 +1091,7 @@ int main(int argc, char *argv[])
        size_t i;
        uid_t myuid = getuid();
 
+       install_segv_handler();
        install_signal_handlers();
 
        /* i18n init */
diff --git a/src/pacman/sighandler.c b/src/pacman/sighandler.c
index 76f7e9d..36f87d7 100644
--- a/src/pacman/sighandler.c
+++ b/src/pacman/sighandler.c
@@ -44,23 +44,16 @@ static ssize_t xwrite(int fd, const void *buf, size_t count)
  */
 static void handler(int signum)
 {
-       if(signum == SIGSEGV) {
-               const char msg[] = "\nerror: segmentation fault\n"
-                       "Please submit a full bug report with --debug if 
appropriate.\n";
+       if(signum == SIGINT) {
+               const char msg[] = "\nInterrupt signal received\n";
                xwrite(STDERR_FILENO, msg, ARRAYSIZE(msg) - 1);
-               exit(signum);
-       } else if(signum == SIGINT || signum == SIGHUP) {
-               if(signum == SIGINT) {
-                       const char msg[] = "\nInterrupt signal received\n";
-                       xwrite(STDERR_FILENO, msg, ARRAYSIZE(msg) - 1);
-               } else {
-                       const char msg[] = "\nHangup signal received\n";
-                       xwrite(STDERR_FILENO, msg, ARRAYSIZE(msg) - 1);
-               }
-               if(alpm_trans_interrupt(config->handle) == 0) {
-                       /* a transaction is being interrupted, don't exit 
pacman yet. */
-                       return;
-               }
+       } else {
+               const char msg[] = "\nHangup signal received\n";
+               xwrite(STDERR_FILENO, msg, ARRAYSIZE(msg) - 1);
+       }
+       if(alpm_trans_interrupt(config->handle) == 0) {
+               /* a transaction is being interrupted, don't exit pacman yet. */
+               return;
        }
        /* SIGINT/SIGHUP: no committing transaction, release it now and then 
exit pacman */
        alpm_unlock(config->handle);
@@ -69,6 +62,23 @@ static void handler(int signum)
        _Exit(128 + signum);
 }
 
+static void segv_handler(int signum)
+{
+       const char msg[] = "\nerror: segmentation fault\n"
+               "Please submit a full bug report with --debug if 
appropriate.\n";
+       xwrite(STDERR_FILENO, msg, sizeof(msg) - 1);
+       _Exit(signum);
+}
+
+void install_segv_handler(void)
+{
+       struct sigaction new_action;
+       new_action.sa_handler = segv_handler;
+       sigemptyset(&new_action.sa_mask);
+       new_action.sa_flags = SA_RESTART;
+       sigaction(SIGSEGV, &new_action, NULL);
+}
+
 static void winch_handler(int signum)
 {
        (void)signum; /* suppress unused variable warnings */
@@ -87,7 +97,7 @@ void install_winch_handler(void)
 void install_signal_handlers(void)
 {
        struct sigaction new_action;
-       const int signals[] = { SIGHUP, SIGINT, SIGSEGV };
+       const int signals[] = { SIGHUP, SIGINT };
        size_t i;
 
        /* Set signal handlers */
diff --git a/src/pacman/sighandler.h b/src/pacman/sighandler.h
index bcf7d88..037d54f 100644
--- a/src/pacman/sighandler.h
+++ b/src/pacman/sighandler.h
@@ -20,6 +20,7 @@
 #ifndef _PM_SIGHANDLER_H
 #define _PM_SIGHANDLER_H
 
+void install_segv_handler(void);
 void install_winch_handler(void);
 void install_signal_handlers(void);
 
-- 
2.6.3

Reply via email to