Problem: Using non-ascii characters in unix domain socket path doesn'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.
This commit is contained in:
Denis Zibarev 2023-12-06 09:27:26 +08:00 committed by Luca Boccassi
parent 665d1d4657
commit 86a42e1e43
3 changed files with 43 additions and 4 deletions

View File

@ -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

View File

@ -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>

View File

@ -28,6 +28,8 @@
#include <windows.h>
#include <mswsock.h>
#include <iphlpapi.h>
#include <string>
#include <vector>
#if !defined __MINGW32__
#include <mstcpip.h>
@ -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 (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