From: MORITA Kazutaka <morita.kazut...@lab.ntt.co.jp>

To avoid infinite recursive call, this patch also sets SA_RESETHAND if
the handler should be called when program terminates.

Signed-off-by: MORITA Kazutaka <morita.kazut...@lab.ntt.co.jp>
---
 collie/collie.c     |   10 ++--------
 include/util.h      |    1 +
 lib/logger.c        |   10 ++--------
 lib/util.c          |   13 +++++++++++++
 sheep/trace/trace.c |    6 +-----
 5 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/collie/collie.c b/collie/collie.c
index bac595b..38d9e8e 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -333,16 +333,10 @@ int main(int argc, char **argv)
        const char *short_options;
        char *p;
        const struct sd_option *sd_opts;
-       struct sigaction sa_old;
-       struct sigaction sa_new;
 
-       init_commands(&commands);
-
-       sa_new.sa_handler = crash_handler;
-       sa_new.sa_flags = 0;
-       sigemptyset(&sa_new.sa_mask);
+       install_sighandler(SIGABRT, crash_handler, true);
 
-       sigaction(SIGABRT, &sa_new, &sa_old);
+       init_commands(&commands);
 
        if (argc < 3)
                usage(commands, 0);
diff --git a/include/util.h b/include/util.h
index d1b2e41..5f37dc7 100644
--- a/include/util.h
+++ b/include/util.h
@@ -85,6 +85,7 @@ ssize_t xpwrite(int fd, const void *buf, size_t count, off_t 
offset);
 void pstrcpy(char *buf, int buf_size, const char *str);
 int rmdir_r(char *dir_path);
 bool is_numeric(const char *p);
+int install_sighandler(int signum, void (*handler)(int), bool once);
 
 void trim_zero_sectors(void *buf, uint64_t *offset, uint32_t *len);
 void untrim_zero_sectors(void *buf, uint64_t offset, uint32_t len,
diff --git a/lib/logger.c b/lib/logger.c
index 7a570eb..ca9c391 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -466,8 +466,6 @@ static notrace void crash_handler(int signo)
 
 static notrace void logger(char *log_dir, char *outfile)
 {
-       struct sigaction sa_old;
-       struct sigaction sa_new;
        int fd;
 
        log_buff = xzalloc(la->end - la->start);
@@ -495,12 +493,8 @@ static notrace void logger(char *log_dir, char *outfile)
        }
 
        /* flush when either the logger or its parent dies */
-       sa_new.sa_handler = crash_handler;
-       sa_new.sa_flags = 0;
-       sigemptyset(&sa_new.sa_mask);
-
-       sigaction(SIGSEGV, &sa_new, &sa_old);
-       sigaction(SIGHUP, &sa_new, &sa_old);
+       install_sighandler(SIGSEGV, crash_handler, true);
+       install_sighandler(SIGHUP, crash_handler, false);
 
        prctl(PR_SET_PDEATHSIG, SIGHUP);
 
diff --git a/lib/util.c b/lib/util.c
index 56ed0de..0999f0e 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <assert.h>
 #include <ctype.h>
+#include <signal.h>
 
 #include "util.h"
 #include "logger.h"
@@ -353,3 +354,15 @@ bool is_numeric(const char *s)
        }
        return false;
 }
+
+int install_sighandler(int signum, void (*handler)(int), bool once)
+{
+       struct sigaction sa = {};
+
+       sa.sa_handler = handler;
+       if (once)
+               sa.sa_flags = SA_RESETHAND;
+       sigemptyset(&sa.sa_mask);
+
+       return sigaction(signum, &sa, NULL);
+}
diff --git a/sheep/trace/trace.c b/sheep/trace/trace.c
index adaf4e6..75f7ff1 100644
--- a/sheep/trace/trace.c
+++ b/sheep/trace/trace.c
@@ -307,12 +307,8 @@ notrace int trace_disable(void)
 
 int trace_init_signal(void)
 {
-       struct sigaction act;
-
-       memset(&act, 0, sizeof(act));
-       act.sa_handler = suspend;
        /* trace uses this signal to suspend the worker threads */
-       if (sigaction(SIGUSR2, &act, NULL) < 0) {
+       if (install_sighandler(SIGUSR2, suspend, false) < 0) {
                sd_dprintf("%m\n");
                return -1;
        }
-- 
1.7.9.5

-- 
sheepdog mailing list
sheepdog@lists.wpkg.org
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to