mirror of
https://github.com/zeromq/libzmq.git
synced 2025-01-14 01:37:56 +08:00
Problem: ipc transport not supported under Windows
Solution: implement support
This commit is contained in:
parent
a33f1101dc
commit
66d0f3511f
@ -193,6 +193,54 @@ set(API_POLLER "" CACHE STRING "Choose polling system for zmq_poll(er)_*. valid
|
|||||||
|
|
||||||
set(POLLER "" CACHE STRING "Choose polling system for I/O threads. valid values are
|
set(POLLER "" CACHE STRING "Choose polling system for I/O threads. valid values are
|
||||||
kqueue, epoll, devpoll, pollset, poll or select [default=autodetect]")
|
kqueue, epoll, devpoll, pollset, poll or select [default=autodetect]")
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
# from https://stackoverflow.com/a/40217291/2019765
|
||||||
|
macro(get_WIN32_WINNT version)
|
||||||
|
if (CMAKE_SYSTEM_VERSION)
|
||||||
|
set(ver ${CMAKE_SYSTEM_VERSION})
|
||||||
|
string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver})
|
||||||
|
string(REGEX MATCH "^([0-9]+)" verMajor ${ver})
|
||||||
|
# Check for Windows 10, b/c we'll need to convert to hex 'A'.
|
||||||
|
if ("${verMajor}" MATCHES "10")
|
||||||
|
set(verMajor "A")
|
||||||
|
string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver})
|
||||||
|
endif ("${verMajor}" MATCHES "10")
|
||||||
|
# Remove all remaining '.' characters.
|
||||||
|
string(REPLACE "." "" ver ${ver})
|
||||||
|
# Prepend each digit with a zero.
|
||||||
|
string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver})
|
||||||
|
set(${version} "0x${ver}")
|
||||||
|
endif(CMAKE_SYSTEM_VERSION)
|
||||||
|
endmacro(get_WIN32_WINNT)
|
||||||
|
|
||||||
|
get_WIN32_WINNT(ZMQ_WIN32_WINNT_DEFAULT)
|
||||||
|
message(STATUS "Detected _WIN32_WINNT from CMAKE_SYSTEM_VERSION: ${ZMQ_WIN32_WINNT_DEFAULT}")
|
||||||
|
|
||||||
|
# TODO limit _WIN32_WINNT to the actual Windows SDK version, which might be different from the default version installed with Visual Studio
|
||||||
|
if(MSVC_VERSION STREQUAL "1500" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.0")
|
||||||
|
set(ZMQ_WIN32_WINNT_LIMIT "0x0600")
|
||||||
|
elseif(MSVC_VERSION STREQUAL "1600" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.1")
|
||||||
|
set(ZMQ_WIN32_WINNT_LIMIT "0x0601")
|
||||||
|
elseif(MSVC_VERSION STREQUAL "1700" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.1")
|
||||||
|
set(ZMQ_WIN32_WINNT_LIMIT "0x0601")
|
||||||
|
elseif(MSVC_VERSION STREQUAL "1800" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.2")
|
||||||
|
set(ZMQ_WIN32_WINNT_LIMIT "0x0602")
|
||||||
|
endif()
|
||||||
|
if(ZMQ_WIN32_WINNT_LIMIT)
|
||||||
|
message(STATUS "Mismatch of Visual Studio Version (${MSVC_VERSION}) and CMAKE_SYSTEM_VERSION (${CMAKE_SYSTEM_VERSION}), limiting _WIN32_WINNT to ${ZMQ_WIN32_WINNT_LIMIT}, you may override this by setting ZMQ_WIN32_WINNT")
|
||||||
|
set(ZMQ_WIN32_WINNT_DEFAULT "${ZMQ_WIN32_WINNT_LIMIT}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(ZMQ_WIN32_WINNT "${ZMQ_WIN32_WINNT_DEFAULT}" CACHE STRING "Value to set _WIN32_WINNT to for building [default=autodetect from build environment]")
|
||||||
|
|
||||||
|
# On Windows Vista or greater, with MSVC 2013 or greater, default to epoll (which is required on Win 10 for ipc support)
|
||||||
|
if (ZMQ_WIN32_WINNT GREATER "0x05FF" AND MSVC_VERSION GREATER 1799 AND POLLER STREQUAL "")
|
||||||
|
set(POLLER "epoll")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-D_WIN32_WINNT=${ZMQ_WIN32_WINNT})
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
if(POLLER STREQUAL "")
|
if(POLLER STREQUAL "")
|
||||||
@ -294,48 +342,11 @@ if(NOT CYGWIN)
|
|||||||
check_include_files(windows.h ZMQ_HAVE_WINDOWS)
|
check_include_files(windows.h ZMQ_HAVE_WINDOWS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if(NOT WIN32)
|
||||||
# from https://stackoverflow.com/a/40217291/2019765
|
set(ZMQ_HAVE_IPC 1)
|
||||||
macro(get_WIN32_WINNT version)
|
else()
|
||||||
if (CMAKE_SYSTEM_VERSION)
|
check_include_files("winsock2.h;afunix.h" ZMQ_HAVE_IPC)
|
||||||
set(ver ${CMAKE_SYSTEM_VERSION})
|
endif()
|
||||||
string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver})
|
|
||||||
string(REGEX MATCH "^([0-9]+)" verMajor ${ver})
|
|
||||||
# Check for Windows 10, b/c we'll need to convert to hex 'A'.
|
|
||||||
if ("${verMajor}" MATCHES "10")
|
|
||||||
set(verMajor "A")
|
|
||||||
string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver})
|
|
||||||
endif ("${verMajor}" MATCHES "10")
|
|
||||||
# Remove all remaining '.' characters.
|
|
||||||
string(REPLACE "." "" ver ${ver})
|
|
||||||
# Prepend each digit with a zero.
|
|
||||||
string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver})
|
|
||||||
set(${version} "0x${ver}")
|
|
||||||
endif(CMAKE_SYSTEM_VERSION)
|
|
||||||
endmacro(get_WIN32_WINNT)
|
|
||||||
|
|
||||||
get_WIN32_WINNT(ZMQ_WIN32_WINNT_DEFAULT)
|
|
||||||
message(STATUS "Detected _WIN32_WINNT from CMAKE_SYSTEM_VERSION: ${ZMQ_WIN32_WINNT_DEFAULT}")
|
|
||||||
|
|
||||||
# TODO limit _WIN32_WINNT to the actual Windows SDK version, which might be different from the default version installed with Visual Studio
|
|
||||||
if(MSVC_VERSION STREQUAL "1500" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.0")
|
|
||||||
set(ZMQ_WIN32_WINNT_LIMIT "0x0600")
|
|
||||||
elseif(MSVC_VERSION STREQUAL "1600" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.1")
|
|
||||||
set(ZMQ_WIN32_WINNT_LIMIT "0x0601")
|
|
||||||
elseif(MSVC_VERSION STREQUAL "1700" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.1")
|
|
||||||
set(ZMQ_WIN32_WINNT_LIMIT "0x0601")
|
|
||||||
elseif(MSVC_VERSION STREQUAL "1800" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.2")
|
|
||||||
set(ZMQ_WIN32_WINNT_LIMIT "0x0602")
|
|
||||||
endif()
|
|
||||||
if(ZMQ_WIN32_WINNT_LIMIT)
|
|
||||||
message(STATUS "Mismatch of Visual Studio Version (${MSVC_VERSION}) and CMAKE_SYSTEM_VERSION (${CMAKE_SYSTEM_VERSION}), limiting _WIN32_WINNT to ${ZMQ_WIN32_WINNT_LIMIT}, you may override this by setting ZMQ_WIN32_WINNT")
|
|
||||||
set(ZMQ_WIN32_WINNT_DEFAULT "${ZMQ_WIN32_WINNT_LIMIT}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(ZMQ_WIN32_WINNT "${ZMQ_WIN32_WINNT_DEFAULT}" CACHE STRING "Value to set _WIN32_WINNT to for building [default=autodetect from build environment]")
|
|
||||||
|
|
||||||
add_definitions(-D_WIN32_WINNT=${ZMQ_WIN32_WINNT})
|
|
||||||
endif(WIN32)
|
|
||||||
|
|
||||||
###################### BEGIN condition_variable_t selection
|
###################### BEGIN condition_variable_t selection
|
||||||
if(NOT ZMQ_CV_IMPL)
|
if(NOT ZMQ_CV_IMPL)
|
||||||
@ -438,6 +449,8 @@ if(NOT MSVC)
|
|||||||
check_cxx_symbol_exists(mkdtemp stdlib.h HAVE_MKDTEMP)
|
check_cxx_symbol_exists(mkdtemp stdlib.h HAVE_MKDTEMP)
|
||||||
check_cxx_symbol_exists(accept4 sys/socket.h HAVE_ACCEPT4)
|
check_cxx_symbol_exists(accept4 sys/socket.h HAVE_ACCEPT4)
|
||||||
check_cxx_symbol_exists(strnlen string.h HAVE_STRNLEN)
|
check_cxx_symbol_exists(strnlen string.h HAVE_STRNLEN)
|
||||||
|
else()
|
||||||
|
set(HAVE_STRNLEN 1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_definitions(-D_REENTRANT -D_THREAD_SAFE)
|
add_definitions(-D_REENTRANT -D_THREAD_SAFE)
|
||||||
|
@ -51,6 +51,8 @@
|
|||||||
#cmakedefine HAVE_ACCEPT4
|
#cmakedefine HAVE_ACCEPT4
|
||||||
#cmakedefine HAVE_STRNLEN
|
#cmakedefine HAVE_STRNLEN
|
||||||
|
|
||||||
|
#cmakedefine ZMQ_HAVE_IPC
|
||||||
|
|
||||||
#cmakedefine ZMQ_USE_BUILTIN_SHA1
|
#cmakedefine ZMQ_USE_BUILTIN_SHA1
|
||||||
#cmakedefine ZMQ_USE_NSS
|
#cmakedefine ZMQ_USE_NSS
|
||||||
#cmakedefine ZMQ_HAVE_WS
|
#cmakedefine ZMQ_HAVE_WS
|
||||||
@ -104,8 +106,10 @@
|
|||||||
#define ZMQ_HAVE_OPENBSD
|
#define ZMQ_HAVE_OPENBSD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO better move OS-specific defines to the automake files, and check for availability of IPC with an explicit test there
|
||||||
#if defined __VMS
|
#if defined __VMS
|
||||||
#define ZMQ_HAVE_OPENVMS
|
#define ZMQ_HAVE_OPENVMS
|
||||||
|
#undef ZMQ_HAVE_IPC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined __APPLE__
|
#if defined __APPLE__
|
||||||
|
@ -143,6 +143,15 @@ if test "x$zmq_militant" = "xyes"; then
|
|||||||
AC_DEFINE(ZMQ_ACT_MILITANT, 1, [Enable militant API assertions])
|
AC_DEFINE(ZMQ_ACT_MILITANT, 1, [Enable militant API assertions])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# IPC is available on all platforms supported by autotools build at the moment except OpenVMS and VxWorks.
|
||||||
|
case "${host_os}" in
|
||||||
|
*vxworks*|*openvms*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_DEFINE(ZMQ_HAVE_IPC, 1, [Have AF_UNIX sockets for ipc transport])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# Memory mis-use detection
|
# Memory mis-use detection
|
||||||
AC_MSG_CHECKING([whether to enable ASan])
|
AC_MSG_CHECKING([whether to enable ASan])
|
||||||
AC_ARG_ENABLE(address-sanitizer, [AS_HELP_STRING([--enable-address-sanitizer=yes/no],
|
AC_ARG_ENABLE(address-sanitizer, [AS_HELP_STRING([--enable-address-sanitizer=yes/no],
|
||||||
|
@ -74,8 +74,7 @@ zmq::address_t::~address_t ()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
else if (protocol == protocol_name::ipc) {
|
else if (protocol == protocol_name::ipc) {
|
||||||
LIBZMQ_DELETE (resolved.ipc_addr);
|
LIBZMQ_DELETE (resolved.ipc_addr);
|
||||||
}
|
}
|
||||||
@ -106,8 +105,7 @@ int zmq::address_t::to_string (std::string &addr_) const
|
|||||||
if (protocol == protocol_name::wss && resolved.ws_addr)
|
if (protocol == protocol_name::wss && resolved.ws_addr)
|
||||||
return resolved.ws_addr->to_string (addr_);
|
return resolved.ws_addr->to_string (addr_);
|
||||||
#endif
|
#endif
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
if (protocol == protocol_name::ipc && resolved.ipc_addr)
|
if (protocol == protocol_name::ipc && resolved.ipc_addr)
|
||||||
return resolved.ipc_addr->to_string (addr_);
|
return resolved.ipc_addr->to_string (addr_);
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,7 +46,7 @@ class ctx_t;
|
|||||||
class tcp_address_t;
|
class tcp_address_t;
|
||||||
class udp_address_t;
|
class udp_address_t;
|
||||||
class ws_address_t;
|
class ws_address_t;
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
|
#if defined ZMQ_HAVE_IPC
|
||||||
class ipc_address_t;
|
class ipc_address_t;
|
||||||
#endif
|
#endif
|
||||||
#if defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_VXWORKS
|
#if defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_VXWORKS
|
||||||
@ -67,8 +67,7 @@ static const char ws[] = "ws";
|
|||||||
#ifdef ZMQ_HAVE_WSS
|
#ifdef ZMQ_HAVE_WSS
|
||||||
static const char wss[] = "wss";
|
static const char wss[] = "wss";
|
||||||
#endif
|
#endif
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
static const char ipc[] = "ipc";
|
static const char ipc[] = "ipc";
|
||||||
#endif
|
#endif
|
||||||
#if defined ZMQ_HAVE_TIPC
|
#if defined ZMQ_HAVE_TIPC
|
||||||
@ -101,8 +100,7 @@ struct address_t
|
|||||||
#ifdef ZMQ_HAVE_WS
|
#ifdef ZMQ_HAVE_WS
|
||||||
ws_address_t *ws_addr;
|
ws_address_t *ws_addr;
|
||||||
#endif
|
#endif
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
ipc_address_t *ipc_addr;
|
ipc_address_t *ipc_addr;
|
||||||
#endif
|
#endif
|
||||||
#if defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_VXWORKS
|
#if defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_VXWORKS
|
||||||
|
@ -30,8 +30,7 @@
|
|||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "ipc_address.hpp"
|
#include "ipc_address.hpp"
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
|
|
||||||
#include "err.hpp"
|
#include "err.hpp"
|
||||||
|
|
||||||
@ -86,7 +85,8 @@ int zmq::ipc_address_t::resolve (const char *path_)
|
|||||||
if (path_[0] == '@')
|
if (path_[0] == '@')
|
||||||
*_address.sun_path = '\0';
|
*_address.sun_path = '\0';
|
||||||
|
|
||||||
_addrlen = offsetof (sockaddr_un, sun_path) + path_len;
|
_addrlen =
|
||||||
|
static_cast<socklen_t> (offsetof (sockaddr_un, sun_path) + path_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,11 +32,14 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
|
|
||||||
|
#if defined _MSC_VER
|
||||||
|
#include <afunix.h>
|
||||||
|
#else
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace zmq
|
namespace zmq
|
||||||
{
|
{
|
||||||
@ -58,7 +61,7 @@ class ipc_address_t
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct sockaddr_un _address;
|
struct sockaddr_un _address;
|
||||||
size_t _addrlen;
|
socklen_t _addrlen;
|
||||||
|
|
||||||
ipc_address_t (const ipc_address_t &);
|
ipc_address_t (const ipc_address_t &);
|
||||||
const ipc_address_t &operator= (const ipc_address_t &);
|
const ipc_address_t &operator= (const ipc_address_t &);
|
||||||
|
@ -30,8 +30,7 @@
|
|||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "ipc_connecter.hpp"
|
#include "ipc_connecter.hpp"
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -44,11 +43,14 @@
|
|||||||
#include "ipc_address.hpp"
|
#include "ipc_address.hpp"
|
||||||
#include "session_base.hpp"
|
#include "session_base.hpp"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <afunix.h>
|
||||||
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
zmq::ipc_connecter_t::ipc_connecter_t (class io_thread_t *io_thread_,
|
zmq::ipc_connecter_t::ipc_connecter_t (class io_thread_t *io_thread_,
|
||||||
class session_base_t *session_,
|
class session_base_t *session_,
|
||||||
@ -127,12 +129,19 @@ int zmq::ipc_connecter_t::open ()
|
|||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Translate other error codes indicating asynchronous connect has been
|
// Translate other error codes indicating asynchronous connect has been
|
||||||
// launched to a uniform EINPROGRESS.
|
// launched to a uniform EINPROGRESS.
|
||||||
|
#ifdef ZMQ_HAVE_WINDOWS
|
||||||
|
const int last_error = WSAGetLastError ();
|
||||||
|
if (last_error == WSAEINPROGRESS || last_error == WSAEWOULDBLOCK)
|
||||||
|
errno = EINPROGRESS;
|
||||||
|
else
|
||||||
|
errno = wsa_error_to_errno (last_error);
|
||||||
|
#else
|
||||||
if (rc == -1 && errno == EINTR) {
|
if (rc == -1 && errno == EINTR) {
|
||||||
errno = EINPROGRESS;
|
errno = EINPROGRESS;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Forward the error.
|
// Forward the error.
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -30,8 +30,7 @@
|
|||||||
#ifndef __IPC_CONNECTER_HPP_INCLUDED__
|
#ifndef __IPC_CONNECTER_HPP_INCLUDED__
|
||||||
#define __IPC_CONNECTER_HPP_INCLUDED__
|
#define __IPC_CONNECTER_HPP_INCLUDED__
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
|
|
||||||
#include "fd.hpp"
|
#include "fd.hpp"
|
||||||
#include "stream_connecter_base.hpp"
|
#include "stream_connecter_base.hpp"
|
||||||
|
@ -30,8 +30,7 @@
|
|||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "ipc_listener.hpp"
|
#include "ipc_listener.hpp"
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
@ -45,11 +44,26 @@
|
|||||||
#include "socket_base.hpp"
|
#include "socket_base.hpp"
|
||||||
#include "address.hpp"
|
#include "address.hpp"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#ifdef ZMQ_IOTHREAD_POLLER_USE_SELECT
|
||||||
|
#error On Windows, IPC does not work with POLLER=select, use POLLER=epoll instead, or disable IPC transport
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <afunix.h>
|
||||||
|
#include <direct.h>
|
||||||
|
|
||||||
|
#define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR)
|
||||||
|
|
||||||
|
#define rmdir _rmdir
|
||||||
|
#define unlink _unlink
|
||||||
|
|
||||||
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#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>
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ZMQ_HAVE_LOCAL_PEERCRED
|
#ifdef ZMQ_HAVE_LOCAL_PEERCRED
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -69,10 +83,26 @@ 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 &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;
|
std::string tmp_path;
|
||||||
|
|
||||||
// If TMPDIR, TEMPDIR, or TMP are available and are directories, create
|
// If TMPDIR, TEMPDIR, or TMP are available and are directories, create
|
||||||
@ -102,7 +132,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[0], tmp_path.c_str ());
|
strcpy (&buffer[0], tmp_path.c_str ());
|
||||||
|
|
||||||
#ifdef HAVE_MKDTEMP
|
#if defined 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
|
||||||
@ -123,6 +153,7 @@ int zmq::ipc_listener_t::create_wildcard_address (std::string &path_,
|
|||||||
::close (fd);
|
::close (fd);
|
||||||
|
|
||||||
file_.assign (&buffer[0]);
|
file_.assign (&buffer[0]);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -202,7 +233,7 @@ int zmq::ipc_listener_t::set_local_address (const char *addr_)
|
|||||||
} else {
|
} else {
|
||||||
// Create a listening socket.
|
// Create a listening socket.
|
||||||
_s = open_socket (AF_UNIX, SOCK_STREAM, 0);
|
_s = open_socket (AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (_s == -1) {
|
if (_s == retired_fd) {
|
||||||
if (!_tmp_socket_dirname.empty ()) {
|
if (!_tmp_socket_dirname.empty ()) {
|
||||||
// We need to preserve errno to return to the user
|
// We need to preserve errno to return to the user
|
||||||
int tmp_errno = errno;
|
int tmp_errno = errno;
|
||||||
@ -242,9 +273,14 @@ error:
|
|||||||
int zmq::ipc_listener_t::close ()
|
int zmq::ipc_listener_t::close ()
|
||||||
{
|
{
|
||||||
zmq_assert (_s != retired_fd);
|
zmq_assert (_s != retired_fd);
|
||||||
int fd_for_event = _s;
|
fd_t fd_for_event = _s;
|
||||||
|
#ifdef ZMQ_HAVE_WINDOWS
|
||||||
|
int rc = closesocket (_s);
|
||||||
|
wsa_assert (rc != SOCKET_ERROR);
|
||||||
|
#else
|
||||||
int rc = ::close (_s);
|
int rc = ::close (_s);
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
_s = retired_fd;
|
_s = retired_fd;
|
||||||
|
|
||||||
@ -352,12 +388,27 @@ zmq::fd_t zmq::ipc_listener_t::accept ()
|
|||||||
#if defined ZMQ_HAVE_SOCK_CLOEXEC && defined HAVE_ACCEPT4
|
#if defined ZMQ_HAVE_SOCK_CLOEXEC && defined HAVE_ACCEPT4
|
||||||
fd_t sock = ::accept4 (_s, NULL, NULL, SOCK_CLOEXEC);
|
fd_t sock = ::accept4 (_s, NULL, NULL, SOCK_CLOEXEC);
|
||||||
#else
|
#else
|
||||||
fd_t sock = ::accept (_s, NULL, NULL);
|
struct sockaddr_storage ss;
|
||||||
|
memset (&ss, 0, sizeof (ss));
|
||||||
|
#if defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_VXWORKS
|
||||||
|
int ss_len = sizeof (ss);
|
||||||
|
#else
|
||||||
|
socklen_t ss_len = sizeof (ss);
|
||||||
#endif
|
#endif
|
||||||
if (sock == -1) {
|
|
||||||
|
fd_t sock =
|
||||||
|
::accept (_s, reinterpret_cast<struct sockaddr *> (&ss), &ss_len);
|
||||||
|
#endif
|
||||||
|
if (sock == retired_fd) {
|
||||||
|
#if defined ZMQ_HAVE_WINDOWS
|
||||||
|
const int last_error = WSAGetLastError ();
|
||||||
|
wsa_assert (last_error == WSAEWOULDBLOCK || last_error == WSAECONNRESET
|
||||||
|
|| last_error == WSAEMFILE || last_error == WSAENOBUFS);
|
||||||
|
#else
|
||||||
errno_assert (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR
|
errno_assert (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR
|
||||||
|| errno == ECONNABORTED || errno == EPROTO
|
|| errno == ECONNABORTED || errno == EPROTO
|
||||||
|| errno == ENFILE);
|
|| errno == ENFILE);
|
||||||
|
#endif
|
||||||
return retired_fd;
|
return retired_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,7 @@
|
|||||||
#ifndef __ZMQ_IPC_LISTENER_HPP_INCLUDED__
|
#ifndef __ZMQ_IPC_LISTENER_HPP_INCLUDED__
|
||||||
#define __ZMQ_IPC_LISTENER_HPP_INCLUDED__
|
#define __ZMQ_IPC_LISTENER_HPP_INCLUDED__
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -77,7 +76,7 @@ class ipc_listener_t : public stream_listener_base_t
|
|||||||
bool _has_file;
|
bool _has_file;
|
||||||
|
|
||||||
// Name of the temporary directory (if any) that has the
|
// Name of the temporary directory (if any) that has the
|
||||||
// the UNIX domain socket
|
// UNIX domain socket
|
||||||
std::string _tmp_socket_dirname;
|
std::string _tmp_socket_dirname;
|
||||||
|
|
||||||
// Name of the file associated with the UNIX domain address.
|
// Name of the file associated with the UNIX domain address.
|
||||||
|
@ -576,8 +576,7 @@ zmq::session_base_t::connecter_factory_entry_t
|
|||||||
connecter_factory_entry_t (protocol_name::wss,
|
connecter_factory_entry_t (protocol_name::wss,
|
||||||
&zmq::session_base_t::create_connecter_wss),
|
&zmq::session_base_t::create_connecter_wss),
|
||||||
#endif
|
#endif
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
connecter_factory_entry_t (protocol_name::ipc,
|
connecter_factory_entry_t (protocol_name::ipc,
|
||||||
&zmq::session_base_t::create_connecter_ipc),
|
&zmq::session_base_t::create_connecter_ipc),
|
||||||
#endif
|
#endif
|
||||||
@ -668,8 +667,7 @@ zmq::own_t *zmq::session_base_t::create_connecter_tipc (io_thread_t *io_thread_,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
zmq::own_t *zmq::session_base_t::create_connecter_ipc (io_thread_t *io_thread_,
|
zmq::own_t *zmq::session_base_t::create_connecter_ipc (io_thread_t *io_thread_,
|
||||||
bool wait_)
|
bool wait_)
|
||||||
{
|
{
|
||||||
|
@ -330,8 +330,7 @@ int zmq::socket_base_t::check_protocol (const std::string &protocol_) const
|
|||||||
{
|
{
|
||||||
// First check out whether the protocol is something we are aware of.
|
// First check out whether the protocol is something we are aware of.
|
||||||
if (protocol_ != protocol_name::inproc
|
if (protocol_ != protocol_name::inproc
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
&& protocol_ != protocol_name::ipc
|
&& protocol_ != protocol_name::ipc
|
||||||
#endif
|
#endif
|
||||||
&& protocol_ != protocol_name::tcp
|
&& protocol_ != protocol_name::tcp
|
||||||
@ -666,8 +665,7 @@ int zmq::socket_base_t::bind (const char *endpoint_uri_)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
if (protocol == protocol_name::ipc) {
|
if (protocol == protocol_name::ipc) {
|
||||||
ipc_listener_t *listener =
|
ipc_listener_t *listener =
|
||||||
new (std::nothrow) ipc_listener_t (io_thread, this, options);
|
new (std::nothrow) ipc_listener_t (io_thread, this, options);
|
||||||
@ -920,8 +918,7 @@ int zmq::socket_base_t::connect (const char *endpoint_uri_)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS \
|
#if defined ZMQ_HAVE_IPC
|
||||||
&& !defined ZMQ_HAVE_VXWORKS
|
|
||||||
else if (protocol == protocol_name::ipc) {
|
else if (protocol == protocol_name::ipc) {
|
||||||
paddr->resolved.ipc_addr = new (std::nothrow) ipc_address_t ();
|
paddr->resolved.ipc_addr = new (std::nothrow) ipc_address_t ();
|
||||||
alloc_assert (paddr->resolved.ipc_addr);
|
alloc_assert (paddr->resolved.ipc_addr);
|
||||||
|
@ -1449,7 +1449,7 @@ int zmq_device (int /* type */, void *frontend_, void *backend_)
|
|||||||
|
|
||||||
int zmq_has (const char *capability_)
|
int zmq_has (const char *capability_)
|
||||||
{
|
{
|
||||||
#if !defined(ZMQ_HAVE_WINDOWS) && !defined(ZMQ_HAVE_OPENVMS)
|
#if defined(ZMQ_HAVE_IPC)
|
||||||
if (strcmp (capability_, zmq::protocol_name::ipc) == 0)
|
if (strcmp (capability_, zmq::protocol_name::ipc) == 0)
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
@ -95,12 +95,17 @@ else()
|
|||||||
message(STATUS "capsh not found, skipping tests that require CAP_NET_ADMIN")
|
message(STATUS "capsh not found, skipping tests that require CAP_NET_ADMIN")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT WIN32)
|
if(ZMQ_HAVE_IPC)
|
||||||
list(APPEND tests
|
list(APPEND tests
|
||||||
test_ipc_wildcard
|
test_ipc_wildcard
|
||||||
test_pair_ipc
|
test_pair_ipc
|
||||||
test_rebind_ipc
|
|
||||||
test_reqrep_ipc
|
test_reqrep_ipc
|
||||||
|
test_rebind_ipc
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
list(APPEND tests
|
||||||
test_proxy
|
test_proxy
|
||||||
test_proxy_hwm
|
test_proxy_hwm
|
||||||
test_proxy_single_socket
|
test_proxy_single_socket
|
||||||
|
@ -34,7 +34,7 @@ SETUP_TEARDOWN_TESTCONTEXT
|
|||||||
|
|
||||||
void test_rebind_ipc ()
|
void test_rebind_ipc ()
|
||||||
{
|
{
|
||||||
char my_endpoint[32];
|
char my_endpoint[MAX_SOCKET_STRING];
|
||||||
make_random_ipc_endpoint (my_endpoint);
|
make_random_ipc_endpoint (my_endpoint);
|
||||||
|
|
||||||
void *sb0 = test_context_socket (ZMQ_PUSH);
|
void *sb0 = test_context_socket (ZMQ_PUSH);
|
||||||
|
@ -58,7 +58,7 @@ void test_reconnect_ivl_against_pair_socket (const char *my_endpoint_,
|
|||||||
test_context_socket_close (sc);
|
test_context_socket_close (sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(ZMQ_HAVE_WINDOWS) && !defined(ZMQ_HAVE_GNU)
|
#if defined(ZMQ_HAVE_IPC) && !defined(ZMQ_HAVE_GNU)
|
||||||
void test_reconnect_ivl_ipc (void)
|
void test_reconnect_ivl_ipc (void)
|
||||||
{
|
{
|
||||||
char my_endpoint[256];
|
char my_endpoint[256];
|
||||||
|
@ -31,7 +31,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifdef _WIN32
|
||||||
|
#include <direct.h>
|
||||||
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -288,9 +290,24 @@ void bind_loopback_tipc (void *socket_, char *my_endpoint_, size_t len_)
|
|||||||
test_bind (socket_, "tipc://<*>", my_endpoint_, len_);
|
test_bind (socket_, "tipc://<*>", my_endpoint_, len_);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(ZMQ_HAVE_WINDOWS) && !defined(ZMQ_HAVE_GNU)
|
#if defined(ZMQ_HAVE_IPC) && !defined(ZMQ_HAVE_GNU)
|
||||||
void make_random_ipc_endpoint (char *out_endpoint_)
|
void make_random_ipc_endpoint (char *out_endpoint_)
|
||||||
{
|
{
|
||||||
|
#ifdef ZMQ_HAVE_WINDOWS
|
||||||
|
char random_file[MAX_PATH];
|
||||||
|
|
||||||
|
{
|
||||||
|
const errno_t rc = tmpnam_s (random_file);
|
||||||
|
TEST_ASSERT_EQUAL (0, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO or use CreateDirectoryA and specify permissions?
|
||||||
|
const int rc = _mkdir (random_file);
|
||||||
|
TEST_ASSERT_EQUAL (0, rc);
|
||||||
|
|
||||||
|
strcat (random_file, "/ipc");
|
||||||
|
|
||||||
|
#else
|
||||||
char random_file[16];
|
char random_file[16];
|
||||||
strcpy (random_file, "tmpXXXXXX");
|
strcpy (random_file, "tmpXXXXXX");
|
||||||
|
|
||||||
@ -301,6 +318,7 @@ void make_random_ipc_endpoint (char *out_endpoint_)
|
|||||||
int fd = mkstemp (random_file);
|
int fd = mkstemp (random_file);
|
||||||
TEST_ASSERT_TRUE (fd != -1);
|
TEST_ASSERT_TRUE (fd != -1);
|
||||||
close (fd);
|
close (fd);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strcpy (out_endpoint_, "ipc://");
|
strcpy (out_endpoint_, "ipc://");
|
||||||
|
@ -256,7 +256,7 @@ void bind_loopback_ipc (void *socket_, char *my_endpoint_, size_t len_);
|
|||||||
// Binds to an ipc endpoint using the tipc wildcard address.
|
// Binds to an ipc endpoint using the tipc wildcard address.
|
||||||
void bind_loopback_tipc (void *socket_, char *my_endpoint_, size_t len_);
|
void bind_loopback_tipc (void *socket_, char *my_endpoint_, size_t len_);
|
||||||
|
|
||||||
#if !defined(ZMQ_HAVE_WINDOWS) && !defined(ZMQ_HAVE_GNU)
|
#if defined(ZMQ_HAVE_IPC) && !defined(ZMQ_HAVE_GNU)
|
||||||
// utility function to create a random IPC endpoint, similar to what a ipc://*
|
// utility function to create a random IPC endpoint, similar to what a ipc://*
|
||||||
// wildcard binding does, but in a way it can be reused for multiple binds
|
// wildcard binding does, but in a way it can be reused for multiple binds
|
||||||
// TODO also add a len parameter here
|
// TODO also add a len parameter here
|
||||||
|
Loading…
x
Reference in New Issue
Block a user