From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45676) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W6Fdw-0002M3-5u for qemu-devel@nongnu.org; Thu, 23 Jan 2014 03:28:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W6Fdn-0000C8-47 for qemu-devel@nongnu.org; Thu, 23 Jan 2014 03:28:08 -0500 Received: from e28smtp04.in.ibm.com ([122.248.162.4]:41588) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W6Fdm-0000Al-GJ for qemu-devel@nongnu.org; Thu, 23 Jan 2014 03:27:59 -0500 Received: from /spool/local by e28smtp04.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 23 Jan 2014 13:57:52 +0530 Received: from d28relay02.in.ibm.com (d28relay02.in.ibm.com [9.184.220.59]) by d28dlp01.in.ibm.com (Postfix) with ESMTP id A5919E004A for ; Thu, 23 Jan 2014 14:00:50 +0530 (IST) Received: from d28av02.in.ibm.com (d28av02.in.ibm.com [9.184.220.64]) by d28relay02.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s0N8RXem19267754 for ; Thu, 23 Jan 2014 13:57:33 +0530 Received: from d28av02.in.ibm.com (localhost [127.0.0.1]) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s0N8RnUx020590 for ; Thu, 23 Jan 2014 13:57:49 +0530 From: Lei Li Date: Thu, 23 Jan 2014 16:27:39 +0800 Message-Id: <1390465663-17650-2-git-send-email-lilei@linux.vnet.ibm.com> In-Reply-To: <1390465663-17650-1-git-send-email-lilei@linux.vnet.ibm.com> References: <1390465663-17650-1-git-send-email-lilei@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 1/5] qemu-fd-exchange: provide common methods for exchange fd List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: mohan@in.ibm.com, Lei Li , pbonzini@redhat.com Signed-off-by: Lei Li --- include/qemu/fd-exchange.h | 25 +++++++++++ util/Makefile.objs | 1 + util/qemu-fd-exchange.c | 97 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 0 deletions(-) create mode 100644 include/qemu/fd-exchange.h create mode 100644 util/qemu-fd-exchange.c diff --git a/include/qemu/fd-exchange.h b/include/qemu/fd-exchange.h new file mode 100644 index 0000000..8502960 --- /dev/null +++ b/include/qemu/fd-exchange.h @@ -0,0 +1,25 @@ +/* + * Internal common methods for exchange of FD + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef FD_EXCHANGE_H +#define FD_EXCHANGE_H + +#include + +union MsgControl { + struct cmsghdr cmsg; + char control[CMSG_SPACE(sizeof(int))]; +}; + +ssize_t qemu_send_with_fd(int sockfd, int passed_fd, + const void *buf, size_t len); + +ssize_t qemu_recv_with_fd(int sockfd, int *passed_fd, + void *buf, size_t len); + +#endif diff --git a/util/Makefile.objs b/util/Makefile.objs index af3e5cb..2fb42bf 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -13,3 +13,4 @@ util-obj-y += hexdump.o util-obj-y += crc32c.o util-obj-y += throttle.o util-obj-y += getauxval.o +util-obj-y += qemu-fd-exchange.o diff --git a/util/qemu-fd-exchange.c b/util/qemu-fd-exchange.c new file mode 100644 index 0000000..bee3fc1 --- /dev/null +++ b/util/qemu-fd-exchange.c @@ -0,0 +1,97 @@ +/* + * Internal common methods for exchange of FD + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/fd-exchange.h" +#include "qemu-common.h" + + +ssize_t qemu_send_with_fd(int sockfd, int passed_fd, + const void *buf, size_t len) +{ + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsg; + union MsgControl msg_control; + int retval; + + iov.iov_base = (char *)buf; + iov.iov_len = len; + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = len; + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + + if (passed_fd < 0) { + *(char *)buf = passed_fd; + } else { + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + + cmsg = &msg_control.cmsg; + cmsg->cmsg_len = CMSG_LEN(sizeof(passed_fd)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + memcpy(CMSG_DATA(cmsg), &passed_fd, sizeof(passed_fd)); + + } + + do { + retval = sendmsg(sockfd, &msg, 0); + } while (retval < 0 && errno == EINTR); + + return retval; +} + +ssize_t qemu_recv_with_fd(int sockfd, int *passed_fd, + void *buf, size_t len) +{ + struct iovec iov; + struct msghdr msg; + struct cmsghdr *cmsg; + union MsgControl msg_control; + int retval; + char data; + + iov.iov_base = &data; + iov.iov_len = len; + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + + do { + retval = recvmsg(sockfd, &msg, 0); + } while (retval < 0 && errno == EINTR); + + if (retval <= 0) { + return retval; + } + + if (data != *(char *)buf) { + *passed_fd = data; + return 0; + } + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) || + cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS) { + continue; + } + + memcpy(passed_fd, CMSG_DATA(cmsg), sizeof(*passed_fd)); + return 0; + } + + *passed_fd = -ENFILE; + return retval; +} -- 1.7.7.6