qemu_set_blocking() relies on g_unix_set_fd_nonblocking(), which always issues fcntl(F_SETFL) even if O_NONBLOCK already has the requested value. macOS rejects F_SETFL on POSIX shared memory descriptors. The socket channel treats this like a read error and disconnects. Those descriptors are passed in blocking mode anyway, so there is nothing to change on them. Query the flags with F_GETFL first and only issue F_SETFL when O_NONBLOCK is actually set.
Signed-off-by: Tim Pambor <[email protected]> --- util/oslib-posix.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/util/oslib-posix.c b/util/oslib-posix.c index dc001da66d..3d5bb16ca6 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -252,17 +252,29 @@ void qemu_anon_ram_free(void *ptr, size_t size) bool qemu_set_blocking(int fd, bool block, Error **errp) { - g_autoptr(GError) err = NULL; + int flags, new_flags; - if (!g_unix_set_fd_nonblocking(fd, !block, &err)) { - error_setg_errno(errp, errno, - "Can't set file descriptor %d %s: %s", fd, - block ? "blocking" : "non-blocking", - err->message); - return false; + flags = fcntl(fd, F_GETFL); + if (flags < 0) { + goto fail; + } + + if (block) { + new_flags = flags & ~O_NONBLOCK; + } else { + new_flags = flags | O_NONBLOCK; + } + + if (new_flags != flags && fcntl(fd, F_SETFL, new_flags) < 0) { + goto fail; } return true; + +fail: + error_setg_errno(errp, errno, "Can't set file descriptor %d %s", fd, + block ? "blocking" : "non-blocking"); + return false; } int socket_set_fast_reuse(int fd) -- 2.55.0
