}
}
-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);
}
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[])
if (nsjconf.mode == MODE_LISTEN_TCP) {
nsjailListenMode(&nsjconf);
} else {
- nsjailStandaloneMode(&nsjconf);
+ return nsjailStandaloneMode(&nsjconf);
}
return 0;
}
}
}
-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);
PLOG_D("Sent SIGKILL to PID: %d", pid);
}
}
+ return rv;
}
void subprocKillAll(struct nsjconf_t *nsjconf)
#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 */