diff options
author | Andrew Gregory <andrew.gregory.8@gmail.com> | 2017-04-15 18:22:51 -0400 |
---|---|---|
committer | Andrew Gregory <andrew.gregory.8@gmail.com> | 2017-04-16 19:41:35 -0400 |
commit | 6a4c6a02de9b45abe4c0f78c4f5d14d92d3359d6 (patch) | |
tree | a04920b212b8552602d48a978a9ae44441474a7c | |
parent | 6d1dcf7937ba3739d17eda614591d1f59ac0bf3a (diff) |
use sockets for scriptlet/hook communication
If a scriptlet/hook dies at the wrong moment it can trigger SIGPIPE,
terminating the process. For pipes, there is no way to prevent SIGPIPE
other than ignoring it process-wide. This can have unintended
consequences in a multi-threaded process. Using send(2) with sockets,
however, allows ignoring SIGPIPE on a per-call basis, leaving other
threads able to make use of SIGPIPE.
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
-rw-r--r-- | lib/libalpm/util.c | 17 |
1 files changed, 4 insertions, 13 deletions
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 58efa5c7..5a7f2c87 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -30,6 +30,7 @@ #include <errno.h> #include <limits.h> #include <sys/wait.h> +#include <sys/socket.h> #include <fnmatch.h> #include <poll.h> @@ -463,7 +464,6 @@ static int _alpm_chroot_write_to_child(alpm_handle_t *handle, int fd, _alpm_cb_io out_cb, void *cb_ctx) { ssize_t nwrite; - struct sigaction newaction, oldaction; if(*buf_size == 0) { /* empty buffer, ask the callback for more */ @@ -473,16 +473,7 @@ static int _alpm_chroot_write_to_child(alpm_handle_t *handle, int fd, } } - /* ignore SIGPIPE in case the pipe has been closed */ - newaction.sa_handler = SIG_IGN; - sigemptyset(&newaction.sa_mask); - newaction.sa_flags = 0; - sigaction(SIGPIPE, &newaction, &oldaction); - - nwrite = write(fd, buf, *buf_size); - - /* restore previous SIGPIPE handler */ - sigaction(SIGPIPE, &oldaction, NULL); + nwrite = send(fd, buf, *buf_size, MSG_NOSIGNAL); if(nwrite != -1) { /* write was successful, remove the written data from the buffer */ @@ -592,13 +583,13 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[], /* Flush open fds before fork() to avoid cloning buffers */ fflush(NULL); - if(pipe(child2parent_pipefd) == -1) { + if(socketpair(AF_UNIX, SOCK_STREAM, 0, child2parent_pipefd) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not create pipe (%s)\n"), strerror(errno)); retval = 1; goto cleanup; } - if(pipe(parent2child_pipefd) == -1) { + if(socketpair(AF_UNIX, SOCK_STREAM, 0, parent2child_pipefd) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not create pipe (%s)\n"), strerror(errno)); retval = 1; goto cleanup; |