Problem: mkdtemp not available on all platforms

Solution: check for availability in autoconf and cmake, and if not
available fall back to random file name rather than random directory.
This commit is contained in:
Luca Boccassi 2016-04-10 22:45:35 +01:00
parent 8028817f6b
commit f18463f323
5 changed files with 24 additions and 10 deletions

View File

@ -186,6 +186,10 @@ set (CMAKE_REQUIRED_INCLUDES sys/time.h)
check_function_exists (gethrtime HAVE_GETHRTIME) check_function_exists (gethrtime HAVE_GETHRTIME)
set (CMAKE_REQUIRED_INCLUDES) set (CMAKE_REQUIRED_INCLUDES)
set (CMAKE_REQUIRED_INCLUDES stdlib.h)
check_function_exists (mkdtemp HAVE_MKDTEMP)
set (CMAKE_REQUIRED_INCLUDES)
add_definitions (-D_REENTRANT -D_THREAD_SAFE) add_definitions (-D_REENTRANT -D_THREAD_SAFE)
add_definitions (-DZMQ_CUSTOM_PLATFORM_HPP) add_definitions (-DZMQ_CUSTOM_PLATFORM_HPP)

View File

@ -12,6 +12,7 @@
#cmakedefine HAVE_FORK #cmakedefine HAVE_FORK
#cmakedefine HAVE_CLOCK_GETTIME #cmakedefine HAVE_CLOCK_GETTIME
#cmakedefine HAVE_GETHRTIME #cmakedefine HAVE_GETHRTIME
#cmakedefine HAVE_MKDTEMP
#cmakedefine ZMQ_HAVE_UIO #cmakedefine ZMQ_HAVE_UIO
#cmakedefine ZMQ_HAVE_EVENTFD #cmakedefine ZMQ_HAVE_EVENTFD

View File

@ -561,7 +561,7 @@ AC_LANG_POP([C++])
# Checks for library functions. # Checks for library functions.
AC_TYPE_SIGNAL AC_TYPE_SIGNAL
AC_CHECK_FUNCS(perror gettimeofday clock_gettime memset socket getifaddrs freeifaddrs fork posix_memalign) AC_CHECK_FUNCS(perror gettimeofday clock_gettime memset socket getifaddrs freeifaddrs fork posix_memalign mkdtemp)
AC_CHECK_HEADERS([alloca.h]) AC_CHECK_HEADERS([alloca.h])
LIBZMQ_CHECK_SOCK_CLOEXEC([ LIBZMQ_CHECK_SOCK_CLOEXEC([

View File

@ -71,7 +71,8 @@ const char *zmq::ipc_listener_t::tmp_env_vars[] = {
0 // Sentinel 0 // Sentinel
}; };
int zmq::ipc_listener_t::create_wildcard_address(std::string& path_) int zmq::ipc_listener_t::create_wildcard_address(std::string& path_,
std::string& file_)
{ {
std::string tmp_path; std::string tmp_path;
@ -101,6 +102,7 @@ int zmq::ipc_listener_t::create_wildcard_address(std::string& path_)
std::vector<char> buffer(tmp_path.length()+1); std::vector<char> buffer(tmp_path.length()+1);
strcpy(buffer.data(), tmp_path.c_str()); strcpy(buffer.data(), tmp_path.c_str());
#ifdef HAVE_MKDTEMP
// Create the directory. POSIX requires that mkdtemp() creates the // Create the directory. POSIX requires that mkdtemp() creates the
// directory with 0700 permissions, meaning the only possible race // directory with 0700 permissions, meaning the only possible race
// with socket creation could be the same user. However, since // with socket creation could be the same user. However, since
@ -112,6 +114,18 @@ int zmq::ipc_listener_t::create_wildcard_address(std::string& path_)
} }
path_.assign(buffer.data()); path_.assign(buffer.data());
file_.assign (path_ + "/socket");
#else
// Silence -Wunused-parameter. #pragma and __attribute__((unused)) are not
// very portable unfortunately...
(void) path_;
int fd = mkstemp (buffer.data());
if (fd == -1)
return -1;
::close (fd);
file_.assign (buffer.data());
#endif
return 0; return 0;
} }
@ -201,15 +215,9 @@ int zmq::ipc_listener_t::set_address (const char *addr_)
// Allow wildcard file // Allow wildcard file
if (addr [0] == '*') { if (addr [0] == '*') {
std::string tmp_path; if ( create_wildcard_address(tmp_socket_dirname, addr) < 0 ) {
if ( create_wildcard_address(tmp_path) < 0 ) {
return -1; return -1;
} }
tmp_socket_dirname.assign(tmp_path);
addr.assign (tmp_path + "/socket");
} }
// Get rid of the file associated with the UNIX domain socket that // Get rid of the file associated with the UNIX domain socket that

View File

@ -74,7 +74,8 @@ namespace zmq
int close (); int close ();
// Create wildcard path address // Create wildcard path address
static int create_wildcard_address(std::string& path_); 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().