From 31cdbd2afa47318316a8a1f203904330e53fc120 Mon Sep 17 00:00:00 2001 From: Brandon Carpenter Date: Thu, 3 Oct 2013 16:21:42 -0700 Subject: [PATCH 1/2] Add abstract namespace support for IPC sockets on Linux. Converts an initial strudel or "at sign" (@) in the Unix socket path to a NULL character ('\0') indicating that the socket uses the abstract namespace instead of the filesystem namespace. For instance, binding a socket to 'ipc://@/tmp/tester' will not create a file associated with the socket whereas binding to 'ipc:///tmp/tester' will create the file /tmp/tester. See issue 567 for more information. --- AUTHORS | 1 + src/ipc_address.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/AUTHORS b/AUTHORS index ab849c70..8481813f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -20,6 +20,7 @@ Ben Gray Bernd Prager Bernd Melchers Bob Beaty +Brandon Carpenter Brian Buchanan Brett Cameron Burak Arslan diff --git a/src/ipc_address.cpp b/src/ipc_address.cpp index 39f0042a..fb1acc86 100644 --- a/src/ipc_address.cpp +++ b/src/ipc_address.cpp @@ -54,6 +54,10 @@ int zmq::ipc_address_t::resolve (const char *path_) address.sun_family = AF_UNIX; strcpy (address.sun_path, path_); +#if defined ZMQ_HAVE_LINUX + if (*path_ == '@') + *address.sun_path = '\0'; +#endif return 0; } @@ -65,7 +69,15 @@ int zmq::ipc_address_t::to_string (std::string &addr_) } std::stringstream s; +#if !defined ZMQ_HAVE_LINUX s << "ipc://" << address.sun_path; +#else + s << "ipc://"; + if (*address.sun_path) + s << address.sun_path; + else + s << "@" << address.sun_path + 1; +#endif addr_ = s.str (); return 0; } From f499c89528be9a8bf87146b3c3808988c83aad74 Mon Sep 17 00:00:00 2001 From: Brandon Carpenter Date: Thu, 3 Oct 2013 16:35:30 -0700 Subject: [PATCH 2/2] Add test for abstract namespace support in ipc sockets on Linux. See issue 567. --- configure.ac | 3 ++ tests/Makefile.am | 8 +++++- tests/test_abstract_ipc.cpp | 57 +++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/test_abstract_ipc.cpp diff --git a/configure.ac b/configure.ac index ac130181..0c416040 100644 --- a/configure.ac +++ b/configure.ac @@ -114,6 +114,7 @@ libzmq_dso_visibility="yes" # Platform specific checks libzmq_on_mingw32="no" libzmq_on_android="no" +libzmq_on_linux="no" # Set some default features required by 0MQ code. CPPFLAGS="-D_REENTRANT -D_THREAD_SAFE $CPPFLAGS" @@ -129,6 +130,7 @@ case "${host_os}" in CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" fi AC_DEFINE(ZMQ_HAVE_LINUX, 1, [Have Linux OS]) + libzmq_on_linux="yes" case "${host_os}" in *android*) @@ -428,6 +430,7 @@ AC_LANG_POP([C++]) AM_CONDITIONAL(BUILD_PGM, test "x$libzmq_pgm_ext" = "xyes") AM_CONDITIONAL(ON_MINGW, test "x$libzmq_on_mingw32" = "xyes") AM_CONDITIONAL(ON_ANDROID, test "x$libzmq_on_android" = "xyes") +AM_CONDITIONAL(ON_LINUX, test "x$libzmq_on_linux" = "xyes") # Checks for library functions. AC_TYPE_SIGNAL diff --git a/tests/Makefile.am b/tests/Makefile.am index f11724fa..b211eb10 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -38,7 +38,8 @@ noinst_PROGRAMS = test_system \ test_req_relaxed \ test_conflate \ test_inproc_connect \ - test_issue_566 + test_issue_566 \ + test_abstract_ipc if !ON_MINGW noinst_PROGRAMS += test_shutdown_stress \ @@ -84,6 +85,7 @@ test_req_relaxed_SOURCES = test_req_relaxed.cpp test_conflate_SOURCES = test_conflate.cpp test_inproc_connect_SOURCES = test_inproc_connect.cpp test_issue_566_SOURCES = test_issue_566.cpp +test_abstract_ipc_SOURCES = test_abstract_ipc.cpp if !ON_MINGW test_shutdown_stress_SOURCES = test_shutdown_stress.cpp test_pair_ipc_SOURCES = test_pair_ipc.cpp testutil.hpp @@ -95,3 +97,7 @@ endif # Run the test cases TESTS = $(noinst_PROGRAMS) XFAIL_TESTS = test_linger + +if !ON_LINUX +XFAIL_TESTS += test_abstract_ipc +endif diff --git a/tests/test_abstract_ipc.cpp b/tests/test_abstract_ipc.cpp new file mode 100644 index 00000000..3c91f32d --- /dev/null +++ b/tests/test_abstract_ipc.cpp @@ -0,0 +1,57 @@ +/* + Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "testutil.hpp" + +int main (void) +{ + setup_test_environment(); + void *ctx = zmq_ctx_new (); + assert (ctx); + + void *sb = zmq_socket (ctx, ZMQ_PAIR); + assert (sb); + int rc = zmq_bind (sb, "ipc://@/tmp/tester"); + assert (rc == 0); + + char endpoint[200]; + size_t size = sizeof(endpoint); + rc = zmq_getsockopt (sb, ZMQ_LAST_ENDPOINT, endpoint, &size); + assert (rc == 0); + rc = strncmp(endpoint, "ipc://@/tmp/tester", size); + assert (rc == 0); + + void *sc = zmq_socket (ctx, ZMQ_PAIR); + assert (sc); + rc = zmq_connect (sc, "ipc://@/tmp/tester"); + assert (rc == 0); + + bounce (sb, sc); + + rc = zmq_close (sc); + assert (rc == 0); + + rc = zmq_close (sb); + assert (rc == 0); + + rc = zmq_ctx_term (ctx); + assert (rc == 0); + + return 0 ; +}