Let's a simple helper that knows how to deal with PID == 1.
return b != 0;
}
+int make_reaper_process(bool b) {
+
+ if (getpid_cached() == 1) {
+
+ if (!b)
+ return -EINVAL;
+
+ return 0;
+ }
+
+ /* Some prctl()s insist that all 5 arguments are specified, others do not. Let's always specify all,
+ * to avoid any ambiguities */
+ if (prctl(PR_SET_CHILD_SUBREAPER, (unsigned long) b, 0UL, 0UL, 0UL) < 0)
+ return -errno;
+
+ return 0;
+}
+
static const char *const sigchld_code_table[] = {
[CLD_EXITED] = "exited",
[CLD_KILLED] = "killed",
int get_process_threads(pid_t pid);
int is_reaper_process(void);
+int make_reaper_process(bool b);
}
}
- if (arg_runtime_scope == RUNTIME_SCOPE_USER)
- /* Become reaper of our children */
- if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0)
- log_warning_errno(errno, "Failed to make us a subreaper, ignoring: %m");
+ r = make_reaper_process(true);
+ if (r < 0)
+ log_warning_errno(r, "Failed to make us a subreaper, ignoring: %m");
/* Bump up RLIMIT_NOFILE for systemd itself */
(void) bump_rlimit_nofile(saved_rlimit_nofile);
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, SIGRTMIN+18, -1) >= 0);
- if (prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) < 0) {
- r = log_error_errno(errno, "Failed to become subreaper: %m");
+ r = make_reaper_process(true);
+ if (r < 0) {
+ log_error_errno(r, "Failed to become subreaper: %m");
goto finish;
}
if (r == 0) {
/* child */
- assert(prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) >= 0);
+ assert(make_reaper_process(true) >= 0);
fd = open("/dev/null", O_RDONLY|O_CLOEXEC);
assert_se(fd >= 0);
/* child */
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);
- assert_se(prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) >= 0);
+ assert_se(make_reaper_process(true) >= 0);
assert_se(mkdtemp_malloc(NULL, &tt) >= 0);
assert_se(kk = path_join(tt, "somefile"));
assert_se(r >= 0);
if (r == 0) {
/* child */
- assert_se(prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) >= 0);
+ assert_se(make_reaper_process(true) >= 0);
assert_se(is_reaper_process() > 0);
_exit(EXIT_SUCCESS);