Commit bd4c2d60 authored by Simon Giesecke's avatar Simon Giesecke

Problem: zmq::listener_t::create_wildcard_address not reusable in ip.cpp

Solution: move to ip.hpp as zmq::create_ipc_wildcard_address
parent 3bcaea53
...@@ -38,11 +38,18 @@ ...@@ -38,11 +38,18 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <stdlib.h>
#include <unistd.h>
#include <vector>
#else #else
#include "tcp.hpp" #include "tcp.hpp"
#include <direct.h>
#endif #endif
#if defined ZMQ_HAVE_OPENVMS || defined ZMQ_HAVE_VXWORKS #if defined ZMQ_HAVE_OPENVMS || defined ZMQ_HAVE_VXWORKS
...@@ -71,6 +78,14 @@ ...@@ -71,6 +78,14 @@
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
#ifndef ZMQ_HAVE_WINDOWS
// Acceptable temporary directory environment variables
static const char *tmp_env_vars[] = {
"TMPDIR", "TEMPDIR", "TMP",
0 // Sentinel
};
#endif
zmq::fd_t zmq::open_socket (int domain_, int type_, int protocol_) zmq::fd_t zmq::open_socket (int domain_, int type_, int protocol_)
{ {
int rc; int rc;
...@@ -730,3 +745,80 @@ void zmq::assert_success_or_recoverable (zmq::fd_t s_, int rc_) ...@@ -730,3 +745,80 @@ void zmq::assert_success_or_recoverable (zmq::fd_t s_, int rc_)
} }
#endif #endif
} }
#ifdef ZMQ_HAVE_IPC
int zmq::create_ipc_wildcard_address (std::string &path_, std::string &file_)
{
#if defined ZMQ_HAVE_WINDOWS
char buffer[MAX_PATH];
{
const errno_t rc = tmpnam_s (buffer);
errno_assert (rc == 0);
}
// TODO or use CreateDirectoryA and specify permissions?
const int rc = _mkdir (buffer);
if (rc != 0) {
return -1;
}
path_.assign (buffer);
file_ = path_ + "/socket";
#else
std::string tmp_path;
// If TMPDIR, TEMPDIR, or TMP are available and are directories, create
// the socket directory there.
const char **tmp_env = tmp_env_vars;
while (tmp_path.empty () && *tmp_env != 0) {
char *tmpdir = getenv (*tmp_env);
struct stat statbuf;
// Confirm it is actually a directory before trying to use
if (tmpdir != 0 && ::stat (tmpdir, &statbuf) == 0
&& S_ISDIR (statbuf.st_mode)) {
tmp_path.assign (tmpdir);
if (*(tmp_path.rbegin ()) != '/') {
tmp_path.push_back ('/');
}
}
// Try the next environment variable
++tmp_env;
}
// Append a directory name
tmp_path.append ("tmpXXXXXX");
// We need room for tmp_path + trailing NUL
std::vector<char> buffer (tmp_path.length () + 1);
strcpy (&buffer[0], tmp_path.c_str ());
#if defined HAVE_MKDTEMP
// Create the directory. POSIX requires that mkdtemp() creates the
// directory with 0700 permissions, meaning the only possible race
// with socket creation could be the same user. However, since
// each socket is created in a directory created by mkdtemp(), and
// mkdtemp() guarantees a unique directory name, there will be no
// collision.
if (mkdtemp (&buffer[0]) == 0) {
return -1;
}
path_.assign (&buffer[0]);
file_ = path_ + "/socket";
#else
LIBZMQ_UNUSED (path_);
int fd = mkstemp (&buffer[0]);
if (fd == -1)
return -1;
::close (fd);
file_.assign (&buffer[0]);
#endif
#endif
return 0;
}
#endif
...@@ -76,6 +76,11 @@ void make_socket_noninheritable (fd_t sock_); ...@@ -76,6 +76,11 @@ void make_socket_noninheritable (fd_t sock_);
// - an internal 0MQ error did not occur, // - an internal 0MQ error did not occur,
// - and, if a socket error occured, it can be recovered from. // - and, if a socket error occured, it can be recovered from.
void assert_success_or_recoverable (fd_t s_, int rc_); void assert_success_or_recoverable (fd_t s_, int rc_);
#ifdef ZMQ_HAVE_IPC
// Create an IPC wildcard path address
int create_ipc_wildcard_address (std::string &path_, std::string &file_);
#endif
} }
#endif #endif
...@@ -52,8 +52,6 @@ ...@@ -52,8 +52,6 @@
#include <afunix.h> #include <afunix.h>
#include <direct.h> #include <direct.h>
#define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR)
#define rmdir _rmdir #define rmdir _rmdir
#define unlink _unlink #define unlink _unlink
...@@ -62,7 +60,6 @@ ...@@ -62,7 +60,6 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/stat.h>
#endif #endif
#ifdef ZMQ_HAVE_LOCAL_PEERCRED #ifdef ZMQ_HAVE_LOCAL_PEERCRED
...@@ -78,87 +75,6 @@ ...@@ -78,87 +75,6 @@
#endif #endif
#endif #endif
const char *zmq::ipc_listener_t::tmp_env_vars[] = {
"TMPDIR", "TEMPDIR", "TMP",
0 // Sentinel
};
int zmq::ipc_listener_t::create_wildcard_address (std::string &path_,
std::string &file_)
{
#if defined ZMQ_HAVE_WINDOWS
char buffer[MAX_PATH];
{
const errno_t rc = tmpnam_s (buffer);
errno_assert (rc == 0);
}
// TODO or use CreateDirectoryA and specify permissions?
const int rc = _mkdir (buffer);
if (rc != 0) {
return -1;
}
path_.assign (buffer);
file_ = path_ + "/socket";
#else
std::string tmp_path;
// If TMPDIR, TEMPDIR, or TMP are available and are directories, create
// the socket directory there.
const char **tmp_env = tmp_env_vars;
while (tmp_path.empty () && *tmp_env != 0) {
char *tmpdir = getenv (*tmp_env);
struct stat statbuf;
// Confirm it is actually a directory before trying to use
if (tmpdir != 0 && ::stat (tmpdir, &statbuf) == 0
&& S_ISDIR (statbuf.st_mode)) {
tmp_path.assign (tmpdir);
if (*(tmp_path.rbegin ()) != '/') {
tmp_path.push_back ('/');
}
}
// Try the next environment variable
++tmp_env;
}
// Append a directory name
tmp_path.append ("tmpXXXXXX");
// We need room for tmp_path + trailing NUL
std::vector<char> buffer (tmp_path.length () + 1);
strcpy (&buffer[0], tmp_path.c_str ());
#if defined HAVE_MKDTEMP
// Create the directory. POSIX requires that mkdtemp() creates the
// directory with 0700 permissions, meaning the only possible race
// with socket creation could be the same user. However, since
// each socket is created in a directory created by mkdtemp(), and
// mkdtemp() guarantees a unique directory name, there will be no
// collision.
if (mkdtemp (&buffer[0]) == 0) {
return -1;
}
path_.assign (&buffer[0]);
file_ = path_ + "/socket";
#else
LIBZMQ_UNUSED (path_);
int fd = mkstemp (&buffer[0]);
if (fd == -1)
return -1;
::close (fd);
file_.assign (&buffer[0]);
#endif
#endif
return 0;
}
zmq::ipc_listener_t::ipc_listener_t (io_thread_t *io_thread_, zmq::ipc_listener_t::ipc_listener_t (io_thread_t *io_thread_,
socket_base_t *socket_, socket_base_t *socket_,
const options_t &options_) : const options_t &options_) :
...@@ -197,7 +113,7 @@ int zmq::ipc_listener_t::set_local_address (const char *addr_) ...@@ -197,7 +113,7 @@ int zmq::ipc_listener_t::set_local_address (const char *addr_)
// Allow wildcard file // Allow wildcard file
if (options.use_fd == -1 && addr[0] == '*') { if (options.use_fd == -1 && addr[0] == '*') {
if (create_wildcard_address (_tmp_socket_dirname, addr) < 0) { if (create_ipc_wildcard_address (_tmp_socket_dirname, addr) < 0) {
return -1; return -1;
} }
} }
......
...@@ -56,9 +56,6 @@ class ipc_listener_t : public stream_listener_base_t ...@@ -56,9 +56,6 @@ class ipc_listener_t : public stream_listener_base_t
// Handlers for I/O events. // Handlers for I/O events.
void in_event (); void in_event ();
// Create wildcard path address
static int create_wildcard_address (std::string &path_, std::string &file_);
// Filter new connections if the OS provides a mechanism to get // Filter new connections if the OS provides a mechanism to get
// the credentials of the peer process. Called from accept(). // the credentials of the peer process. Called from accept().
#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED #if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED
...@@ -82,9 +79,6 @@ class ipc_listener_t : public stream_listener_base_t ...@@ -82,9 +79,6 @@ class ipc_listener_t : public stream_listener_base_t
// Name of the file associated with the UNIX domain address. // Name of the file associated with the UNIX domain address.
std::string _filename; std::string _filename;
// Acceptable temporary directory environment variables
static const char *tmp_env_vars[];
ipc_listener_t (const ipc_listener_t &); ipc_listener_t (const ipc_listener_t &);
const ipc_listener_t &operator= (const ipc_listener_t &); const ipc_listener_t &operator= (const ipc_listener_t &);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment