From 2c44b805cf3af7dd910e819f277f28c294e445b0 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Mon, 18 May 2020 09:02:06 +0200 Subject: [PATCH] shared: use more portable path_open() method --- src/utils/conftree.cpp | 8 +++++--- src/utils/pathut.cpp | 24 ++++++++++++++++++++++++ src/utils/pathut.h | 1 + 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/utils/conftree.cpp b/src/utils/conftree.cpp index e5a33c57..9e172e76 100644 --- a/src/utils/conftree.cpp +++ b/src/utils/conftree.cpp @@ -234,7 +234,8 @@ ConfSimple::ConfSimple(const char *fname, int readonly, bool tildexp, if (!readonly && !path_exists(fname)) { mode |= ios::trunc; } - fstream input = path_open(fname, mode); + fstream input; + path_open(fname, mode, input); if (!input.is_open()) { LOGDEB0("ConfSimple::ConfSimple: fstream(w)(" << fname << ", " << mode << ") errno " << errno << "\n"); @@ -245,7 +246,7 @@ ConfSimple::ConfSimple(const char *fname, int readonly, bool tildexp, input.clear(); status = STATUS_RO; // open readonly - input = path_open(fname, ios::in); + path_open(fname, ios::in, input); } if (!input.is_open()) { @@ -577,7 +578,8 @@ bool ConfSimple::write() return true; } if (m_filename.length()) { - fstream output = path_open(m_filename, ios::out | ios::trunc); + fstream output; + path_open(m_filename, ios::out | ios::trunc, output); if (!output.is_open()) { return 0; } diff --git a/src/utils/pathut.cpp b/src/utils/pathut.cpp index 6a0bfb81..34ca05ef 100644 --- a/src/utils/pathut.cpp +++ b/src/utils/pathut.cpp @@ -836,6 +836,9 @@ bool path_makepath(const string& ipath, int mode) return true; } +#if !defined(__GNUC__) || __GNUC__ > 4 +// Not sure what g++ version supports fstream assignment but 4.9 +// (jessie) certainly does not std::fstream path_open(const std::string& path, int mode) { #if defined(_WIN32) && defined (_MSC_VER) @@ -853,6 +856,27 @@ std::fstream path_open(const std::string& path, int mode) return std::fstream(path, std::ios_base::openmode(mode)); #endif } +#endif + +bool path_open(const std::string& path, int mode, std::fstream& outstream) +{ +#if defined(_WIN32) && defined (_MSC_VER) + // MSC STL has support for using wide chars in fstream + // constructor. We need this if, e.g. the user name/home directory + // is not ASCII. Actually don't know how to do this with gcc + wchar_t wpath[MAX_PATH + 1]; + utf8towchar(path, wpath, MAX_PATH); + outstream.open(wpath, std::ios_base::openmode(mode)); + if (!outstream.is_open()) { + LOGERR("path_open("<< path << ", "<< mode <<") errno " << errno <<"\n"); + return false; + } + return true; +#else + outstream.open(path, std::ios_base::openmode(mode)); + return outstream.is_open(); +#endif +} bool path_isdir(const string& path, bool follow) { diff --git a/src/utils/pathut.h b/src/utils/pathut.h index 16d825f9..3bcfc874 100644 --- a/src/utils/pathut.h +++ b/src/utils/pathut.h @@ -147,6 +147,7 @@ extern bool path_makepath(const std::string& path, int mode); * @param path an utf-8 file path. * @param mode is an std::fstream mode (ios::in etc.) */ extern std::fstream path_open(const std::string& path, int mode); +extern bool path_open(const std::string& path, int mode, std::fstream& outstream); /// Where we create the user data subdirs extern std::string path_homedata();