1
0
Fork 0

add symlinks for windows (#8846)

This commit is contained in:
Jan Christoph Uhde 2019-05-02 17:32:29 +02:00 committed by Jan
parent fb67de568e
commit e0b073543b
21 changed files with 201 additions and 122 deletions

View File

@ -179,7 +179,7 @@ if (WIN32)
-Dembedded_builtins_snapshot_src=
-Dv8_enable_handle_zapping=0
-Dv8_use_snapshot=0
-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
-DPYTHON_EXECUTABLE="${PYTHON_EXECUTABLE}"
-Dnode_use_pch=false
)
@ -203,7 +203,7 @@ if (WIN32)
SOURCE_DIR
"${V8_DIR}"
CONFIGURE_COMMAND
env GYP_MSVS_VERSION=${GYP_MSVS_VERSION} GYP_GENERATORS=${GYP_GENERATORS} GYP_MSVS_OVERRIDE_PATH=${GYP_MSVS_OVERRIDE_PATH} DEPOT_TOOLS_WIN_TOOLCHAIN=${DEPOT_TOOLS_WIN_TOOLCHAIN} ${PYTHON_EXECUTABLE} ${GYP_MAIN} ${V8_GYP_ARGS} -Dmode=${MS_TARGET_CONF_LOWER}
${CMAKE_COMMAND} -E env GYP_MSVS_VERSION=${GYP_MSVS_VERSION} GYP_GENERATORS=${GYP_GENERATORS} GYP_MSVS_OVERRIDE_PATH=${GYP_MSVS_OVERRIDE_PATH} DEPOT_TOOLS_WIN_TOOLCHAIN=${DEPOT_TOOLS_WIN_TOOLCHAIN} "${PYTHON_EXECUTABLE}" ${GYP_MAIN} ${V8_GYP_ARGS} -Dmode=${MS_TARGET_CONF_LOWER}
BUILD_COMMAND
""
INSTALL_COMMAND

View File

@ -23,6 +23,7 @@
#include <fuerte/types.h>
#include <algorithm>
#include <stdexcept>
namespace arangodb { namespace fuerte { inline namespace v1 {

View File

@ -83,7 +83,7 @@
#define IRESEARCH_HELPER_DLL_IMPORT __declspec(dllimport)
#define IRESEARCH_HELPER_DLL_EXPORT __declspec(dllexport)
#define IRESEARCH_HELPER_DLL_LOCAL
#define IRESEARCH_HELPER_TEMPLATE_IMPORT
#define IRESEARCH_HELPER_TEMPLATE_IMPORT
#define IRESEARCH_HELPER_TEMPLATE_EXPORT
#if _MSC_VER < 1900 // before msvc2015
@ -104,7 +104,7 @@
#define FORCE_INLINE inline __forceinline
#define NO_INLINE __declspec(noinline)
#define RESTRICT __restrict
#define RESTRICT __restrict
#define IRESEARCH_IGNORE_UNUSED /* unused */
#else
#if defined(__GNUC__) && __GNUC__ >= 4
@ -118,8 +118,8 @@
#define IRESEARCH_HELPER_DLL_LOCAL
#define CONSTEXPR
#endif
#define IRESEARCH_HELPER_TEMPLATE_IMPORT IRESEARCH_HELPER_DLL_IMPORT
#define IRESEARCH_HELPER_TEMPLATE_EXPORT IRESEARCH_HELPER_DLL_EXPORT
#define IRESEARCH_HELPER_TEMPLATE_IMPORT IRESEARCH_HELPER_DLL_IMPORT
#define IRESEARCH_HELPER_TEMPLATE_EXPORT IRESEARCH_HELPER_DLL_EXPORT
#define NOEXCEPT noexcept
#define ALIGNOF(v) alignof(v)
@ -206,6 +206,13 @@
#define MSVC2017_ONLY(...)
#endif
// hook for MSVC2019-only code
#if defined(_MSC_VER) && (_MSC_VER == 1920 )
#define MSVC2019_ONLY(...) __VA_ARGS__
#else
#define MSVC2019_ONLY(...)
#endif
// hook for GCC-only code
#if defined(__GNUC__)
#define GCC_ONLY(...) __VA_ARGS__
@ -234,11 +241,11 @@
// IRESEARCH_PLUGIN is used for public API symbols of plugin modules
#ifdef IRESEARCH_DLL
#ifdef IRESEARCH_DLL_EXPORTS
#define IRESEARCH_API IRESEARCH_HELPER_DLL_EXPORT
#define IRESEARCH_API_TEMPLATE IRESEARCH_HELPER_TEMPLATE_EXPORT
#define IRESEARCH_API IRESEARCH_HELPER_DLL_EXPORT
#define IRESEARCH_API_TEMPLATE IRESEARCH_HELPER_TEMPLATE_EXPORT
#else
#define IRESEARCH_API IRESEARCH_HELPER_DLL_IMPORT
#define IRESEARCH_API_TEMPLATE IRESEARCH_HELPER_TEMPLATE_IMPORT
#define IRESEARCH_API_TEMPLATE IRESEARCH_HELPER_TEMPLATE_IMPORT
#endif // IRESEARCH_DLL_EXPORTS
#define IRESEARCH_API_PRIVATE_VARIABLES_BEGIN MSVC_ONLY(__pragma(warning(disable: 4251)))
#define IRESEARCH_API_PRIVATE_VARIABLES_END MSVC_ONLY(__pragma(warning(default: 4251)))
@ -253,14 +260,14 @@
#define IRESEARCH_TEMPLATE_EXPORT(x) template IRESEARCH_API x
#define IRESEARCH_TEMPLATE_IMPORT(x) extern template x
#else // IRESEARCH_DLL is not defined: this means IRESEARCH is a static lib.
#define IRESEARCH_API
#define IRESEARCH_API
#define IRESEARCH_API_TEMPLATE
#define IRESEARCH_API_PRIVATE_VARIABLES_BEGIN
#define IRESEARCH_API_PRIVATE_VARIABLES_END
#define IRESEARCH_LOCAL
#define IRESEARCH_PLUGIN
#define IRESEARCH_TEMPLATE_EXPORT(x)
#define IRESEARCH_TEMPLATE_IMPORT(x)
#define IRESEARCH_TEMPLATE_IMPORT(x)
#endif // IRESEARCH_DLL
// MSVC 2015 does not define __cpp_lib_generic_associative_lookup macro

View File

@ -290,6 +290,7 @@ class codecvt16_facet final: public codecvtu_base<char16_t> {
public:
MSVC2015_ONLY(static std::locale::id id;) // MSVC2015 requires a static instance of an 'id' member
MSVC2017_ONLY(static std::locale::id id;) // MSVC2017 requires a static instance of an 'id' member
MSVC2019_ONLY(static std::locale::id id;)
codecvt16_facet(converter_pool& converters): codecvtu_base(converters) {}
bool append(
@ -321,6 +322,7 @@ class codecvt16_facet final: public codecvtu_base<char16_t> {
MSVC2015_ONLY(/*static*/ std::locale::id codecvt16_facet::id;) // MSVC2015 requires a static instance of an 'id' member
MSVC2017_ONLY(/*static*/ std::locale::id codecvt16_facet::id;) // MSVC2017 requires a static instance of an 'id' member
MSVC2019_ONLY(std::locale::id codecvt16_facet::id;)
#if defined (__GNUC__)
#pragma GCC diagnostic push
@ -508,6 +510,7 @@ class codecvt32_facet final: public codecvtu_base<char32_t> {
public:
MSVC2015_ONLY(static std::locale::id id;) // MSVC2015 requires a static instance of an 'id' member
MSVC2017_ONLY(static std::locale::id id;) // MSVC2017 requires a static instance of an 'id' member
MSVC2019_ONLY(static std::locale::id id;)
codecvt32_facet(converter_pool& converters): codecvtu_base(converters) {}
bool append(
@ -539,6 +542,7 @@ class codecvt32_facet final: public codecvtu_base<char32_t> {
MSVC2015_ONLY(/*static*/ std::locale::id codecvt32_facet::id;) // MSVC2015 requires a static instance of an 'id' member
MSVC2017_ONLY(/*static*/ std::locale::id codecvt32_facet::id;) // MSVC2017 requires a static instance of an 'id' member
MSVC2019_ONLY(std::locale::id codecvt32_facet::id;)
bool codecvt32_facet::append(
std::basic_string<intern_type>& buf, const icu::UnicodeString& value
@ -3750,4 +3754,4 @@ NS_END
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -24,8 +24,8 @@
#ifndef ARANGOD_AUTHENTICATION_COMMON_H
#define ARANGOD_AUTHENTICATION_COMMON_H 1
#include "Basics/Common.h"
#include <velocypack/Slice.h>
#include "Basics/Result.h"
namespace arangodb {
namespace auth {

View File

@ -24,8 +24,8 @@
#ifndef ARANGOD_AUTHENTICATION_HANDLER_H
#define ARANGOD_AUTHENTICATION_HANDLER_H 1
#include "Auth/Common.h"
#include "Basics/Result.h"
#include "Auth/Common.h"
#include <velocypack/Slice.h>

View File

@ -22,6 +22,8 @@
/// @author Achim Brandt
////////////////////////////////////////////////////////////////////////////////
#include "Basics/Common.h"
#include "GeneralListenTask.h"
#include "GeneralServer/GeneralServer.h"

View File

@ -21,6 +21,8 @@
/// @author Vasiliy Nabatchikov
////////////////////////////////////////////////////////////////////////////////
#include "Basics/Common.h"
#include "IResearchLinkHelper.h"
#include "IResearchCommon.h"
#include "IResearchFeature.h"
@ -827,4 +829,4 @@ namespace iresearch {
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -28,6 +28,7 @@
#include <velocypack/Builder.h>
#include <velocypack/Slice.h>
#include <cstdint>
#include <map>
struct TRI_vocbase_t;

View File

@ -24,13 +24,15 @@
#ifndef ARANGOSH_UTILS_MANAGED_DIRECTORY_H
#define ARANGOSH_UTILS_MANAGED_DIRECTORY_H 1
#include "Basics/Common.h"
#include "Basics/Result.h"
#include "zlib.h"
#include <velocypack/Builder.h>
#include <velocypack/Parser.h>
#include <velocypack/velocypack-aliases.h>
#include "Basics/Result.h"
#ifdef USE_ENTERPRISE
#include "Enterprise/Encryption/EncryptionFeature.h"

View File

@ -31,6 +31,7 @@
#include "ProgramOptions/Section.h"
#include "V8/v8-globals.h"
#include <stdexcept>
#include <v8.h>
using namespace arangodb;
@ -84,7 +85,8 @@ void convertToSingleExpression(std::vector<std::string> const& files, std::strin
targetRegex = arangodb::basics::StringUtils::join(files, '|');
}
void convertToSingleExpression(std::unordered_set<std::string> const& files, std::string& targetRegex) {
void convertToSingleExpression(std::unordered_set<std::string> const& files,
std::string& targetRegex) {
// does not delete from the set
if (files.empty()) {
return;
@ -286,19 +288,23 @@ void V8SecurityFeature::addToInternalWhitelist(std::string const& inItem, FSAcce
auto* expression = &_readWhitelist;
auto* re = &_readWhitelistRegex;
if(type == FSAccessType::WRITE) {
if (type == FSAccessType::WRITE) {
set = &_writeWhitelistSet;
expression = &_writeWhitelist;
re = &_writeWhitelistRegex;
}
auto item = arangodb::basics::StringUtils::escapeRegexParams(inItem);
auto path = "^" + canonicalpath(item) + TRI_DIR_SEPARATOR_STR;
auto item = canonicalpath(inItem + TRI_DIR_SEPARATOR_STR);
auto path = "^" + arangodb::basics::StringUtils::escapeRegexParams(item);
set->emplace(std::move(path));
expression->clear();
convertToSingleExpression(*set, *expression);
*re = std::regex(*expression, std::regex::nosubs | std::regex::ECMAScript);
try {
*re = std::regex(*expression, std::regex::nosubs | std::regex::ECMAScript);
} catch (std::exception const& ex) {
throw std::invalid_argument(ex.what() + std::string(" '") + *expression + "'");
}
}
bool V8SecurityFeature::isAllowedToControlProcesses(v8::Isolate* isolate) const {
@ -400,5 +406,5 @@ bool V8SecurityFeature::isAllowedToAccessPath(v8::Isolate* isolate, char const*
}
return checkBlackAndWhitelist(path, !_filesWhitelist.empty(), _filesWhitelistRegex,
false, _filesWhitelistRegex /*passed to match the signature but not used*/);
false, _filesWhitelistRegex /*passed to match the signature but not used*/);
}

View File

@ -46,6 +46,7 @@
#define TRI_WITHIN_COMMON 1
// clang-format off
#include "Basics/Result.h"
#include "Basics/operating-system.h"
#include "Basics/application-exit.h"
// clang-format on
@ -192,8 +193,8 @@ typedef long suseconds_t;
// Windows debug mode also seems to define DEBUG preproc symbol
#undef DEBUG
#endif
#ifdef ARANGODB_USE_CATCH_TESTS
#define TEST_VIRTUAL virtual
#else

View File

@ -23,7 +23,8 @@
#ifndef ARANGODB_BASICS_RESULT_H
#define ARANGODB_BASICS_RESULT_H 1
#include "Basics/Common.h"
#include <string>
#include "Basics/voc-errors.h"
namespace arangodb {
class Result final {

View File

@ -43,6 +43,29 @@
using namespace arangodb::basics;
using namespace icu;
#ifdef _WIN32
std::wstring arangodb::basics::toWString(std::string const& validUTF8String) {
icu::UnicodeString utf16(validUTF8String.c_str(), validUTF8String.size());
// // probably required for newer c++ versions
// using bufferType = std::remove_pointer_t<decltype(utf16.getTerminatedBuffer())>;
// static_assert(sizeof(std::wchar_t) == sizeof(bufferType), "sizes do not match");
// return std::wstring(reinterpret_cast<wchar_t const*>(utf16.getTerminatedBuffer()), utf16.length());
return std::wstring(utf16.getTerminatedBuffer(), utf16.length());
}
std::string arangodb::basics::fromWString(wchar_t const* validUTF16String, std::size_t size) {
std::string out;
icu::UnicodeString ICUString(validUTF16String, size);
ICUString.toUTF8String<std::string>(out);
return out;
}
std::string arangodb::basics::fromWString(std::wstring const& validUTF16String) {
return arangodb::basics::fromWString(validUTF16String.data(), validUTF16String.size());
}
#endif
Utf8Helper Utf8Helper::DefaultUtf8Helper(nullptr);
Utf8Helper::Utf8Helper(std::string const& lang, void* icuDataPtr)
@ -554,7 +577,7 @@ char* TRI_tolower_utf8(char const* src, int32_t srcLength, int32_t* dstLength) {
/// @brief convert a utf-8 string to a uchar (utf-16)
////////////////////////////////////////////////////////////////////////////////
UChar* TRI_Utf8ToUChar(char const* utf8, size_t inLength,
UChar* TRI_Utf8ToUChar(char const* utf8, size_t inLength,
UChar* buffer, size_t bufferSize, size_t* outLength) {
UErrorCode status = U_ZERO_ERROR;
@ -571,7 +594,7 @@ UChar* TRI_Utf8ToUChar(char const* utf8, size_t inLength,
// use local buffer
utf16 = buffer;
} else {
// dynamic memory
// dynamic memory
utf16 = (UChar*)TRI_Allocate((utf16Length + 1) * sizeof(UChar));
if (utf16 == nullptr) {
return nullptr;

View File

@ -25,17 +25,24 @@
#ifndef ARANGODB_BASICS_UTF8HELPER_H
#define ARANGODB_BASICS_UTF8HELPER_H 1
#include <velocypack/StringRef.h>
#include "Basics/Common.h"
#include <velocypack/StringRef.h>
#include <unicode/coll.h>
#include <unicode/regex.h>
#include <unicode/ustring.h>
#include <unicode/locid.h>
namespace arangodb {
namespace basics {
#ifdef _WIN32
std::wstring toWString(std::string const& validUTF8String);
std::string fromWString(wchar_t const* validUTF16String, std::size_t size);
std::string fromWString(std::wstring const& validUTF16String);
#endif
class Utf8Helper {
Utf8Helper(Utf8Helper const&) = delete;
Utf8Helper& operator=(Utf8Helper const&) = delete;

View File

@ -26,7 +26,6 @@
#ifdef _WIN32
#include <Shlwapi.h>
#include <tchar.h>
#include <unicode/locid.h>
#include <chrono>
#include <thread>
#endif
@ -45,6 +44,7 @@
#include "Basics/directories.h"
#include "Basics/hashes.h"
#include "Basics/tri-strings.h"
#include "Basics/Utf8Helper.h"
#include "Logger/Logger.h"
#include "Random/RandomGenerator.h"
@ -88,6 +88,7 @@ struct LockfileRemover {
/// @brief this instance will remove all lockfiles in its dtor
static LockfileRemover remover;
} // namespace
/// @brief read buffer size (used for bulk file reading)
@ -276,16 +277,22 @@ bool TRI_IsSymbolicLink(char const* path) {
/// @brief creates a symbolic link
////////////////////////////////////////////////////////////////////////////////
bool TRI_CreateSymbolicLink(std::string const& target, std::string const& linkpath,
std::string& error) {
bool TRI_CreateSymbolicLink(std::string const& target,
std::string const& linkpath, std::string& error) {
#ifdef _WIN32
// TODO : check if a file is a symbolic link - without opening the file
return false;
bool created =
::CreateSymbolicLinkW(toWString(linkpath).data(), toWString(target).data(), 0x0);
if (!created) {
auto rv = translateWindowsError(::GetLastError());
error = "failed to create a symlink " + target + " -> " + linkpath + " - " + rv.errorMessage();
}
return created;
#else
int res = symlink(target.c_str(), linkpath.c_str());
if (res < 0) {
error = "failed to create a symlink " + target + " -> " + linkpath + " - " + strerror(errno);
error = "failed to create a symlink " + target + " -> " + linkpath + " - " +
strerror(errno);
}
return res == 0;
#endif
@ -296,11 +303,11 @@ bool TRI_CreateSymbolicLink(std::string const& target, std::string const& linkpa
////////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
std::string TRI_ResolveSymbolicLink(std::string path, bool& hadError, bool recursive) {
std::string TRI_ResolveSymbolicLink(std::string path, bool& hadError, bool recursive) {
return path;
}
std::string TRI_ResolveSymbolicLink(std::string path, bool recursive) {
std::string TRI_ResolveSymbolicLink(std::string path, bool recursive) {
return path;
}
#else
@ -310,24 +317,25 @@ static bool IsSymbolicLink(char const* path, struct stat* stbuf) {
return (res == 0) && ((stbuf->st_mode & S_IFMT) == S_IFLNK);
}
static void deleteBuf(char *p) { std::free(p); };
}
static void deleteBuf(char* p) { std::free(p); };
} // namespace
std::string TRI_ResolveSymbolicLink(std::string path, bool& hadError, bool recursive) {
struct stat sb;
while (IsSymbolicLink(path.data(), &sb)) {
// if file is a symlink this contains the targets file name length
// instead of the file size
ssize_t bufsize = sb.st_size + 1;
ssize_t buffsize = sb.st_size + 1;
// resolve symlinks
auto buf = std::unique_ptr<char ,void(*)(char*)>((char*)std::malloc(bufsize), &deleteBuf );
auto written = ::readlink(path.c_str(), buf.get(), bufsize);
std::vector<char> buff;
buff.resize(buffsize);
auto written = ::readlink(path.c_str(), buff.data(), buff.size());
if(written) {
path = std::string(buf.get(), bufsize);
if (written) {
path = std::string(buff.data(), buff.size());
} else {
//error occured while resolving
// error occured while resolving
hadError = true;
break;
}
@ -396,8 +404,7 @@ bool TRI_ExistsFile(char const* path) {
int TRI_ChMod(char const* path, long mode, std::string& err) {
int res;
#ifdef _WIN32
icu::UnicodeString wpath(path);
res = _wchmod(reinterpret_cast<const wchar_t*>(wpath.getTerminatedBuffer()), static_cast<int>(mode));
res = _wchmod(toWString(path).data(), static_cast<int>(mode));
#else
res = chmod(path, mode);
#endif
@ -552,7 +559,8 @@ int TRI_RemoveDirectory(char const* filename) {
<< "removing symbolic link '" << filename << "'";
return TRI_UnlinkFile(filename);
} else if (TRI_IsDirectory(filename)) {
LOG_TOPIC("0207a", TRACE, arangodb::Logger::FIXME) << "removing directory '" << filename << "'";
LOG_TOPIC("0207a", TRACE, arangodb::Logger::FIXME)
<< "removing directory '" << filename << "'";
int res = TRI_ERROR_NO_ERROR;
std::vector<std::string> files = TRI_FilesDirectory(filename);
@ -572,7 +580,8 @@ int TRI_RemoveDirectory(char const* filename) {
return res;
} else if (TRI_ExistsFile(filename)) {
LOG_TOPIC("f103f", TRACE, arangodb::Logger::FIXME) << "removing file '" << filename << "'";
LOG_TOPIC("f103f", TRACE, arangodb::Logger::FIXME)
<< "removing file '" << filename << "'";
return TRI_UnlinkFile(filename);
} else {
@ -726,22 +735,15 @@ std::vector<std::string> TRI_FilesDirectory(char const* path) {
struct _wfinddata_t fd;
icu::UnicodeString wfilter(filter.c_str());
intptr_t handle = _wfindfirst(reinterpret_cast<const wchar_t*>(wfilter.getTerminatedBuffer()), &fd);
intptr_t handle = _wfindfirst(toWString(filter).data(), &fd);
if (handle == -1) {
return result;
}
std::string ufn;
icu::UnicodeString fn;
do {
if (wcscmp(fd.name, L".") != 0 && wcscmp(fd.name, L"..") != 0) {
ufn.clear();
fn = fd.name;
fn.toUTF8String<std::string>(ufn);
result.emplace_back(ufn);
result.emplace_back(fromWString(fd.name));
}
} while (_wfindnext(handle, &fd) != -1);
@ -802,11 +804,7 @@ int TRI_RenameFile(char const* old, char const* filename, long* systemError,
#ifdef _WIN32
BOOL moveResult = 0;
icu::UnicodeString oldf(old);
icu::UnicodeString newf(filename);
moveResult = MoveFileExW(reinterpret_cast<const wchar_t*>(oldf.getTerminatedBuffer()),
reinterpret_cast<const wchar_t*>(newf.getTerminatedBuffer()),
moveResult = MoveFileExW(toWString(old).data(), toWString(filename).data(),
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
if (!moveResult) {
@ -885,7 +883,8 @@ bool TRI_ReadPointer(int fd, void* buffer, size_t length) {
return false;
} else if (n == 0) {
TRI_set_errno(TRI_ERROR_SYS_ERROR);
LOG_TOPIC("87f52", ERR, arangodb::Logger::FIXME) << "cannot read, end-of-file";
LOG_TOPIC("87f52", ERR, arangodb::Logger::FIXME)
<< "cannot read, end-of-file";
return false;
}
@ -1039,8 +1038,7 @@ int TRI_CreateLockFile(char const* filename) {
}
}
icu::UnicodeString fn(filename);
HANDLE fd = CreateFileW(reinterpret_cast<const wchar_t*>(fn.getTerminatedBuffer()), GENERIC_WRITE, 0, NULL,
HANDLE fd = CreateFileW(toWString(filename).data(), GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fd == INVALID_HANDLE_VALUE) {
@ -1372,7 +1370,8 @@ char* TRI_GetFilename(char const* filename) {
#ifdef _WIN32
std::string TRI_GetAbsolutePath(std::string const& fileName, std::string const& currentWorkingDirectory) {
std::string TRI_GetAbsolutePath(std::string const& fileName,
std::string const& currentWorkingDirectory) {
// Check that fileName actually makes some sense
if (fileName.empty()) {
return std::string();
@ -1386,8 +1385,7 @@ std::string TRI_GetAbsolutePath(std::string const& fileName, std::string const&
if (fileName.size() >= 3 &&
((fileName[0] > 64 && fileName[0] < 91) || (fileName[0] > 96 && fileName[0] < 123)) &&
fileName[1] == ':' &&
(fileName[2] == '/' || fileName[2] == '\\')) {
fileName[1] == ':' && (fileName[2] == '/' || fileName[2] == '\\')) {
return fileName;
}
@ -1408,7 +1406,8 @@ std::string TRI_GetAbsolutePath(std::string const& fileName, std::string const&
// ...........................................................................
if (currentWorkingDirectory.size() >= 3 &&
((currentWorkingDirectory[0] > 64 && currentWorkingDirectory[0] < 91) || (currentWorkingDirectory[0] > 96 && currentWorkingDirectory[0] < 123)) &&
((currentWorkingDirectory[0] > 64 && currentWorkingDirectory[0] < 91) ||
(currentWorkingDirectory[0] > 96 && currentWorkingDirectory[0] < 123)) &&
currentWorkingDirectory[1] == ':' &&
(currentWorkingDirectory[2] == '/' || currentWorkingDirectory[2] == '\\')) {
// e.g. C:/ or Z:\ drive letter paths
@ -1422,10 +1421,8 @@ std::string TRI_GetAbsolutePath(std::string const& fileName, std::string const&
// Determine the total length of the new string
std::string result;
if (currentWorkingDirectory.back() == '\\' ||
currentWorkingDirectory.back() == '/' ||
fileName.front() == '\\' ||
fileName.front() == '/') {
if (currentWorkingDirectory.back() == '\\' || currentWorkingDirectory.back() == '/' ||
fileName.front() == '\\' || fileName.front() == '/') {
// we do not require a backslash
result.reserve(currentWorkingDirectory.size() + fileName.size());
result.append(currentWorkingDirectory);
@ -1443,14 +1440,16 @@ std::string TRI_GetAbsolutePath(std::string const& fileName, std::string const&
#else
std::string TRI_GetAbsolutePath(std::string const& fileName, std::string const& currentWorkingDirectory) {
std::string TRI_GetAbsolutePath(std::string const& fileName,
std::string const& currentWorkingDirectory) {
if (fileName.empty()) {
return std::string();
}
// name is absolute if starts with either forward or backslash
// file is also absolute if contains a colon
bool isAbsolute = (fileName[0] == '/' || fileName[0] == '\\' || fileName.find(':') != std::string::npos);
bool isAbsolute = (fileName[0] == '/' || fileName[0] == '\\' ||
fileName.find(':') != std::string::npos);
if (isAbsolute) {
return fileName;
@ -1510,12 +1509,7 @@ std::string TRI_LocateBinaryPath(char const* argv0) {
}
size_t len = q - buff;
icu::UnicodeString fn(buff, static_cast<int32_t>(len));
std::string ufn;
fn.toUTF8String<std::string>(ufn);
return ufn;
return fromWString(buff, len);
}
return std::string();
@ -1654,7 +1648,7 @@ static bool CopyFileContents(int srcFD, int dstFD, ssize_t fileSize, std::string
// write can write less data than requested. so we must go on writing
// until we have written out all data
ssize_t nWritten = TRI_WRITE(dstFD, buf + writeOffset,
static_cast<TRI_write_t>(writeRemaining));
static_cast<TRI_write_t>(writeRemaining));
if (nWritten < 0) {
// error during write
@ -1683,15 +1677,12 @@ bool TRI_CopyFile(std::string const& src, std::string const& dst, std::string& e
#ifdef _WIN32
TRI_ERRORBUF;
icu::UnicodeString s(src.c_str());
icu::UnicodeString d(dst.c_str());
bool rc = CopyFileW(reinterpret_cast<const wchar_t*>(s.getTerminatedBuffer()),
reinterpret_cast<const wchar_t*>(d.getTerminatedBuffer()), true) != 0;
bool rc = CopyFileW(toWString(src).data(), toWString(dst).data(), true) != 0;
if (!rc) {
TRI_SYSTEM_ERROR();
error = "failed to copy " + src + " to " + dst + ": " + TRI_GET_ERRORBUF;
}
return rc;
#else
size_t dsize;
@ -1950,9 +1941,7 @@ static std::string getTempPath() {
<< ":dwReturnValue=" << dwReturnValue;
}
icu::UnicodeString tmpPathW(tempPathName, dwReturnValue);
std::string result;
tmpPathW.toUTF8String<std::string>(result);
std::string result = fromWString(tempPathName, dwReturnValue);
// ...........................................................................
// Whether or not UNICODE is defined, we assume that the temporary file name
// fits in the ascii set of characters. This is a small compromise so that
@ -1973,20 +1962,24 @@ static std::string getTempPath() {
}
static int mkDTemp(char* s, size_t bufferSize) {
std::string out;
icu::UnicodeString sw(s);
auto w = std::make_unique<wchar_t[]>(bufferSize);
static_assert(sizeof(wchar_t) == sizeof(char16_t), "icu utf16 type needs to match wchar_t");
memcpy(w.get(), sw.getTerminatedBuffer(), sizeof(wchar_t) * bufferSize);
// this will overwrite the _XXX part of the string:
auto rc = _wmktemp_s(w.get(), bufferSize);
if (rc == 0) {
std::string tmp(s, bufferSize);
std::wstring ws = toWString(tmp);
// get writeable copy of wstring buffer and replace the _XXX part in the buffer
std::vector<wchar_t> writeBuffer;
writeBuffer.resize(ws.size());
memcpy(writeBuffer.data(), ws.data(), sizeof(wchar_t) * ws.size());
auto rc = _wmktemp_s(writeBuffer.data(), writeBuffer.size()); // requires writeable buffer -- returns errno_t
if (rc == 0) { // error of 0 is ok
// if it worked out, we need to return the utf8 version:
sw = w.get();
sw.toUTF8String<std::string>(out);
memcpy(s, out.c_str(), bufferSize);
ws = std::wstring(writeBuffer.data(), writeBuffer.size()); // write back to wstring
tmp = fromWString(ws);
memcpy(s, tmp.data(), bufferSize); // copy back into parameter
rc = TRI_MKDIR(s, 0700);
}
// should error be translated to arango error code?
return rc;
}
@ -2358,8 +2351,8 @@ int TRI_CreateDatafile(std::string const& filename, size_t maximalSize) {
// remove empty file
TRI_UnlinkFile(filename.c_str());
LOG_TOPIC("dfc52", ERR, arangodb::Logger::FIXME) << "cannot seek in datafile '" << filename
<< "': '" << TRI_GET_ERRORBUF << "'";
LOG_TOPIC("dfc52", ERR, arangodb::Logger::FIXME)
<< "cannot seek in datafile '" << filename << "': '" << TRI_GET_ERRORBUF << "'";
return -1;
}
@ -2368,8 +2361,7 @@ int TRI_CreateDatafile(std::string const& filename, size_t maximalSize) {
bool TRI_PathIsAbsolute(std::string const& path) {
#if _WIN32
icu::UnicodeString upath(path.c_str(), (uint16_t)path.length());
return !PathIsRelativeW(reinterpret_cast<const wchar_t*>(upath.getTerminatedBuffer()));
return !PathIsRelativeW(toWString(path).data());
#else
return (!path.empty()) && path.c_str()[0] == '/';
#endif
@ -2392,15 +2384,13 @@ void TRI_ShutdownFiles() {}
bool TRI_GETENV(char const* which, std::string& value) {
#ifdef _WIN32
icu::UnicodeString uwhich(which);
wchar_t const* v = _wgetenv(reinterpret_cast<const wchar_t*>(uwhich.getTerminatedBuffer()));
wchar_t const* wideBuffer = _wgetenv(toWString(which).data());
if (v == nullptr) {
if (wideBuffer == nullptr) {
return false;
}
value.clear();
icu::UnicodeString vu(v);
vu.toUTF8String<std::string>(value);
value = fromWString(wideBuffer);
return true;
#else
char const* v = getenv(which);

View File

@ -858,13 +858,19 @@ int TRI_UNLINK(char const* filename);
void TRI_GET_ARGV_WIN(int& argc, char** argv);
// system error string macro requires ERRORBUF to instantiate its buffer before.
#define TRI_SYSTEM_ERROR() \
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, \
windowsErrorBuf, sizeof(windowsErrorBuf), NULL) == 0) { \
memcpy(&windowsErrorBuf[0], "unknown error\0", strlen("unknown error\0")); \
} \
errno = TRI_MapSystemError(GetLastError())
#define TRI_SYSTEM_ERROR() \
do { \
auto result = translateWindowsError(::GetLastError()); \
errno = result.errorNumber(); \
auto const& mesg = result.errorMessage(); \
if (mesg.empty()) { \
memcpy(&windowsErrorBuf[0], "unknown error\0", strlen("unknown error\0")); \
} else { \
memcpy(&windowsErrorBuf[0], mesg.data(), \
(std::min)(sizeof(windowsErrorBuf) / sizeof(windowsErrorBuf[0]), \
mesg.size())); \
} \
} while (false)
#define STDERR_FILENO 2
#define STDIN_FILENO 0

View File

@ -48,6 +48,7 @@
#include "Basics/directories.h"
#include "Basics/files.h"
#include "Basics/tri-strings.h"
#include "Basics/Utf8Helper.h"
#include "Logger/Logger.h"
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
@ -318,6 +319,25 @@ int TRI_UNLINK(char const* filename) {
/// @brief converts a Windows error to a *nix system error
////////////////////////////////////////////////////////////////////////////////
arangodb::Result translateWindowsError(DWORD error) {
return {TRI_MapSystemError(error), windowsErrorToUTF8(error)};
}
std::string windowsErrorToUTF8(DWORD errorNum) {
LPWSTR buffer = nullptr;
TRI_DEFER(::LocalFree(buffer);)
size_t size =
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, errorNum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&buffer, 0, nullptr);
if (size) {
std::wstring out(buffer, size);
return fromWString(out);
}
return "error translation failed";
}
int TRI_MapSystemError(DWORD error) {
switch (error) {
case ERROR_INVALID_FUNCTION:

View File

@ -27,6 +27,8 @@
#include <WinSock2.h>
#include <string>
#include "Basics/Result.h"
// .............................................................................
// Called before anything else starts - initializes whatever is required to be
// initialized.
@ -68,6 +70,8 @@ int TRI_OPEN_WIN32(char const* filename, int openFlags);
////////////////////////////////////////////////////////////////////////////////
int TRI_MapSystemError(DWORD);
std::string windowsErrorToUTF8(DWORD);
arangodb::Result translateWindowsError(DWORD);
////////////////////////////////////////////////////////////////////////////////
/// @brief open/close the windows eventlog. Call on start / shutdown

View File

@ -23,12 +23,13 @@
#ifndef ARANGOD_GEO_GEO_PARAMS_H
#define ARANGOD_GEO_GEO_PARAMS_H 1
#include <cmath>
#include "Basics/Common.h"
#include "Geo/ShapeContainer.h"
#include <cmath>
#include <s2/s2latlng.h>
#include <s2/s2region_coverer.h>
#include "Geo/ShapeContainer.h"
namespace arangodb {
namespace velocypack {

View File

@ -24,6 +24,7 @@
#define ARANGOD_GEO_SHAPE_CONTAINER_H 1
#include <string>
#include <memory>
#include <s2/s2cell_id.h>