Skip to content

Commit

Permalink
Problem: Using non-ascii characters in unix domain socket path doesn'…
Browse files Browse the repository at this point in the history
…t work on Windows

Solution: Convert utf-8 socket paths to utf-16 file names when using
filesystem calls to delete files and directories as Windows doesn't
have any filesystem calls that take utf-8 path.

rmdir_utf8() and unlink_utf8() static functions were created which
substitute rmdir() and unlink() when building on Windows.
  • Loading branch information
dz-fsd committed Dec 11, 2023
1 parent 665d1d4 commit 3b9aa2f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/ip.cpp
Expand Up @@ -27,8 +27,8 @@

#include <direct.h>

#define rmdir _rmdir
#define unlink _unlink
#define rmdir rmdir_utf8
#define unlink unlink_utf8
#endif

#if defined ZMQ_HAVE_OPENVMS || defined ZMQ_HAVE_VXWORKS
Expand Down
4 changes: 2 additions & 2 deletions src/ipc_listener.cpp
Expand Up @@ -25,8 +25,8 @@
#include <afunix.h>
#include <direct.h>

#define rmdir _rmdir
#define unlink _unlink
#define rmdir rmdir_utf8
#define unlink unlink_utf8

#else
#include <unistd.h>
Expand Down
39 changes: 39 additions & 0 deletions src/windows.hpp
Expand Up @@ -28,6 +28,8 @@
#include <windows.h>
#include <mswsock.h>
#include <iphlpapi.h>
#include <string>
#include <vector>

#if !defined __MINGW32__
#include <mstcpip.h>
Expand Down Expand Up @@ -64,6 +66,43 @@ static inline int poll (struct pollfd *pfd, unsigned long nfds, int timeout)
#define AI_NUMERICSERV 0x0400
#endif

// Need unlink() and rmdir() functions that take utf-8 encoded file path.
static inline std::wstring utf8_to_utf16 (_In_z const char *utf8_string)
{
std::wstring retVal;

if (utf8_string && *utf8_string) {
const int utf16_length = ::MultiByteToWideChar (
CP_UTF8, MB_ERR_INVALID_CHARS, utf8_string,
-1, // assume the input string is null-terminated
NULL, 0);

if (utf16_length > 0) {
retVal.resize (utf16_length);

const int conversion_result = ::MultiByteToWideChar (
CP_UTF8, MB_ERR_INVALID_CHARS, utf8_string,
-1, // assume the input string is null-terminated
&retVal[0], static_cast<int> (retVal.size ()));

if (conversion_result == 0)
retVal.clear ();
}
}

return retVal;
}

static inline int unlink_utf8 (const char *filename)
{
return _wunlink (utf8_to_utf16 (filename).c_str ());
}

static inline int rmdir_utf8 (const char *filename)
{
return _wrmdir (utf8_to_utf16 (filename).c_str ());
}

// In MSVC prior to v14, snprintf is not available
// The closest implementation is the _snprintf_s function
#if defined(_MSC_VER) && _MSC_VER < 1900
Expand Down

0 comments on commit 3b9aa2f

Please sign in to comment.