return -errno;
r = safe_fork_full("(sd-homework)",
- NULL,
- (int[]) { stdin_fd, stdout_fd }, 2,
- FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &pid);
+ (int[]) { stdin_fd, stdout_fd, STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
if (r < 0)
log_warning_errno(r, "Failed to update $SYSTEMD_EXEC_PID, ignoring: %m");
- r = rearrange_stdio(TAKE_FD(stdin_fd), TAKE_FD(stdout_fd), STDERR_FILENO); /* fds are invalidated by rearrange_stdio() even on failure */
- if (r < 0) {
- log_error_errno(r, "Failed to rearrange stdin/stdout/stderr: %m");
- _exit(EXIT_FAILURE);
- }
-
-
/* Allow overriding the homework path via an environment variable, to make debugging
* easier. */
homework = getenv("SYSTEMD_HOMEWORK_PATH") ?: SYSTEMD_HOMEWORK_PATH;
use_selinux = mac_selinux_use();
- r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ r = safe_fork_full("(tar)",
+ (int[]) { pipefd[0], -EBADF, STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
/* Child */
- pipefd[1] = safe_close(pipefd[1]);
-
- r = rearrange_stdio(TAKE_FD(pipefd[0]), -EBADF, STDERR_FILENO);
- if (r < 0) {
- log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
- _exit(EXIT_FAILURE);
- }
-
if (unshare(CLONE_NEWNET) < 0)
log_warning_errno(errno, "Failed to lock tar into network namespace, ignoring: %m");
use_selinux = mac_selinux_use();
- r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ r = safe_fork_full("(tar)",
+ (int[]) { -EBADF, pipefd[1], STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
/* Child */
- pipefd[0] = safe_close(pipefd[0]);
-
- r = rearrange_stdio(-EBADF, TAKE_FD(pipefd[1]), STDERR_FILENO);
- if (r < 0) {
- log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
- _exit(EXIT_FAILURE);
- }
-
if (unshare(CLONE_NEWNET) < 0)
log_error_errno(errno, "Failed to lock tar into network namespace, ignoring: %m");
if (pipe2(pipefd, O_CLOEXEC) < 0)
return -errno;
- r = safe_fork("(sd-transfer)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &t->pid);
+ r = safe_fork_full("(sd-transfer)",
+ (int[]) { t->stdin_fd, t->stdout_fd < 0 ? pipefd[1] : t->stdout_fd, pipefd[1] },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO, &t->pid);
if (r < 0)
return r;
if (r == 0) {
/* Child */
- pipefd[0] = safe_close(pipefd[0]);
-
- r = rearrange_stdio(TAKE_FD(t->stdin_fd),
- t->stdout_fd < 0 ? pipefd[1] : TAKE_FD(t->stdout_fd),
- pipefd[1]);
- TAKE_FD(pipefd[1]);
- if (r < 0) {
- log_error_errno(r, "Failed to set stdin/stdout/stderr: %m");
- _exit(EXIT_FAILURE);
- }
-
if (setenv("SYSTEMD_LOG_TARGET", "console-prefixed", 1) < 0 ||
setenv("NOTIFY_SOCKET", "/run/systemd/import/notify", 1) < 0) {
log_error_errno(errno, "setenv() failed: %m");
gpg_home_created = true;
- r = safe_fork("(gpg)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
+ r = safe_fork_full("(gpg)",
+ (int[]) { gpg_pipe[0], -EBADF, STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+ &pid);
if (r < 0)
return r;
if (r == 0) {
/* Child */
- gpg_pipe[1] = safe_close(gpg_pipe[1]);
-
- r = rearrange_stdio(TAKE_FD(gpg_pipe[0]), -EBADF, STDERR_FILENO);
- if (r < 0) {
- log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
- _exit(EXIT_FAILURE);
- }
-
cmd[k++] = strjoina("--homedir=", gpg_home);
/* We add the user keyring only to the command line arguments, if it's around since gpg fails
if (pipe(fd) < 0)
return log_error_errno(errno, "Failed to create pager pipe: %m");
- r = safe_fork("(remote)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &child_pid);
+ r = safe_fork_full("(remote)",
+ (int[]) {STDIN_FILENO, fd[1], STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &child_pid);
if (r < 0) {
safe_close_pair(fd);
return r;
/* In the child */
if (r == 0) {
- fd[0] = safe_close(fd[0]);
-
- r = rearrange_stdio(STDIN_FILENO, TAKE_FD(fd[1]), STDERR_FILENO);
- if (r < 0) {
- log_error_errno(r, "Failed to dup pipe to stdout: %m");
- _exit(EXIT_FAILURE);
- }
-
execvp(child, argv);
log_error_errno(errno, "Failed to exec child %s: %m", child);
_exit(EXIT_FAILURE);
return -errno;
r = safe_fork_full("(sd-busexec)",
- NULL,
- s+1, 1,
- FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid);
+ (int[]) { s[1], s[1], STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid);
if (r < 0) {
safe_close_pair(s);
return r;
if (r == 0) {
/* Child */
- r = rearrange_stdio(s[1], s[1], STDERR_FILENO);
- TAKE_FD(s[1]);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
if (b->exec_argv)
execvp(b->exec_path, b->exec_argv);
else
if (pipe2(pipe_fds, O_CLOEXEC) < 0)
return log_error_errno(errno, "Failed to allocate pipe: %m");
- r = safe_fork("(getent)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
+ r = safe_fork_full("(getent)",
+ (int[]) { -EBADF, pipe_fds[1], -EBADF }, NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+ &pid);
if (r < 0) {
safe_close_pair(pipe_fds);
return r;
}
if (r == 0) {
- char *empty_env = NULL;
-
- pipe_fds[0] = safe_close(pipe_fds[0]);
-
- if (rearrange_stdio(-EBADF, TAKE_FD(pipe_fds[1]), -EBADF) < 0)
- _exit(EXIT_FAILURE);
-
- (void) close_all_fds(NULL, 0);
-
- execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env);
- execle("/bin/getent", "getent", database, key, NULL, &empty_env);
+ execle("/usr/bin/getent", "getent", database, key, NULL, &(char*[1]){});
+ execle("/bin/getent", "getent", database, key, NULL, &(char*[1]){});
_exit(EXIT_FAILURE);
}
}
r = safe_fork_full("(test-resolved-stream-tls-openssl)",
- NULL,
- (int[]) { fd_server, fd_tls }, 2,
- FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &openssl_pid);
+ (int[]) { fd_tls, fd_tls, STDOUT_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG,
+ &openssl_pid);
assert_se(r >= 0);
if (r == 0) {
/* Child */
- assert_se(dup2(fd_tls, STDIN_FILENO) >= 0);
- assert_se(dup2(fd_tls, STDOUT_FILENO) >= 0);
- close(TAKE_FD(fd_server));
- close(TAKE_FD(fd_tls));
-
execlp("openssl", "openssl", "s_server", "-accept", bind_str,
"-key", key_path, "-cert", cert_path,
"-quiet", "-naccept", "1", NULL);
log_info("%s Acquiring manifest file %s%s", special_glyph(SPECIAL_GLYPH_DOWNLOAD),
suffixed_url, special_glyph(SPECIAL_GLYPH_ELLIPSIS));
- r = safe_fork("(sd-pull)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ r = safe_fork_full("(sd-pull)",
+ (int[]) { -EBADF, pfd[1], STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG,
+ &pid);
if (r < 0)
return r;
if (r == 0) {
NULL
};
- pfd[0] = safe_close(pfd[0]);
-
- r = rearrange_stdio(-EBADF, pfd[1], STDERR_FILENO);
- if (r < 0) {
- log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
- _exit(EXIT_FAILURE);
- }
-
(void) unsetenv("NOTIFY_SOCKET");
execv(pull_binary_path(), (char *const*) cmdline);
log_error_errno(errno, "Failed to execute %s tool: %m", pull_binary_path());
assert_se(pipe2(outpipe, O_NONBLOCK|O_CLOEXEC) == 0);
assert_se(pipe2(errpipe, O_NONBLOCK|O_CLOEXEC) == 0);
- r = safe_fork("(spawn-ldd)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ r = safe_fork_full("(spawn-ldd)",
+ (int[]) { -EBADF, outpipe[1], errpipe[1] },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
assert_se(r >= 0);
if (r == 0) {
- if (rearrange_stdio(-EBADF, TAKE_FD(outpipe[1]), TAKE_FD(errpipe[1])) < 0)
- _exit(EXIT_FAILURE);
-
- (void) close_all_fds(NULL, 0);
-
execlp("ldd", "ldd", exec, NULL);
_exit(EXIT_FAILURE);
}
log_device_debug(event->dev, "Starting '%s'", cmd);
- r = safe_fork("(spawn)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
+ r = safe_fork_full("(spawn)",
+ (int[]) { -EBADF, outpipe[WRITE_END], errpipe[WRITE_END] },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+ &pid);
if (r < 0)
return log_device_error_errno(event->dev, r,
"Failed to fork() to execute command '%s': %m", cmd);
if (r == 0) {
- if (rearrange_stdio(-EBADF, TAKE_FD(outpipe[WRITE_END]), TAKE_FD(errpipe[WRITE_END])) < 0)
- _exit(EXIT_FAILURE);
-
- (void) close_all_fds(NULL, 0);
-
DEVICE_TRACE_POINT(spawn_exec, event->dev, cmd);
-
execve(argv[0], argv, envp);
_exit(EXIT_FAILURE);
}