Windows wide path conversions: don't use SYSPATH outside pathut.cpp
This commit is contained in:
parent
a15b2d5f45
commit
e8a5ee327d
@ -78,6 +78,7 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
@ -134,6 +135,10 @@
|
|||||||
#define RMDIR _wrmdir
|
#define RMDIR _wrmdir
|
||||||
#define CHDIR _wchdir
|
#define CHDIR _wchdir
|
||||||
|
|
||||||
|
#define SYSPATH(PATH, SPATH) wchar_t PATH ## _buf[2048]; \
|
||||||
|
utf8towchar(PATH, PATH ## _buf, 2048); \
|
||||||
|
wchar_t *SPATH = PATH ## _buf;
|
||||||
|
|
||||||
#define ftruncate _chsize_s
|
#define ftruncate _chsize_s
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -172,6 +177,9 @@
|
|||||||
#define RMDIR ::rmdir
|
#define RMDIR ::rmdir
|
||||||
#define CHDIR ::chdir
|
#define CHDIR ::chdir
|
||||||
|
|
||||||
|
#define SYSPATH(PATH, SPATH) const char *SPATH = PATH.c_str()
|
||||||
|
|
||||||
|
|
||||||
#endif /* !_WIN32 */
|
#endif /* !_WIN32 */
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -256,6 +264,31 @@ bool utf8towchar(const std::string& in, wchar_t *out, size_t obytescap)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<wchar_t[]> utf8towchar(const std::string& in)
|
||||||
|
{
|
||||||
|
// Note that as we supply in.size(), mbtowch computes the size
|
||||||
|
// without a terminating 0 (and won't write in the second call of
|
||||||
|
// course). We take this into account by allocating one more and
|
||||||
|
// terminating the output.
|
||||||
|
int wcharcnt = MultiByteToWideChar(
|
||||||
|
CP_UTF8, MB_ERR_INVALID_CHARS, in.c_str(), in.size(), nullptr, 0);
|
||||||
|
if (wcharcnt <= 0) {
|
||||||
|
LOGERR("utf8towchar: conversion error for [" << in << "]\n");
|
||||||
|
return std::unique_ptr<wchar_t[]>();
|
||||||
|
}
|
||||||
|
auto buf = unique_ptr<wchar_t[]>(new wchar_t[wcharcnt+1]);
|
||||||
|
|
||||||
|
wcharcnt = MultiByteToWideChar(
|
||||||
|
CP_UTF8, MB_ERR_INVALID_CHARS, in.c_str(), in.size(),
|
||||||
|
buf.get(), wcharcnt);
|
||||||
|
if (wcharcnt <= 0) {
|
||||||
|
LOGERR("utf8towchar: conversion error for [" << in << "]\n");
|
||||||
|
return std::unique_ptr<wchar_t[]>();
|
||||||
|
}
|
||||||
|
buf.get()[wcharcnt] = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert \ separators to /
|
/// Convert \ separators to /
|
||||||
void path_slashize(string& s)
|
void path_slashize(string& s)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -123,14 +123,10 @@ extern int path_fileprops(const std::string path, struct PathStat *stp,
|
|||||||
extern std::string path_PATHsep();
|
extern std::string path_PATHsep();
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern bool wchartoutf8(const wchar_t *in, std::string& out, size_t len = 0);
|
bool wchartoutf8(const wchar_t *in, std::string& out, size_t len = 0);
|
||||||
extern std::string wchartoutf8(const wchar_t *in, size_t len = 0);
|
std::string wchartoutf8(const wchar_t *in, size_t len = 0);
|
||||||
extern bool utf8towchar(const std::string& in, wchar_t *out, size_t obytescap);
|
bool utf8towchar(const std::string& in, wchar_t *out, size_t obytescap);
|
||||||
#define SYSPATH(PATH, SPATH) wchar_t PATH ## _buf[2048]; \
|
std::unique_ptr<wchar_t[]> utf8towchar(const std::string& in);
|
||||||
utf8towchar(PATH, PATH ## _buf, 2048); \
|
|
||||||
wchar_t *SPATH = PATH ## _buf;
|
|
||||||
#else
|
|
||||||
#define SYSPATH(PATH, SPATH) const char *SPATH = PATH.c_str()
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Directory reading interface. UTF-8 on Windows.
|
/// Directory reading interface. UTF-8 on Windows.
|
||||||
|
|||||||
@ -32,7 +32,6 @@
|
|||||||
#include "safefcntl.h"
|
#include "safefcntl.h"
|
||||||
#include "safesysstat.h"
|
#include "safesysstat.h"
|
||||||
#include "safeunistd.h"
|
#include "safeunistd.h"
|
||||||
#include "transcode.h"
|
|
||||||
#define OPEN _wopen
|
#define OPEN _wopen
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -333,7 +332,12 @@ public:
|
|||||||
|
|
||||||
// If we have a file name, open it, else use stdin.
|
// If we have a file name, open it, else use stdin.
|
||||||
if (!m_fn.empty()) {
|
if (!m_fn.empty()) {
|
||||||
SYSPATH(m_fn, realpath);
|
#ifdef _WIN32
|
||||||
|
auto buf = utf8towchar(m_fn);
|
||||||
|
auto realpath = buf.get();
|
||||||
|
#else
|
||||||
|
auto realpath = m_fn.c_str();
|
||||||
|
#endif
|
||||||
fd = OPEN(realpath, O_RDONLY | O_BINARY);
|
fd = OPEN(realpath, O_RDONLY | O_BINARY);
|
||||||
if (fd < 0 || fstat(fd, &st) < 0) {
|
if (fd < 0 || fstat(fd, &st) < 0) {
|
||||||
catstrerror(m_reason, "open/stat", errno);
|
catstrerror(m_reason, "open/stat", errno);
|
||||||
@ -440,7 +444,12 @@ public:
|
|||||||
if (m_fn.empty()) {
|
if (m_fn.empty()) {
|
||||||
ret1 = mz_zip_reader_init_mem(&zip, m_data, m_cnt, 0);
|
ret1 = mz_zip_reader_init_mem(&zip, m_data, m_cnt, 0);
|
||||||
} else {
|
} else {
|
||||||
SYSPATH(m_fn, realpath);
|
#ifdef _WIN32
|
||||||
|
auto buf = utf8towchar(m_fn);
|
||||||
|
auto realpath = buf.get();
|
||||||
|
#else
|
||||||
|
auto realpath = m_fn.c_str();
|
||||||
|
#endif
|
||||||
ret1 = mz_zip_reader_init_file(&zip, realpath, 0);
|
ret1 = mz_zip_reader_init_file(&zip, realpath, 0);
|
||||||
}
|
}
|
||||||
if (!ret1) {
|
if (!ret1) {
|
||||||
|
|||||||
@ -793,9 +793,9 @@ int ExecCmd::startExec(const string &cmd, const vector<string>& args,
|
|||||||
int flags = CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT;
|
int flags = CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT;
|
||||||
// Create the child process.
|
// Create the child process.
|
||||||
LOGDEB("ExecCmd:startExec: cmdline [" << cmdline << "]\n");
|
LOGDEB("ExecCmd:startExec: cmdline [" << cmdline << "]\n");
|
||||||
SYSPATH(cmdline, wcmdline);
|
auto wcmdline = utf8towchar(cmdline);
|
||||||
bSuccess = CreateProcessW(NULL, // app name
|
bSuccess = CreateProcessW(NULL, // app name
|
||||||
wcmdline, // command line
|
wcmdline.get(), // command line
|
||||||
NULL, // process security attributes
|
NULL, // process security attributes
|
||||||
NULL, // primary thread security attrs
|
NULL, // primary thread security attrs
|
||||||
TRUE, // handles are inherited
|
TRUE, // handles are inherited
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user