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>
This commit is contained in:
parent
6d1dcf7937
commit
6a4c6a02de
1 changed files with 4 additions and 13 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue