diff --git a/src/ipc_listener.cpp b/src/ipc_listener.cpp index 84437596..8a9d2aea 100644 --- a/src/ipc_listener.cpp +++ b/src/ipc_listener.cpp @@ -95,32 +95,34 @@ void zmq::ipc_listener_t::in_event () send_attach (session, engine, false); } -int zmq::ipc_listener_t::get_address (std::string *addr_) +int zmq::ipc_listener_t::get_address (std::string &addr_) { - struct sockaddr_un saddr; + struct sockaddr_storage ss; int rc; // Get the details of the IPC socket - socklen_t sl = sizeof(sockaddr_un); - rc = getsockname (s, (sockaddr *)&saddr, &sl); + socklen_t sl = sizeof (ss); + rc = getsockname (s, (sockaddr *) &ss, &sl); if (rc != 0) { return rc; } // Store the address for retrieval by users using wildcards - *addr_ = std::string("ipc://") + std::string(saddr.sun_path); + addr_ = std::string ("ipc://"); + struct sockaddr_un saddr; + memcpy (&saddr, &ss, sizeof (saddr)); + addr_.append (saddr.sun_path); return 0; } int zmq::ipc_listener_t::set_address (const char *addr_) { - // Allow wildcard file - if(*addr_ == '*') { + if (*addr_ == '*') { addr_ = tempnam(NULL, NULL); } - + // Get rid of the file associated with the UNIX domain socket that // may have been left behind by the previous run of the application. ::unlink (addr_); @@ -148,8 +150,8 @@ int zmq::ipc_listener_t::set_address (const char *addr_) rc = listen (s, options.backlog); if (rc != 0) return -1; - - return 0; + + return 0; } int zmq::ipc_listener_t::close () diff --git a/src/ipc_listener.hpp b/src/ipc_listener.hpp index 228e9f24..7f3047b3 100644 --- a/src/ipc_listener.hpp +++ b/src/ipc_listener.hpp @@ -50,7 +50,7 @@ namespace zmq int set_address (const char *addr_); // Get the bound address for use with wildcards - int get_address(std::string *addr_); + int get_address (std::string &addr_); private: diff --git a/src/socket_base.cpp b/src/socket_base.cpp index fc5f35bd..4dab68c4 100644 --- a/src/socket_base.cpp +++ b/src/socket_base.cpp @@ -324,7 +324,7 @@ int zmq::socket_base_t::bind (const char *addr_) // For convenience's sake, bind can be used interchageable with // connect for PGM and EPGM transports. - return connect (addr_); + return connect (addr_); } // Remaining trasnports require to be run in an I/O thread, so at this @@ -344,8 +344,8 @@ int zmq::socket_base_t::bind (const char *addr_) delete listener; return -1; } - - rc = listener->get_address (&options.last_endpoint); + + rc = listener->get_address (options.last_endpoint); launch_child (listener); return 0; } @@ -360,8 +360,8 @@ int zmq::socket_base_t::bind (const char *addr_) delete listener; return -1; } - - rc = listener->get_address (&options.last_endpoint); + + rc = listener->get_address (options.last_endpoint); launch_child (listener); return 0; } diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp index 7fc0203d..b9978d2f 100644 --- a/src/tcp_listener.cpp +++ b/src/tcp_listener.cpp @@ -120,7 +120,7 @@ void zmq::tcp_listener_t::close () s = retired_fd; } -int zmq::tcp_listener_t::get_address (std::string *addr_) +int zmq::tcp_listener_t::get_address (std::string &addr_) { struct sockaddr_storage ss; char host [NI_MAXHOST]; @@ -141,11 +141,17 @@ int zmq::tcp_listener_t::get_address (std::string *addr_) } if (ss.ss_family == AF_INET) { - address << "tcp://" << host << ":" << port; + struct sockaddr_in sa = {0}; + memcpy (&sa, &ss, sizeof (sa)); + + address << "tcp://" << host << ":" << ntohs (sa.sin_port); } else { - address << "tcp://[" << host << "]:" << port; + struct sockaddr_in6 sa = {0}; + memcpy (&sa, &ss, sizeof (sa)); + + address << "tcp://[" << host << "]:" << ntohs (sa.sin6_port); } - *addr_ = address.str (); + addr_ = address.str (); return 0; } diff --git a/src/tcp_listener.hpp b/src/tcp_listener.hpp index 66c4fb2e..3e286bed 100644 --- a/src/tcp_listener.hpp +++ b/src/tcp_listener.hpp @@ -46,7 +46,7 @@ namespace zmq int set_address (const char *addr_); // Get the bound address for use with wildcard - int get_address(std::string *addr_); + int get_address (std::string &addr_); private: diff --git a/tests/Makefile.am b/tests/Makefile.am index 3c46db69..6c270163 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -12,7 +12,8 @@ noinst_PROGRAMS = test_pair_inproc \ test_sub_forward \ test_invalid_rep \ test_msg_flags \ - test_connect_resolve + test_connect_resolve \ + test_last_endpoint if !ON_MINGW noinst_PROGRAMS += test_shutdown_stress \ @@ -31,6 +32,7 @@ test_sub_forward_SOURCES = test_sub_forward.cpp test_invalid_rep_SOURCES = test_invalid_rep.cpp test_msg_flags_SOURCES = test_msg_flags.cpp test_connect_resolve_SOURCES = test_connect_resolve.cpp +test_last_endpoint_SOURCES = test_last_endpoint.cpp if !ON_MINGW test_shutdown_stress_SOURCES = test_shutdown_stress.cpp diff --git a/tests/test_last_endpoint.cpp b/tests/test_last_endpoint.cpp new file mode 100644 index 00000000..657fcbb1 --- /dev/null +++ b/tests/test_last_endpoint.cpp @@ -0,0 +1,52 @@ +/* + Copyright (c) 2007-2012 iMatix Corporation + Copyright (c) 2011 250bpm s.r.o. + Copyright (c) 2007-2011 Other 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 +#include + +#include "../include/zmq.h" + +int main (int argc, char *argv []) +{ + // Create the infrastructure + void *ctx = zmq_init (1); + assert (ctx); + + void *sb = zmq_socket (ctx, ZMQ_XREP); + assert (sb); + int rc = zmq_bind (sb, "tcp://127.0.0.1:12345"); + assert (rc == 0); + + char test [255]; + size_t siz = 255; + rc = zmq_getsockopt (sb, ZMQ_LAST_ENDPOINT, test, &siz); + assert (rc == 0 && strcmp (test, "tcp://127.0.0.1:12345") == 0); + + rc = zmq_bind (sb, "tcp://127.0.0.1:54321"); + assert (rc == 0); + + siz = 255; + rc = zmq_getsockopt (sb, ZMQ_LAST_ENDPOINT, test, &siz); + assert (rc == 0 && strcmp (test, "tcp://127.0.0.1:54321") == 0); + + return 0 ; +} +