logwrap: wait for child process when receiving SIGINT or SIGQUIT

- Wait for the child to exit before propagating SIGINT and SIGQUIT
to the parent
- Add ignore_int_quit argument to logwrap() that gives the caller the
option to ignore SIGINT and SIGQUIT while logwrap is running

Change-Id: If5c96cf23094917211310f00aa6aed515f110f5b
diff --git a/logwrapper/include/logwrap/logwrap.h b/logwrapper/include/logwrap/logwrap.h
index 722dda2..6593f3c 100644
--- a/logwrapper/include/logwrap/logwrap.h
+++ b/logwrapper/include/logwrap/logwrap.h
@@ -18,6 +18,8 @@
 #ifndef __LIBS_LOGWRAP_H
 #define __LIBS_LOGWRAP_H
 
+#include <stdbool.h>
+
 __BEGIN_DECLS
 
 /*
@@ -36,13 +38,17 @@
  *           NULL-terminated
  *   status: the equivalent child status as populated by wait(status). This
  *           value is only valid when logwrap successfully completes
+ *   ignore_int_quit: set to true if you want to completely ignore SIGINT and
+ *           SIGQUIT while logwrap is running. This may force the end-user to
+ *           send a signal twice to signal the caller (once for the child, and
+ *           once for the caller)
  *
  * Return value:
  *   0 when logwrap successfully run the child process and captured its status
  *   -1 when an internal error occurred
  *
  */
-int logwrap(int argc, char* argv[], int *status);
+int logwrap(int argc, char* argv[], int *status, bool ignore_int_quit);
 
 __END_DECLS
 
diff --git a/logwrapper/logwrap.c b/logwrapper/logwrap.c
index ef457de..99a462f 100644
--- a/logwrapper/logwrap.c
+++ b/logwrapper/logwrap.c
@@ -176,13 +176,15 @@
     write(signal_fd_write, &sig, 1);
 }
 
-int logwrap(int argc, char* argv[], int *status) {
+int logwrap(int argc, char* argv[], int *status, bool ignore_int_quit) {
     pid_t pid;
     int parent_ptty;
     int child_ptty;
     char *child_devname = NULL;
     struct sigaction chldact;
     struct sigaction oldchldact;
+    struct sigaction intact;
+    struct sigaction quitact;
     sigset_t blockset;
     sigset_t oldset;
     int sockets[2];
@@ -204,6 +206,8 @@
     }
 
     sigemptyset(&blockset);
+    sigaddset(&blockset, SIGINT);
+    sigaddset(&blockset, SIGQUIT);
     sigaddset(&blockset, SIGCHLD);
     sigprocmask(SIG_BLOCK, &blockset, &oldset);
 
@@ -231,6 +235,8 @@
         fatal("This should never happen\n");
         return -1;
     } else {
+        struct sigaction ignact;
+
         memset(&chldact, 0, sizeof(chldact));
         chldact.sa_handler = sigchld_handler;
         chldact.sa_flags = SA_NOCLDSTOP;
@@ -245,6 +251,13 @@
                     "handler and might cause interaction issues");
         }
 
+        if (ignore_int_quit) {
+            memset(&ignact, 0, sizeof(ignact));
+            ignact.sa_handler = SIG_IGN;
+            sigaction(SIGINT, &ignact, &intact);
+            sigaction(SIGQUIT, &ignact, &quitact);
+        }
+
         rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
         if (rc == -1) {
             char msg[40];
@@ -268,6 +281,10 @@
     close(sockets[0]);
     close(sockets[1]);
 err_socketpair:
+    if (ignore_int_quit) {
+        sigaction(SIGINT, &intact, NULL);
+        sigaction(SIGQUIT, &quitact, NULL);
+    }
     sigaction(SIGCHLD, &oldchldact, NULL);
 err_fork:
     sigprocmask(SIG_SETMASK, &oldset, NULL);
diff --git a/logwrapper/logwrapper.c b/logwrapper/logwrapper.c
index e647b4d..563fcee 100644
--- a/logwrapper/logwrapper.c
+++ b/logwrapper/logwrapper.c
@@ -59,7 +59,7 @@
         usage();
     }
 
-    rc = logwrap(argc - 1, &argv[1], &status);
+    rc = logwrap(argc - 1, &argv[1], &status, true);
     if (!rc) {
         if (WIFEXITED(status))
             rc = WEXITSTATUS(status);