mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 17:51:22 +03:00
fd-util: add new helper move_fd() and make use of it
We are using the same pattern at various places: call dup2() on an fd, and close the old fd, usually in combination with some O_CLOEXEC fiddling. Let's add a little helper for this, and port a few obvious cases over.
This commit is contained in:
parent
05d69e0294
commit
046a82c1b2
@ -377,3 +377,47 @@ int fd_get_path(int fd, char **ret) {
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int move_fd(int from, int to, int cloexec) {
|
||||
int r;
|
||||
|
||||
/* Move fd 'from' to 'to', make sure FD_CLOEXEC remains equal if requested, and release the old fd. If
|
||||
* 'cloexec' is passed as -1, the original FD_CLOEXEC is inherited for the new fd. If it is 0, it is turned
|
||||
* off, if it is > 0 it is turned on. */
|
||||
|
||||
if (from < 0)
|
||||
return -EBADF;
|
||||
if (to < 0)
|
||||
return -EBADF;
|
||||
|
||||
if (from == to) {
|
||||
|
||||
if (cloexec >= 0) {
|
||||
r = fd_cloexec(to, cloexec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
if (cloexec < 0) {
|
||||
int fl;
|
||||
|
||||
fl = fcntl(from, F_GETFD, 0);
|
||||
if (fl < 0)
|
||||
return -errno;
|
||||
|
||||
cloexec = !!(fl & FD_CLOEXEC);
|
||||
}
|
||||
|
||||
r = dup3(from, to, cloexec ? O_CLOEXEC : 0);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
assert(r == to);
|
||||
|
||||
safe_close(from);
|
||||
|
||||
return to;
|
||||
}
|
||||
|
@ -75,6 +75,8 @@ bool fdname_is_valid(const char *s);
|
||||
|
||||
int fd_get_path(int fd, char **ret);
|
||||
|
||||
int move_fd(int from, int to, int cloexec);
|
||||
|
||||
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
|
||||
#define ERRNO_IS_DISCONNECT(r) \
|
||||
IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)
|
||||
|
@ -275,7 +275,7 @@ static bool exec_context_needs_term(const ExecContext *c) {
|
||||
}
|
||||
|
||||
static int open_null_as(int flags, int nfd) {
|
||||
int fd, r;
|
||||
int fd;
|
||||
|
||||
assert(nfd >= 0);
|
||||
|
||||
@ -283,13 +283,7 @@ static int open_null_as(int flags, int nfd) {
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (fd != nfd) {
|
||||
r = dup2(fd, nfd) < 0 ? -errno : nfd;
|
||||
safe_close(fd);
|
||||
} else
|
||||
r = nfd;
|
||||
|
||||
return r;
|
||||
return move_fd(fd, nfd, false);
|
||||
}
|
||||
|
||||
static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
|
||||
@ -381,16 +375,10 @@ static int connect_logger_as(
|
||||
is_kmsg_output(output),
|
||||
is_terminal_output(output));
|
||||
|
||||
if (fd == nfd)
|
||||
return nfd;
|
||||
|
||||
r = dup2(fd, nfd) < 0 ? -errno : nfd;
|
||||
safe_close(fd);
|
||||
|
||||
return r;
|
||||
return move_fd(fd, nfd, false);
|
||||
}
|
||||
static int open_terminal_as(const char *path, mode_t mode, int nfd) {
|
||||
int fd, r;
|
||||
int fd;
|
||||
|
||||
assert(path);
|
||||
assert(nfd >= 0);
|
||||
@ -399,13 +387,7 @@ static int open_terminal_as(const char *path, mode_t mode, int nfd) {
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
if (fd != nfd) {
|
||||
r = dup2(fd, nfd) < 0 ? -errno : nfd;
|
||||
safe_close(fd);
|
||||
} else
|
||||
r = nfd;
|
||||
|
||||
return r;
|
||||
return move_fd(fd, nfd, false);
|
||||
}
|
||||
|
||||
static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
|
||||
@ -459,7 +441,7 @@ static int setup_input(
|
||||
case EXEC_INPUT_TTY:
|
||||
case EXEC_INPUT_TTY_FORCE:
|
||||
case EXEC_INPUT_TTY_FAIL: {
|
||||
int fd, r;
|
||||
int fd;
|
||||
|
||||
fd = acquire_terminal(exec_context_tty_path(context),
|
||||
i == EXEC_INPUT_TTY_FAIL,
|
||||
@ -469,13 +451,7 @@ static int setup_input(
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
if (fd != STDIN_FILENO) {
|
||||
r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
|
||||
safe_close(fd);
|
||||
} else
|
||||
r = STDIN_FILENO;
|
||||
|
||||
return r;
|
||||
return move_fd(fd, STDIN_FILENO, false);
|
||||
}
|
||||
|
||||
case EXEC_INPUT_SOCKET:
|
||||
|
@ -103,28 +103,24 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
|
||||
|
||||
pipefd[1] = safe_close(pipefd[1]);
|
||||
|
||||
if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
|
||||
log_error_errno(errno, "Failed to dup2() fd: %m");
|
||||
r = move_fd(pipefd[0], STDIN_FILENO, false);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to move fd: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (pipefd[0] != STDIN_FILENO)
|
||||
pipefd[0] = safe_close(pipefd[0]);
|
||||
|
||||
null_fd = open("/dev/null", O_WRONLY|O_NOCTTY);
|
||||
if (null_fd < 0) {
|
||||
log_error_errno(errno, "Failed to open /dev/null: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (dup2(null_fd, STDOUT_FILENO) != STDOUT_FILENO) {
|
||||
log_error_errno(errno, "Failed to dup2() fd: %m");
|
||||
r = move_fd(null_fd, STDOUT_FILENO, false);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to move fd: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (null_fd != STDOUT_FILENO)
|
||||
null_fd = safe_close(null_fd);
|
||||
|
||||
stdio_unset_cloexec();
|
||||
|
||||
if (unshare(CLONE_NEWNET) < 0)
|
||||
@ -175,28 +171,24 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
|
||||
|
||||
pipefd[0] = safe_close(pipefd[0]);
|
||||
|
||||
if (dup2(pipefd[1], STDOUT_FILENO) != STDOUT_FILENO) {
|
||||
log_error_errno(errno, "Failed to dup2() fd: %m");
|
||||
r = move_fd(pipefd[1], STDOUT_FILENO, false);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to move fd: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (pipefd[1] != STDOUT_FILENO)
|
||||
pipefd[1] = safe_close(pipefd[1]);
|
||||
|
||||
null_fd = open("/dev/null", O_RDONLY|O_NOCTTY);
|
||||
if (null_fd < 0) {
|
||||
log_error_errno(errno, "Failed to open /dev/null: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (dup2(null_fd, STDIN_FILENO) != STDIN_FILENO) {
|
||||
log_error_errno(errno, "Failed to dup2() fd: %m");
|
||||
r = move_fd(null_fd, STDIN_FILENO, false);
|
||||
if (r < 0) {
|
||||
log_error_errno(errno, "Failed to move fd: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (null_fd != STDIN_FILENO)
|
||||
null_fd = safe_close(null_fd);
|
||||
|
||||
stdio_unset_cloexec();
|
||||
|
||||
if (unshare(CLONE_NEWNET) < 0)
|
||||
|
@ -492,28 +492,24 @@ int pull_verify(PullJob *main_job,
|
||||
|
||||
gpg_pipe[1] = safe_close(gpg_pipe[1]);
|
||||
|
||||
if (dup2(gpg_pipe[0], STDIN_FILENO) != STDIN_FILENO) {
|
||||
log_error_errno(errno, "Failed to dup2() fd: %m");
|
||||
r = move_fd(gpg_pipe[0], STDIN_FILENO, false);
|
||||
if (r < 0) {
|
||||
log_error_errno(errno, "Failed to move fd: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (gpg_pipe[0] != STDIN_FILENO)
|
||||
gpg_pipe[0] = safe_close(gpg_pipe[0]);
|
||||
|
||||
null_fd = open("/dev/null", O_WRONLY|O_NOCTTY);
|
||||
if (null_fd < 0) {
|
||||
log_error_errno(errno, "Failed to open /dev/null: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (dup2(null_fd, STDOUT_FILENO) != STDOUT_FILENO) {
|
||||
log_error_errno(errno, "Failed to dup2() fd: %m");
|
||||
r = move_fd(null_fd, STDOUT_FILENO, false);
|
||||
if (r < 0) {
|
||||
log_error_errno(errno, "Failed to move fd: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (null_fd != STDOUT_FILENO)
|
||||
null_fd = safe_close(null_fd);
|
||||
|
||||
cmd[k++] = strjoina("--homedir=", gpg_home);
|
||||
|
||||
/* We add the user keyring only to the command line
|
||||
|
Loading…
Reference in New Issue
Block a user