diff options
Diffstat (limited to '')
-rw-r--r-- | DEPENDENCIES | 16 | ||||
-rw-r--r-- | Makefile | 87 | ||||
-rw-r--r-- | src/reapd.c | 108 |
3 files changed, 211 insertions, 0 deletions
diff --git a/DEPENDENCIES b/DEPENDENCIES new file mode 100644 index 0000000..1b2a9af --- /dev/null +++ b/DEPENDENCIES @@ -0,0 +1,16 @@ +RUNTIME DEPENDENCIES: + + linux>=3.4 + libc + +BUILD DEPENDENCIES: + + libc + cc + make + +INSTALL DEPENDENCIES: + + make + coreutils + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cbe44c2 --- /dev/null +++ b/Makefile @@ -0,0 +1,87 @@ +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. This file is offered as-is, +# without any warranty. + + +# The package path prefix, if you want to install to another root, set DESTDIR to that root. +PREFIX ?= /usr +# The binary path excluding prefix. +BIN ?= /bin +# The resource path excluding prefix. +DATA ?= /share +# The binary path including prefix. +BINDIR ?= $(PREFIX)$(BIN) +# The resource path including prefix. +DATADIR ?= $(PREFIX)$(DATA) +# The license base path including prefix. +LICENSEDIR ?= $(DATADIR)/licenses + + +# The name of the package as it should be installed. +PKGNAME ?= orphan-reaper + +# The name of the command as it should be installed. +COMMAND ?= reapd + + + +# Build rules. + +.PHONY: all +all: bin/reapd + + +bin/reapd: src/reapd.c + mkdir -p bin + $(CC) -O3 -Wall -Wextra -pedantic $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) -o $@ $< + + +# Install rules. + +.PHONY: install +install: install-base + +.PHONY: install +install-all: install-base + +.PHONY: install-base +install-base: install-cmd install-copyright + + +.PHONY: install-cmd +install-cmd: bin/reapd + install -dm755 -- "$(DESTDIR)$(BINDIR)" + install -m755 $< -- "$(DESTDIR)$(BINDIR)/$(COMMAND)" + + +.PHONY: install-copyright +install-copyright: install-copying install-license + +.PHONY: install-copying +install-copying: + install -dm755 -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)" + install -m644 COPYING -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/COPYING" + +.PHONY: install-license +install-license: + install -dm755 -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)" + install -m644 LICENSE -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/LICENSE" + + + +# Uninstall rules. + +.PHONY: uninstall +uninstall: + -rm -- "$(DESTDIR)$(BINDIR)/$(COMMAND)" + -rm -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/COPYING" + -rm -- "$(DESTDIR)$(LICENSEDIR)/$(PKGNAME)/LICENSE" + + +# Clean rules. + +.PHONY: clean +clean: + -rm -rf obj bin + diff --git a/src/reapd.c b/src/reapd.c new file mode 100644 index 0000000..5ffecd5 --- /dev/null +++ b/src/reapd.c @@ -0,0 +1,108 @@ +/** + * 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 <errno.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"); +} + + +int main(int argc, char** argv) +{ + int i, j, r, 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]; + + 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; +} + |