From patchwork Mon Jan 7 13:15:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Barabash X-Patchwork-Id: 209918 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E3E522C009B for ; Tue, 8 Jan 2013 00:16:15 +1100 (EST) Received: from localhost ([::1]:33751 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TsCYj-0007rv-W2 for incoming@patchwork.ozlabs.org; Mon, 07 Jan 2013 08:16:09 -0500 Received: from eggs.gnu.org ([208.118.235.92]:38682) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TsCYa-0007rd-Ec for qemu-devel@nongnu.org; Mon, 07 Jan 2013 08:16:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TsCYV-0001i7-0R for qemu-devel@nongnu.org; Mon, 07 Jan 2013 08:16:00 -0500 Received: from relay1.mentorg.com ([192.94.38.131]:50598) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TsCYU-0001hw-Qd for qemu-devel@nongnu.org; Mon, 07 Jan 2013 08:15:54 -0500 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1TsCYU-0007Ew-4W from Alexander_Barabash@mentor.com for qemu-devel@nongnu.org; Mon, 07 Jan 2013 05:15:54 -0800 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Mon, 7 Jan 2013 05:15:53 -0800 Received: from galileo.isr.mentorg.com (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.1.289.1; Mon, 7 Jan 2013 13:15:52 +0000 From: Alexander Barabash To: Date: Mon, 7 Jan 2013 15:15:49 +0200 Message-ID: <1357564549-18031-1-git-send-email-alexander_barabash@mentor.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 X-OriginalArrivalTime: 07 Jan 2013 13:15:53.0937 (UTC) FILETIME=[1F370410:01CDECD9] X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 192.94.38.131 Cc: Alexander Barabash Subject: [Qemu-devel] [PATCH 1/1] Support abstract socket namespace in AF_UNIX socket family. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The abstract socket namespace is a nonportable Linux extension. The sockets' names in this namespace have no connection with file system pathnames. To specify a named AF_UNIX socket in the abstract socket namespace, start the socket's path option with a backslash followed by zero: \0. Signed-off-by: Alexander Barabash --- qemu-sockets.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/qemu-sockets.c b/qemu-sockets.c index 3537bf3..70c8ad5 100644 --- a/qemu-sockets.c +++ b/qemu-sockets.c @@ -663,11 +663,50 @@ int inet_nonblocking_connect(const char *str, #ifndef _WIN32 +/* + * The abstract socket namespace is a nonportable Linux extension. + * The sockets' names in this namespace have no connection + * with file system pathnames. To specify a named AF_UNIX socket + * in the abstract socket namespace, start the socket's path option + * with a backslash followed by zero: \0. + */ +static +char *get_abstract_namespace_path(const char *path, int *abstract_path_length) +{ + char *abstract_path; + char *inp; + char *outp; + char c; + + *abstract_path_length = 0; + if ((path == NULL) || (path[0] != '\\') || (path[1] != '0')) { + return NULL; + } + abstract_path = g_strdup(path + 2); + for (inp = abstract_path, outp = abstract_path; (c = *inp); ++inp, ++outp) { + if (c == '\\') { + c = *++inp; + if (c == '\\') { + *outp = c; + } else if (c == '0') { + *outp = '\0'; + } + } else { + *outp = c; + } + } + *abstract_path_length = outp - abstract_path; + return abstract_path; +} + int unix_listen_opts(QemuOpts *opts, Error **errp) { struct sockaddr_un un; const char *path = qemu_opt_get(opts, "path"); + int abstract_path_length; + char *abstract_path; int sock, fd; + socklen_t addrlen = sizeof(un); sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); if (sock < 0) { @@ -675,9 +714,18 @@ int unix_listen_opts(QemuOpts *opts, Error **errp) return -1; } + abstract_path = get_abstract_namespace_path(path, &abstract_path_length); + memset(&un, 0, sizeof(un)); un.sun_family = AF_UNIX; - if (path && strlen(path)) { + if (abstract_path != NULL) { + if (abstract_path_length > sizeof(un.sun_path) - 1) { + abstract_path_length = sizeof(un.sun_path) - 1; + } + memcpy(un.sun_path + 1, abstract_path, abstract_path_length); + addrlen = + offsetof(struct sockaddr_un, sun_path) + 1 + abstract_path_length; + } else if (path && strlen(path)) { snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); } else { char *tmpdir = getenv("TMPDIR"); @@ -694,8 +742,10 @@ int unix_listen_opts(QemuOpts *opts, Error **errp) qemu_opt_set(opts, "path", un.sun_path); } - unlink(un.sun_path); - if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { + if (abstract_path == NULL) { + unlink(un.sun_path); + } + if (bind(sock, (struct sockaddr *) &un, addrlen) < 0) { error_set_errno(errp, errno, QERR_SOCKET_BIND_FAILED); goto err; } @@ -704,10 +754,12 @@ int unix_listen_opts(QemuOpts *opts, Error **errp) goto err; } + g_free(abstract_path); return sock; err: closesocket(sock); + g_free(abstract_path); return -1; }