From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:38146) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPFH7-0007I8-C7 for qemu-devel@nongnu.org; Tue, 01 May 2012 11:46:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SPFH5-00069B-9g for qemu-devel@nongnu.org; Tue, 01 May 2012 11:46:00 -0400 Received: from e06smtp10.uk.ibm.com ([195.75.94.106]:55931) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPF45-0001G4-20 for qemu-devel@nongnu.org; Tue, 01 May 2012 11:32:33 -0400 Received: from /spool/local by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 1 May 2012 16:32:28 +0100 Received: from d06av07.portsmouth.uk.ibm.com (d06av07.portsmouth.uk.ibm.com [9.149.37.248]) by d06nrmr1707.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q41FW05o2556112 for ; Tue, 1 May 2012 16:32:00 +0100 Received: from d06av07.portsmouth.uk.ibm.com (d06av07.portsmouth.uk.ibm.com [127.0.0.1]) by d06av07.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q41FSJBD005878 for ; Tue, 1 May 2012 11:28:19 -0400 From: Stefan Hajnoczi Date: Tue, 1 May 2012 16:31:46 +0100 Message-Id: <1335886307-27586-5-git-send-email-stefanha@linux.vnet.ibm.com> In-Reply-To: <1335886307-27586-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1335886307-27586-1-git-send-email-stefanha@linux.vnet.ibm.com> Subject: [Qemu-devel] [RFC 4/5] osdep: add qemu_recvmsg() wrapper List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Anthony Liguori , Stefan Hajnoczi , libvir-list@redhat.com, Corey Bryant Usually we need to set O_CLOEXEC, which is platform-specific. Add a wrapper like qemu_open() but for qemu_recvmsg(). Signed-off-by: Stefan Hajnoczi --- block.c | 5 +---- osdep.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ qemu-common.h | 2 ++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/block.c b/block.c index d3bf443..e66d64f 100644 --- a/block.c +++ b/block.c @@ -176,10 +176,7 @@ int file_open(const char *filename, int flags, mode_t mode) msg.msg_control = &msg_control; msg.msg_controllen = sizeof(msg_control); - do { - ret = recvmsg(remote_file_fd, &msg, 0); - } while (ret == -1 && errno == EINTR); - if (ret != sizeof(OpenResponse)) { + if (qemu_recvmsg(remote_file_fd, &msg, 0) != sizeof(OpenResponse)) { errno = EPIPE; return -1; } diff --git a/osdep.c b/osdep.c index 3e6bada..834e78f 100644 --- a/osdep.c +++ b/osdep.c @@ -103,6 +103,52 @@ int qemu_open(const char *name, int flags, ...) } /* + * Receive a message from a socket + * + * This behaves like recvmsg(2) except that EINTR is handled internally and + * never returned. Passed file descriptors will have O_CLOEXEC set. + */ +ssize_t qemu_recvmsg(int fd, struct msghdr *msg, int flags) +{ + ssize_t ret; + +#ifdef MSG_CMSG_CLOEXEC + /* Receive file descriptors with O_CLOEXEC */ + flags |= MSG_CMSG_CLOEXEC; +#endif + + do { + ret = recvmsg(fd, msg, flags); + } while (ret == -1 && errno == EINTR); + if (ret < 0) { + return ret; + } + +#ifndef MSG_CMSG_CLOEXEC + /* As a fallback, set O_CLOEXEC in a way that is not thread-safe */ + { + struct cmsghdr *cmsg; + for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { + int new_fd; + + if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) || + cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS) { + continue; + } + + new_fd = *((int *)CMSG_DATA(cmsg)); + if (new_fd >= 0) { + qemu_set_cloexec(new_fd); + } + } + } +#endif + + return ret; +} + +/* * A variant of write(2) which handles partial write. * * Return the number of bytes transferred. diff --git a/qemu-common.h b/qemu-common.h index 50f659a..e3a6c4d 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -184,6 +184,8 @@ const char *path(const char *pathname); void *qemu_oom_check(void *ptr); int qemu_open(const char *name, int flags, ...); +struct msghdr; +ssize_t qemu_recvmsg(int fd, struct msghdr *msg, int flags); ssize_t qemu_write_full(int fd, const void *buf, size_t count) QEMU_WARN_UNUSED_RESULT; ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags) -- 1.7.10