And use it in io/channel-socket.c. This simplifies the following commit, which will move this functionality from io/channel-socket.c to the callers.
Signed-off-by: Vladimir Sementsov-Ogievskiy <[email protected]> --- include/qemu/osdep.h | 7 +++++++ io/channel-socket.c | 24 +++++++++++++----------- util/oslib-posix.c | 12 ++++++++++++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 1b38cb7e45..dde98d588c 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -689,6 +689,13 @@ ssize_t qemu_write_full(int fd, const void *buf, size_t count) void qemu_set_cloexec(int fd); bool qemu_set_blocking(int fd, bool block, Error **errp); +/* + * qemu_fds_set_blockinging: + * Call qemu_socket_set_block() on several fds. + * When @nfds = 0, does nothing, @fds is not touched. + */ +bool qemu_fds_set_blockinging(int *fds, int nfds, bool block, Error **errp); + /* Return a dynamically allocated directory path that is appropriate for storing * local state. * diff --git a/io/channel-socket.c b/io/channel-socket.c index 4f7e86f72f..96098b5bcc 100644 --- a/io/channel-socket.c +++ b/io/channel-socket.c @@ -472,8 +472,11 @@ static void qio_channel_socket_copy_fds(struct msghdr *msg, *fds = NULL; for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { - int fd_size, i; + int fd_size; int gotfds; +#ifndef MSG_CMSG_CLOEXEC + int i; +#endif if (cmsg->cmsg_len < CMSG_LEN(sizeof(int)) || cmsg->cmsg_level != SOL_SOCKET || @@ -491,20 +494,19 @@ static void qio_channel_socket_copy_fds(struct msghdr *msg, *fds = g_renew(int, *fds, *nfds + gotfds); memcpy(*fds + *nfds, CMSG_DATA(cmsg), fd_size); + /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */ + /* TODO: don't crash on error, just handle it! */ + qemu_fds_set_blockinging(*fds + *nfds, gotfds, true, &error_abort); + +#ifndef MSG_CMSG_CLOEXEC for (i = 0; i < gotfds; i++) { int fd = (*fds)[*nfds + i]; - if (fd < 0) { - continue; + if (fd >= 0) { + qemu_set_cloexec(fd); } - - /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */ - /* TODO: don't crash on error, just handle it! */ - qemu_set_blocking(fd, true, &error_abort); - -#ifndef MSG_CMSG_CLOEXEC - qemu_set_cloexec(fd); -#endif } +#endif + *nfds += gotfds; } } diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 8891d82db0..8589ff21ec 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -262,6 +262,18 @@ bool qemu_set_blocking(int fd, bool block, Error **errp) return true; } +bool qemu_fds_set_blockinging(int *fds, int nfds, bool block, Error **errp) +{ + int i; + for (i = 0; i < nfds; i++) { + if (fds[i] >= 0 && !qemu_set_blocking(fds[i], block, errp)) { + return false; + } + } + + return true; +} + int socket_set_fast_reuse(int fd) { int val = 1, ret; -- 2.48.1
