diff options
Diffstat (limited to '')
-rw-r--r-- | Makefile | 27 | ||||
-rw-r--r-- | src/orphan-reaper.c | 102 | ||||
-rw-r--r-- | src/reapd.c | 89 |
3 files changed, 133 insertions, 85 deletions
@@ -8,10 +8,14 @@ PREFIX ?= /usr # The binary path excluding prefix. BIN ?= /bin +# The library binary path excluding prefix. +LIBEXEC ?= /libexec # The resource path excluding prefix. DATA ?= /share # The binary path including prefix. BINDIR ?= $(PREFIX)$(BIN) +# The library binary path including prefix. +LIBEXECDIR ?= $(PREFIX)$(LIBEXEC) # The resource path including prefix. DATADIR ?= $(PREFIX)$(DATA) # The license base path including prefix. @@ -22,19 +26,27 @@ LICENSEDIR ?= $(DATADIR)/licenses PKGNAME ?= orphan-reaper # The name of the command as it should be installed. -COMMAND ?= reapd +COMMAND ?= orphan-reaper + + +# Flags to compile with. +USER_FLAGS = $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) +WARN = -Wall -Wextra -pedantic +OPTIMISE = -O3 +DEFS = -D'LIBEXECDIR="$(LIBEXECDIR)"' +C_FLAGS = $(OPTIMISE) $(WARN) $(DEFS) $(USER_FLAGS) # Build rules. .PHONY: all -all: bin/reapd +all: bin/orphan-reaper bin/reapd -bin/reapd: src/reapd.c +bin/%: src/%.c mkdir -p bin - $(CC) -O3 -Wall -Wextra -pedantic $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) -o $@ $< + $(CC) $(C_FLAGS) -o $@ $< # Install rules. @@ -50,9 +62,11 @@ install-base: install-cmd install-copyright .PHONY: install-cmd -install-cmd: bin/reapd +install-cmd: bin/orphan-reaper bin/reapd install -dm755 -- "$(DESTDIR)$(BINDIR)" - install -m755 $< -- "$(DESTDIR)$(BINDIR)/$(COMMAND)" + install -dm755 -- "$(DESTDIR)$(LIBEXECDIR)" + install -m755 bin/orphan-reaper -- "$(DESTDIR)$(BINDIR)/$(COMMAND)" + install -m755 bin/reapd -- "$(DESTDIR)$(LIBEXECDIR)/reapd" .PHONY: install-copyright @@ -75,6 +89,7 @@ install-license: .PHONY: uninstall uninstall: -rm -- "$(DESTDIR)$(BINDIR)/$(COMMAND)" + -rm -- "$(DESTDIR)$(LIBEXECDIR)/reapd" -rm -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/COPYING" -rm -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/LICENSE" diff --git a/src/orphan-reaper.c b/src/orphan-reaper.c new file mode 100644 index 0000000..7115583 --- /dev/null +++ b/src/orphan-reaper.c @@ -0,0 +1,102 @@ +/** + * orphan-reaper — Place subreapers in your process tree to keep it structured + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/prctl.h> + + + +static void usage(void) +{ + printf("USAGE: orphan-reaper [--fatal] [--] <command...>\n"); + printf("\n"); + printf("Unless `--fatal` is used, the program will run <command>\n"); + printf("even if the process cound not be marked as a child subreaper.\n"); + printf("\n"); +} + + +int main(int argc, char** argv) +{ + int i, j, fatal = 0; + char** exec_argv; + pid_t pid; + + if ((argc < 2) || !strcmp(argv[1], "--help")) + return usage(), argc < 2 ? 1 : 0; + + for (i = 1; i < argc; i++) + if (!strcmp(argv[i], "--fatal")) + fatal = 1; + else if (!strcmp(argv[i], "--")) + { + i++; + break; + } + else if (strstr(argv[i], "-") == argv[i]) + return usage(), 1; + else + break; + + if (i == argc) + return usage(), 1; + + exec_argv = malloc((argc - i + 1) * sizeof(char*)); + if (exec_argv == NULL) + return perror(*argv), 2; + exec_argv[argc - i] = NULL; + for (j = 0; i < argc; j++, i++) + exec_argv[j] = argv[i]; + + if (access(LIBEXECDIR "/reapd", X_OK) < 0) + goto pfail; + + if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) + goto error; + + pid = fork(); + if (pid == -1) + goto error; + else if (pid == 0) + goto exec; + else + { + exec_argv[0] = LIBEXECDIR "/reapd"; + exec_argv[1] = NULL; + execvp(*exec_argv, exec_argv); + goto pfail; + } + + exec: + (void) prctl(PR_SET_CHILD_SUBREAPER, 0); + execvp(*exec_argv, exec_argv); + pfail: + perror(*argv); + fail: + free(exec_argv); + return 2; + + error: + perror(*argv); + if (fatal) + goto fail; + goto exec; +} + diff --git a/src/reapd.c b/src/reapd.c index 5ffecd5..be74690 100644 --- a/src/reapd.c +++ b/src/reapd.c @@ -15,94 +15,25 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> +#include <stddef.h> #include <sys/types.h> #include <sys/wait.h> -#include <sys/prctl.h> - - - -static void usage(void) -{ - printf("USAGE: reapd [--fatal] [--] <command...>\n"); - printf("\n"); - printf("Unless `--fatal` is used, the program will run <command>\n"); - printf("even if the process cound not be marked as a child subreaper.\n"); - printf("\n"); -} +#include <errno.h> +#include <stdio.h> int main(int argc, char** argv) { - int i, j, r, fatal = 0; - char** exec_argv; pid_t pid; + (void) argc; - if ((argc < 2) || !strcmp(argv[1], "--help")) - return usage(), argc < 2 ? 1 : 0; - - for (i = 1; i < argc; i++) - if (!strcmp(argv[i], "--fatal")) - fatal = 1; - else if (!strcmp(argv[i], "--")) + for (;;) + if (pid = wait(NULL), pid == -1) { - i++; - break; + if (errno == ECHILD) + return 0; + else if (errno != EINTR) + return perror(*argv), 2; } - else if (strstr(argv[i], "-") == argv[i]) - return usage(), 1; - else - break; - - if (i == argc) - return usage(), 1; - - exec_argv = malloc((argc - i + 1) * sizeof(char*)); - if (exec_argv == NULL) - return perror(*argv), 2; - exec_argv[argc - i] = NULL; - for (j = 0; i < argc; j++, i++) - exec_argv[j] = argv[i]; - - r = prctl(PR_SET_CHILD_SUBREAPER, 1); - if (r < 0) - goto error; - - pid = fork(); - if (pid == -1) - goto error; - - if (pid == 0) - goto exec; - else - { - free(exec_argv); - for (;;) - if (pid = wait(NULL), pid == -1) - { - if (errno == ECHILD) - return 0; - else if (errno != EINTR) - return perror(*argv), 2; - } - } - - exec: - (void) prctl(PR_SET_CHILD_SUBREAPER, 0); - execvp(*exec_argv, exec_argv); - perror(*argv); - fail: - free(exec_argv); - return 2; - - error: - perror(*argv); - if (fatal) - goto fail; - goto exec; } |