diff --git a/src/util-io.c b/src/util-io.c index 702da88..4765e6c 100644 --- a/src/util-io.c +++ b/src/util-io.c @@ -47,7 +47,9 @@ xread_with_fds(int fd, void *buf, size_t count, int **fds) .msg_controllen = sizeof(control), }; + sigset_t old_mask = signals_block(); int received = xerrno(recvmsg(fd, &msg, 0)); + signals_release(old_mask); if (received > 0) { *fds = NULL; @@ -110,7 +112,11 @@ xsend_with_fd(int fd, const void *buf, size_t len, int *fds) header->cmsg_type = SCM_RIGHTS; memcpy(CMSG_DATA(CMSG_FIRSTHDR(&msg)), fds, nfds * sizeof(int)); - return xerrno(sendmsg(fd, &msg, MSG_NOSIGNAL)); + sigset_t old_mask = signals_block(); + int sent = xerrno(sendmsg(fd, &msg, MSG_NOSIGNAL)); + signals_release(old_mask); + + return sent; } /* consider this struct opaque */ diff --git a/src/util-io.h b/src/util-io.h index ac65bde..ab42d1c 100644 --- a/src/util-io.h +++ b/src/util-io.h @@ -43,7 +43,7 @@ /** * Blocks the SIGALRM signal. * - * @return the previous set of signals to pass to release_signals() + * @return the previous set of signals to pass to signals_release() */ static inline sigset_t signals_block(void) @@ -61,7 +61,7 @@ signals_block(void) /** * Release the SIGALRM signal. * - * @param mask: The previous set of signals as returned by block_signals(). + * @param mask: The previous set of signals as returned by signals_block(). */ static inline void signals_release(sigset_t mask) @@ -81,12 +81,15 @@ xerrno(int value) { } /** - * Wrapper around close(). It checks for fd != -1 to satisfy coverity and - * friends and always returns -1. + * Wrapper around close() that blocks the SIGALRM signal. It checks for + * fd != -1 to satisfy coverity and friends and always returns -1. */ static inline int xclose(int fd) { + sigset_t old_mask = signals_block(); if (fd != -1) close(fd); + signals_release(old_mask); + return -1; } @@ -97,42 +100,56 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(FILE *, fclose); #define _cleanup_fclose_ _cleanup_(fclosep) /** - * Wrapper around read(). Returns the number of bytes read or a negative - * errno on failure. + * Wrapper around read() that blocks the SIGALRM signal. + * Returns the number of bytes read or a negative errno on failure. */ static inline int xread(int fd, void *buf, size_t count) { - return xerrno(read(fd, buf, count)); + sigset_t old_mask = signals_block(); + int n = xerrno(read(fd, buf, count)); + signals_release(old_mask); + + return n; } /** - * Wrapper around read(). Returns the number of bytes read or a negative - * errno on failure. Any fds passed along with the message - * are stored in the -1-terminated allocated fds array, to be freed by the - * caller. Where no fds were passed, the array is NULL. + * Wrapper around read() that blocks the SIGALRM signal. + * Returns the number of bytes read or a negative errno on failure. + * Any fds passed along with the message are stored in the -1-terminated + * allocated fds array, to be freed by the caller. Where no fds were + * passed, the array is NULL. */ int xread_with_fds(int fd, void *buf, size_t count, int **fds); /** - * Wrapper around write(). Returns the number of bytes written or a negative - * errno on failure. + * Wrapper around write() that blocks the SIGALRM signal. + * Returns the number of bytes written or a negative errno on failure. */ static inline int xwrite(int fd, const void *buf, size_t count) { - return xerrno(write(fd, buf, count)); + sigset_t old_mask = signals_block(); + int n = xerrno(write(fd, buf, count)); + signals_release(old_mask); + + return n; } /** - * Wrapper around send() that always sets MSG_NOSIGNAL. Returns the number - * of bytes written or a negative errno on failure. + * Wrapper around send() that always sets MSG_NOSIGNAL and blocks the + * SIGALRM signal. + * Returns the number of bytes written or a negative errno on failure. */ static inline int xsend(int fd, const void *buf, size_t len) { - return xerrno(send(fd, buf, len, MSG_NOSIGNAL)); + sigset_t old_mask = signals_block(); + int n = xerrno(send(fd, buf, len, MSG_NOSIGNAL)); + signals_release(old_mask); + + return n; } /** @@ -158,14 +175,19 @@ xconnect(const char *path) if (!xsnprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path)) return -EINVAL; + sigset_t old_mask = signals_block(); int sockfd = socket(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK, 0); if (sockfd == -1) - return -errno; + goto fail; if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) - return -errno; + goto fail; + signals_release(old_mask); return sockfd; +fail: + signals_release(old_mask); + return -errno; } /**