From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42503) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlAEP-0004PQ-Qj for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QlAEM-0005bM-CG for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:16 -0400 Received: from e4.ny.us.ibm.com ([32.97.182.144]:39447) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlAEL-0005aw-Hg for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:13 -0400 Received: from d01relay07.pok.ibm.com (d01relay07.pok.ibm.com [9.56.227.147]) by e4.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p6P1Mjqs007212 for ; Sun, 24 Jul 2011 21:22:45 -0400 Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by d01relay07.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p6P1jCmN1085672 for ; Sun, 24 Jul 2011 21:45:12 -0400 Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p6P1jCsQ008149 for ; Sun, 24 Jul 2011 21:45:12 -0400 From: Anthony Liguori Date: Sun, 24 Jul 2011 20:44:53 -0500 Message-Id: <1311558293-5855-22-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> References: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> Subject: [Qemu-devel] [PATCH 21/21] qom-chrdrv: add UnixServer List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Anthony Liguori This is roughly equivalent to -chardev socket,path=PATH,server=on Signed-off-by: Anthony Liguori --- chrdrv/Makefile | 1 + chrdrv/Qconfig | 7 +++ chrdrv/unixsrv.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ include/qemu/unixsrv.h | 24 +++++++++++ 4 files changed, 136 insertions(+), 0 deletions(-) create mode 100644 chrdrv/unixsrv.c create mode 100644 include/qemu/unixsrv.h diff --git a/chrdrv/Makefile b/chrdrv/Makefile index 50a3d50..43e516f 100644 --- a/chrdrv/Makefile +++ b/chrdrv/Makefile @@ -2,3 +2,4 @@ chrdrv-obj-$(CONFIG_CHRDRV) := chrdrv.o chrdrv-obj-$(CONFIG_CHRDRV_MEM) += memchr.o chrdrv-obj-$(CONFIG_CHRDRV_SOCKET) += socketchr.o chrdrv-obj-$(CONFIG_CHRDRV_TCP_SERVER) += tcpsrv.o +chrdrv-obj-$(CONFIG_CHRDRV_UNIX_SERVER) += unixsrv.o diff --git a/chrdrv/Qconfig b/chrdrv/Qconfig index ea22b50..ae2c20e 100644 --- a/chrdrv/Qconfig +++ b/chrdrv/Qconfig @@ -24,3 +24,10 @@ config CHRDRV_TCP_SERVER depends on CHRDRV_SOCKET help Character driver that implements a TCP server transport. + +config CHRDRV_UNIX_SERVER + bool "UNIX server character driver" + default y + depends on CHRDRV_SOCKET && UNIX + help + Character driver that implements a domain socket server transport. diff --git a/chrdrv/unixsrv.c b/chrdrv/unixsrv.c new file mode 100644 index 0000000..c4a0621 --- /dev/null +++ b/chrdrv/unixsrv.c @@ -0,0 +1,104 @@ +#include "qemu/unixsrv.h" + +void unix_server_initialize(UnixServer *obj, const char *id) +{ + type_initialize(obj, TYPE_UNIX_SERVER, id); +} + +void unix_server_finalize(UnixServer *obj) +{ + type_finalize(obj); +} + +const char *unix_server_get_path(UnixServer *obj, Error **errp) +{ + return obj->path; +} + +void unix_server_set_path(UnixServer *obj, const char *path, Error **errp) +{ + qemu_free(obj->path); + obj->path = qemu_strdup(path); + + socket_server_rebind(SOCKET_SERVER(obj)); +} + +static int unix_server_make_listen_socket(SocketServer *ss) +{ + UnixServer *s = UNIX_SERVER(ss); + struct sockaddr_un addr; + int ret; + int fd = -1; + + fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + return -1; + } + + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", s->path); + + ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1) { + closesocket(fd); + return -1; + } + + listen(fd, 1); + + return fd; +} + +static int unix_server_accept(SocketServer *ss) +{ + int fd; + + do { + struct sockaddr_un addr; + socklen_t addrlen = sizeof(addr); + fd = qemu_accept(ss->listen_fd, (struct sockaddr *)&addr, &addrlen); + } while (fd == -1 && errno == EINTR); + + return fd; +} + +static void unix_server_init(TypeInstance *inst) +{ + UnixServer *s = UNIX_SERVER(inst); + + plug_add_property_str(PLUG(s), "path", + (PlugPropertyGetterStr *)unix_server_get_path, + (PlugPropertySetterStr *)unix_server_set_path, + PROP_F_READWRITE); +} + +static void unix_server_fini(TypeInstance *inst) +{ + UnixServer *s = UNIX_SERVER(inst); + + qemu_free(s->path); +} + +static void unix_server_class_init(TypeClass *class) +{ + SocketServerClass *ssc = SOCKET_SERVER_CLASS(class); + + ssc->accept = unix_server_accept; + ssc->make_listen_socket = unix_server_make_listen_socket; +} + +static TypeInfo unix_server_type_info = { + .name = TYPE_UNIX_SERVER, + .parent = TYPE_SOCKET_SERVER, + .instance_size = sizeof(UnixServer), + .instance_init = unix_server_init, + .instance_finalize = unix_server_fini, + .class_init = unix_server_class_init, +}; + +static void register_backends(void) +{ + type_register_static(&unix_server_type_info); +} + +device_init(register_backends); diff --git a/include/qemu/unixsrv.h b/include/qemu/unixsrv.h new file mode 100644 index 0000000..71182bc --- /dev/null +++ b/include/qemu/unixsrv.h @@ -0,0 +1,24 @@ +#ifndef CHAR_DRIVER_UNIX_H +#define CHAR_DRIVER_UNIX_H + +#include "qemu/socketchr.h" +#include "qemu_socket.h" + +typedef struct UnixServer +{ + SocketServer parent; + + /* private */ + char *path; +} UnixServer; + +#define TYPE_UNIX_SERVER "unix-server" +#define UNIX_SERVER(obj) TYPE_CHECK(UnixServer, obj, TYPE_UNIX_SERVER) + +void unix_server_initialize(UnixServer *obj, const char *id); +void unix_server_finalize(UnixServer *obj); + +const char *unix_server_get_path(UnixServer *obj, Error **errp); +void unix_server_set_path(UnixServer *obj, const char *value, Error **errp); + +#endif -- 1.7.4.1