pathut: path_chdir, more error checking in conversions

This commit is contained in:
Jean-Francois Dockes 2020-06-02 08:56:02 +01:00
parent 7ccde15839
commit 0f8b53d43b
2 changed files with 39 additions and 17 deletions

View File

@ -75,10 +75,6 @@
#ifdef _WIN32
#if !defined(S_IFLNK)
#define S_IFLNK 0
#endif
#ifndef _MSC_VER
#undef WINVER
#define WINVER 0x0601
@ -98,6 +94,10 @@
#include <io.h>
#include <sys/stat.h>
#if !defined(S_IFLNK)
#define S_IFLNK 0
#endif
#ifndef S_ISDIR
# define S_ISDIR(ST_MODE) (((ST_MODE) & _S_IFMT) == _S_IFDIR)
#endif
@ -122,6 +122,7 @@
#define MKDIR(a,b) _wmkdir(a)
#define OPEN ::_wopen
#define UNLINK _wunlink
#define CHDIR _wchdir
#define ftruncate _chsize_s
@ -153,7 +154,8 @@
#define MKDIR(a,b) mkdir(a,b)
#define O_BINARY 0
#define OPEN ::open
#define UNLINK unlink
#define UNLINK ::unlink
#define CHDIR ::chdir
#endif /* !_WIN32 */
@ -161,29 +163,39 @@ using namespace std;
#ifdef _WIN32
bool wchartoutf8(const wchar_t *in, std::string& out)
std::string wchartoutf8(const wchar_t *in, size_t len)
{
// fprintf(stderr, "WCHARTOUTF8: in [%S]\n", in);
std::string out;
wchartoutf8(in, out, len);
return out;
}
bool wchartoutf8(const wchar_t *in, std::string& out, size_t wlen)
{
LOGDEB1("WCHARTOUTF8: in [" << in << "]\n");
out.clear();
if (nullptr == in) {
return true;
}
size_t wlen = wcslen(in);
if (wlen == 0) {
wlen = wcslen(in);
}
int flags = WC_ERR_INVALID_CHARS|WC_NO_BEST_FIT_CHARS;
int bytes = ::WideCharToMultiByte(
CP_UTF8, WC_ERR_INVALID_CHARS, in, wlen, nullptr, 0, nullptr, nullptr);
CP_UTF8, flags, in, wlen, nullptr, 0, nullptr, nullptr);
if (bytes <= 0) {
std::cerr << "wchartoutf8: CONVERSION ERROR1\n";
LOGERR("wchartoutf8: conversion error1\n");
return false;
}
char *cp = (char *)malloc(bytes+1);
if (nullptr == cp) {
std::cerr << "wchartoutf8: MALLOC FAILED\n";
LOGERR("wchartoutf8: malloc failed\n");
return false;
}
bytes = ::WideCharToMultiByte(
CP_UTF8, WC_ERR_INVALID_CHARS, in, wlen, cp, bytes, nullptr, nullptr);
CP_UTF8, flags, in, wlen, cp, bytes, nullptr, nullptr);
if (bytes <= 0) {
std::cerr << "wchartoutf8: CONVERSION ERROR2\n";
LOGERR("wchartoutf8: CONVERSION ERROR2\n");
free(cp);
return false;
}
@ -204,17 +216,17 @@ bool utf8towchar(const std::string& in, wchar_t *out, size_t obytescap)
int wcharcnt = MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS, in.c_str(), in.size(), nullptr, 0);
if (wcharcnt <= 0) {
std::cerr << "utf8towchar: CONVERSION ERROR\n";
LOGERR("utf8towchar: conversion error for [" << in << "]\n");
return false;
}
if (wcharcnt + 1 > int(wcharsavail)) {
std::cerr << "utf8towchar: NOT ENOUGH SPACE\n";
LOGERR("utf8towchar: not enough space\n");
return false;
}
wcharcnt = MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS, in.c_str(), in.size(), out, wcharsavail);
if (wcharcnt <= 0) {
std::cerr << "utf8towchar: CONVERSION ERROR\n";
LOGERR("utf8towchar: conversion error for [" << in << "]\n");
return false;
}
out[wcharcnt] = 0;
@ -836,6 +848,12 @@ bool path_makepath(const string& ipath, int mode)
return true;
}
bool path_chdir(const std::string& path)
{
SYSPATH(path, syspath);
return CHDIR(syspath) == 0;
}
#if !defined(__GNUC__) || __GNUC__ > 4 || defined(__clang__)
// Not sure what g++ version supports fstream assignment but 4.9
// (jessie) certainly does not

View File

@ -109,7 +109,8 @@ extern bool path_readable(const std::string& path);
extern std::string path_PATHsep();
#ifdef _WIN32
extern bool wchartoutf8(const wchar_t *in, std::string& out);
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); \
@ -132,6 +133,9 @@ bool fsocc(const std::string& path, int *pc, long long *avmbs = 0);
/// mkdir -p
extern bool path_makepath(const std::string& path, int mode);
///
extern bool path_chdir(const std::string& path);
/* Open file, trying to do the right thing with non-ASCII paths on
* Windows, where it only works with MSVC at the moment if the path is
* not ASCII, because it uses fstream(wchar_t*), which is an MSVC