80 lines
1.3 KiB
C
80 lines
1.3 KiB
C
/* See LICENSE file for copyright and license details. */
|
|
#include <sys/prctl.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#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;
|
|
}
|