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>
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef _MSC_VER
|
||||
@ -134,6 +135,10 @@
|
||||
#define RMDIR _wrmdir
|
||||
#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
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -172,6 +177,9 @@
|
||||
#define RMDIR ::rmdir
|
||||
#define CHDIR ::chdir
|
||||
|
||||
#define SYSPATH(PATH, SPATH) const char *SPATH = PATH.c_str()
|
||||
|
||||
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
using namespace std;
|
||||
@ -256,6 +264,31 @@ bool utf8towchar(const std::string& in, wchar_t *out, size_t obytescap)
|
||||
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 /
|
||||
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();
|
||||
|
||||
#ifdef _WIN32
|
||||
extern 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);
|
||||
extern bool utf8towchar(const std::string& in, wchar_t *out, size_t obytescap);
|
||||
#define SYSPATH(PATH, SPATH) wchar_t PATH ## _buf[2048]; \
|
||||
utf8towchar(PATH, PATH ## _buf, 2048); \
|
||||
wchar_t *SPATH = PATH ## _buf;
|
||||
#else
|
||||
#define SYSPATH(PATH, SPATH) const char *SPATH = PATH.c_str()
|
||||
bool wchartoutf8(const wchar_t *in, std::string& out, size_t len = 0);
|
||||
std::string wchartoutf8(const wchar_t *in, size_t len = 0);
|
||||
bool utf8towchar(const std::string& in, wchar_t *out, size_t obytescap);
|
||||
std::unique_ptr<wchar_t[]> utf8towchar(const std::string& in);
|
||||
#endif
|
||||
|
||||
/// Directory reading interface. UTF-8 on Windows.
|
||||
|
||||
@ -32,7 +32,6 @@
|
||||
#include "safefcntl.h"
|
||||
#include "safesysstat.h"
|
||||
#include "safeunistd.h"
|
||||
#include "transcode.h"
|
||||
#define OPEN _wopen
|
||||
|
||||
#else
|
||||
@ -333,7 +332,12 @@ public:
|
||||
|
||||
// If we have a file name, open it, else use stdin.
|
||||
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);
|
||||
if (fd < 0 || fstat(fd, &st) < 0) {
|
||||
catstrerror(m_reason, "open/stat", errno);
|
||||
@ -440,7 +444,12 @@ public:
|
||||
if (m_fn.empty()) {
|
||||
ret1 = mz_zip_reader_init_mem(&zip, m_data, m_cnt, 0);
|
||||
} 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);
|
||||
}
|
||||
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;
|
||||
// Create the child process.
|
||||
LOGDEB("ExecCmd:startExec: cmdline [" << cmdline << "]\n");
|
||||
SYSPATH(cmdline, wcmdline);
|
||||
auto wcmdline = utf8towchar(cmdline);
|
||||
bSuccess = CreateProcessW(NULL, // app name
|
||||
wcmdline, // command line
|
||||
wcmdline.get(), // command line
|
||||
NULL, // process security attributes
|
||||
NULL, // primary thread security attrs
|
||||
TRUE, // handles are inherited
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user