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 ;
+}
+