Return child exit status in standalone mode
authorJT Olds <hello@jtolds.com>
Tue, 7 Jul 2015 16:33:10 +0000 (10:33 -0600)
committerJT Olds <hello@jtolds.com>
Tue, 7 Jul 2015 16:33:47 +0000 (10:33 -0600)
nsjail.c
subproc.c
subproc.h

index 42fb6ce82404e3fcb205f8ca22858d83e00319f1..b36c2a1ba6efb14618c08c16a7efe6319d4bc78c 100644 (file)
--- a/nsjail.c
+++ b/nsjail.c
@@ -130,13 +130,14 @@ static void nsjailListenMode(struct nsjconf_t *nsjconf)
        }
 }
 
-static void nsjailStandaloneMode(struct nsjconf_t *nsjconf)
+static int nsjailStandaloneMode(struct nsjconf_t *nsjconf)
 {
+       int child_status = 0;
        subprocRunChild(nsjconf, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
        for (;;) {
                if (subprocCount(nsjconf) == 0) {
                        if (nsjconf->mode == MODE_STANDALONE_ONCE) {
-                               return;
+                               return child_status;
                        }
                        subprocRunChild(nsjconf, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
                }
@@ -147,11 +148,13 @@ static void nsjailStandaloneMode(struct nsjconf_t *nsjconf)
                if (nsjailSigFatal > 0) {
                        subprocKillAll(nsjconf);
                        logStop(nsjailSigFatal);
-                       return;
+                       return -1;
                }
                pause();
-               subprocReap(nsjconf);
+               child_status = subprocReap(nsjconf);
        }
+       // not reached
+       return child_status;
 }
 
 int main(int argc, char *argv[])
@@ -177,7 +180,7 @@ int main(int argc, char *argv[])
        if (nsjconf.mode == MODE_LISTEN_TCP) {
                nsjailListenMode(&nsjconf);
        } else {
-               nsjailStandaloneMode(&nsjconf);
+               return nsjailStandaloneMode(&nsjconf);
        }
        return 0;
 }
index 4af216a6418edf9d14121ca9ad9066170b2b3904..ca5d1868b3590eaf521c9d7bbf77816eab88104a 100644 (file)
--- a/subproc.c
+++ b/subproc.c
@@ -144,15 +144,19 @@ void subprocDisplay(struct nsjconf_t *nsjconf)
        }
 }
 
-void subprocReap(struct nsjconf_t *nsjconf)
+int subprocReap(struct nsjconf_t *nsjconf)
 {
        int status;
+       int rv = 0;
        pid_t pid;
        while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
                if (WIFEXITED(status)) {
                        subprocRemove(nsjconf, pid);
                        LOG_I("PID: %d exited with status: %d, (PIDs left: %d)", pid,
                              WEXITSTATUS(status), subprocCount(nsjconf));
+                       if (rv == 0) {
+                               rv = WEXITSTATUS(status);
+                       }
                }
                if (WIFSIGNALED(status)) {
                        subprocRemove(nsjconf, pid);
@@ -180,6 +184,7 @@ void subprocReap(struct nsjconf_t *nsjconf)
                        PLOG_D("Sent SIGKILL to PID: %d", pid);
                }
        }
+       return rv;
 }
 
 void subprocKillAll(struct nsjconf_t *nsjconf)
index b189e8490b2866001a8ea2e1f907ec123aca2036..fb1301c61f86e02ab3808a03e7fe7308d83cc529 100644 (file)
--- a/subproc.h
+++ b/subproc.h
 #include "common.h"
 
 void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err);
-void subprocReap(struct nsjconf_t *nsjconf);
 int subprocCount(struct nsjconf_t *nsjconf);
 void subprocDisplay(struct nsjconf_t *nsjconf);
 void subprocKillAll(struct nsjconf_t *nsjconf);
 
+/* Returns the exit code of the first failing subprocess, or 0 if none fail */
+int subprocReap(struct nsjconf_t *nsjconf);
+
 #endif                         /* _PROC_H */