/* See LICENSE file for copyright and license details. */ #include #include #include #include #include #include #include "arg.h" #ifdef TEST # define LIBEXECDIR "." # define REAPD "reapd.test" #else # ifndef REAPD # define REAPD "reapd" # endif #endif char *argv0; static void usage(void) { fprintf(stderr, "usage: %s [-f] command ...\n", argv0); exit(1); } int main(int argc, char *argv[]) { int fatal = 0; ARGBEGIN { case 'f': fatal = 1; break; default: usage(); } ARGEND; if (!argc) usage(); if (access(LIBEXECDIR"/"REAPD, X_OK) < 0) { fprintf(stderr, "%s: access %s: %s\n", argv0, LIBEXECDIR"/"REAPD, strerror(errno)); return 2; } if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) { fprintf(stderr, "%s: prctl PR_SET_CHILD_SUBREAPER: %s\n", argv0, strerror(errno)); if (fatal) return 2; goto exec; } switch (fork()) { case -1: fprintf(stderr, "%s: fork: %s\n", argv0, strerror(errno)); if (fatal) break; /* fall through */ case 0: (void) prctl(PR_SET_CHILD_SUBREAPER, 0); exec: execvp(*argv, argv); fprintf(stderr, "%s: execvp %s: %s\n", argv0, *argv, strerror(errno)); break; default: execl(LIBEXECDIR"/"REAPD, LIBEXECDIR"/"REAPD, NULL); fprintf(stderr, "%s: execl %s: %s\n", argv0, *argv, strerror(errno)); break; } return 2; }