mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-01 22:54:12 +08:00
mdbx: native wchar_t
pathname for Windows.
This commit is contained in:
parent
98c53555ab
commit
2ff8d3c4f2
35
mdbx.h
35
mdbx.h
@ -827,18 +827,30 @@ enum MDBX_constants {
|
|||||||
#ifndef MDBX_LOCKNAME
|
#ifndef MDBX_LOCKNAME
|
||||||
/** \brief The name of the lock file in the environment
|
/** \brief The name of the lock file in the environment
|
||||||
* without using \ref MDBX_NOSUBDIR */
|
* without using \ref MDBX_NOSUBDIR */
|
||||||
|
#if !(defined(_WIN32) || defined(_WIN64))
|
||||||
#define MDBX_LOCKNAME "/mdbx.lck"
|
#define MDBX_LOCKNAME "/mdbx.lck"
|
||||||
|
#else
|
||||||
|
#define MDBX_LOCKNAME L"\\mdbx.lck"
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* MDBX_LOCKNAME */
|
||||||
#ifndef MDBX_DATANAME
|
#ifndef MDBX_DATANAME
|
||||||
/** \brief The name of the data file in the environment
|
/** \brief The name of the data file in the environment
|
||||||
* without using \ref MDBX_NOSUBDIR */
|
* without using \ref MDBX_NOSUBDIR */
|
||||||
|
#if !(defined(_WIN32) || defined(_WIN64))
|
||||||
#define MDBX_DATANAME "/mdbx.dat"
|
#define MDBX_DATANAME "/mdbx.dat"
|
||||||
|
#else
|
||||||
|
#define MDBX_DATANAME L"\\mdbx.dat"
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* MDBX_DATANAME */
|
||||||
|
|
||||||
#ifndef MDBX_LOCK_SUFFIX
|
#ifndef MDBX_LOCK_SUFFIX
|
||||||
/** \brief The suffix of the lock file when \ref MDBX_NOSUBDIR is used */
|
/** \brief The suffix of the lock file when \ref MDBX_NOSUBDIR is used */
|
||||||
|
#if !(defined(_WIN32) || defined(_WIN64))
|
||||||
#define MDBX_LOCK_SUFFIX "-lck"
|
#define MDBX_LOCK_SUFFIX "-lck"
|
||||||
|
#else
|
||||||
|
#define MDBX_LOCK_SUFFIX L"-lck"
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* MDBX_LOCK_SUFFIX */
|
||||||
|
|
||||||
/* DEBUG & LOGGING ************************************************************/
|
/* DEBUG & LOGGING ************************************************************/
|
||||||
|
|
||||||
@ -2275,6 +2287,11 @@ LIBMDBX_API int mdbx_env_get_option(const MDBX_env *env,
|
|||||||
LIBMDBX_API int mdbx_env_open(MDBX_env *env, const char *pathname,
|
LIBMDBX_API int mdbx_env_open(MDBX_env *env, const char *pathname,
|
||||||
MDBX_env_flags_t flags, mdbx_mode_t mode);
|
MDBX_env_flags_t flags, mdbx_mode_t mode);
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
LIBMDBX_API int mdbx_env_openW(MDBX_env *env, const wchar_t *pathnameW,
|
||||||
|
MDBX_env_flags_t flags, mdbx_mode_t mode);
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
/** \brief Deletion modes for \ref mdbx_env_delete().
|
/** \brief Deletion modes for \ref mdbx_env_delete().
|
||||||
* \ingroup c_extra
|
* \ingroup c_extra
|
||||||
* \see mdbx_env_delete() */
|
* \see mdbx_env_delete() */
|
||||||
@ -2317,6 +2334,10 @@ typedef enum MDBX_env_delete_mode_t MDBX_env_delete_mode_t;
|
|||||||
* so no deletion was performed. */
|
* so no deletion was performed. */
|
||||||
LIBMDBX_API int mdbx_env_delete(const char *pathname,
|
LIBMDBX_API int mdbx_env_delete(const char *pathname,
|
||||||
MDBX_env_delete_mode_t mode);
|
MDBX_env_delete_mode_t mode);
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
LIBMDBX_API int mdbx_env_deleteW(const wchar_t *pathnameW,
|
||||||
|
MDBX_env_delete_mode_t mode);
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
/** \brief Copy an MDBX environment to the specified path, with options.
|
/** \brief Copy an MDBX environment to the specified path, with options.
|
||||||
* \ingroup c_extra
|
* \ingroup c_extra
|
||||||
@ -2351,6 +2372,10 @@ LIBMDBX_API int mdbx_env_delete(const char *pathname,
|
|||||||
* \returns A non-zero error value on failure and 0 on success. */
|
* \returns A non-zero error value on failure and 0 on success. */
|
||||||
LIBMDBX_API int mdbx_env_copy(MDBX_env *env, const char *dest,
|
LIBMDBX_API int mdbx_env_copy(MDBX_env *env, const char *dest,
|
||||||
MDBX_copy_flags_t flags);
|
MDBX_copy_flags_t flags);
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
LIBMDBX_API int mdbx_env_copyW(MDBX_env *env, const wchar_t *dest,
|
||||||
|
MDBX_copy_flags_t flags);
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
/** \brief Copy an environment to the specified file descriptor, with
|
/** \brief Copy an environment to the specified file descriptor, with
|
||||||
* options.
|
* options.
|
||||||
@ -2803,7 +2828,11 @@ LIBMDBX_API int mdbx_env_get_flags(const MDBX_env *env, unsigned *flags);
|
|||||||
* \returns A non-zero error value on failure and 0 on success,
|
* \returns A non-zero error value on failure and 0 on success,
|
||||||
* some possible errors are:
|
* some possible errors are:
|
||||||
* \retval MDBX_EINVAL An invalid parameter was specified. */
|
* \retval MDBX_EINVAL An invalid parameter was specified. */
|
||||||
|
#if !(defined(_WIN32) || defined(_WIN64))
|
||||||
LIBMDBX_API int mdbx_env_get_path(const MDBX_env *env, const char **dest);
|
LIBMDBX_API int mdbx_env_get_path(const MDBX_env *env, const char **dest);
|
||||||
|
#else
|
||||||
|
LIBMDBX_API int mdbx_env_get_pathW(const MDBX_env *env, const wchar_t **dest);
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
/** \brief Return the file descriptor for the given environment.
|
/** \brief Return the file descriptor for the given environment.
|
||||||
* \ingroup c_statinfo
|
* \ingroup c_statinfo
|
||||||
@ -5195,6 +5224,12 @@ LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor,
|
|||||||
LIBMDBX_API int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
|
LIBMDBX_API int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
|
||||||
unsigned target_meta,
|
unsigned target_meta,
|
||||||
bool writeable);
|
bool writeable);
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
LIBMDBX_API int mdbx_env_open_for_recoveryW(MDBX_env *env,
|
||||||
|
const wchar_t *pathnameW,
|
||||||
|
unsigned target_meta,
|
||||||
|
bool writeable);
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
/** \brief Turn database to the specified meta-page.
|
/** \brief Turn database to the specified meta-page.
|
||||||
*
|
*
|
||||||
|
8
mdbx.h++
8
mdbx.h++
@ -3225,6 +3225,8 @@ public:
|
|||||||
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||||
env ©(const ::std::wstring &destination, bool compactify,
|
env ©(const ::std::wstring &destination, bool compactify,
|
||||||
bool force_dynamic_size = false);
|
bool force_dynamic_size = false);
|
||||||
|
env ©(const wchar_t *destination, bool compactify,
|
||||||
|
bool force_dynamic_size = false);
|
||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
env ©(const ::std::string &destination, bool compactify,
|
env ©(const ::std::string &destination, bool compactify,
|
||||||
bool force_dynamic_size = false);
|
bool force_dynamic_size = false);
|
||||||
@ -3260,6 +3262,8 @@ public:
|
|||||||
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||||
static bool remove(const ::std::wstring &pathname,
|
static bool remove(const ::std::wstring &pathname,
|
||||||
const remove_mode mode = just_remove);
|
const remove_mode mode = just_remove);
|
||||||
|
static bool remove(const wchar_t *pathname,
|
||||||
|
const remove_mode mode = just_remove);
|
||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
static bool remove(const ::std::string &pathname,
|
static bool remove(const ::std::string &pathname,
|
||||||
const remove_mode mode = just_remove);
|
const remove_mode mode = just_remove);
|
||||||
@ -3507,6 +3511,8 @@ public:
|
|||||||
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||||
env_managed(const ::std::wstring &pathname, const operate_parameters &,
|
env_managed(const ::std::wstring &pathname, const operate_parameters &,
|
||||||
bool accede = true);
|
bool accede = true);
|
||||||
|
explicit env_managed(const wchar_t *pathname, const operate_parameters &,
|
||||||
|
bool accede = true);
|
||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
env_managed(const ::std::string &pathname, const operate_parameters &,
|
env_managed(const ::std::string &pathname, const operate_parameters &,
|
||||||
bool accede = true);
|
bool accede = true);
|
||||||
@ -3531,6 +3537,8 @@ public:
|
|||||||
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||||
env_managed(const ::std::wstring &pathname, const create_parameters &,
|
env_managed(const ::std::wstring &pathname, const create_parameters &,
|
||||||
const operate_parameters &, bool accede = true);
|
const operate_parameters &, bool accede = true);
|
||||||
|
explicit env_managed(const wchar_t *pathname, const create_parameters &,
|
||||||
|
const operate_parameters &, bool accede = true);
|
||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
env_managed(const ::std::string &pathname, const create_parameters &,
|
env_managed(const ::std::string &pathname, const create_parameters &,
|
||||||
const operate_parameters &, bool accede = true);
|
const operate_parameters &, bool accede = true);
|
||||||
|
174
src/core.c
174
src/core.c
@ -12433,7 +12433,7 @@ __cold static int mdbx_setup_dxb(MDBX_env *env, const int lck_rc,
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
/* Open and/or initialize the lock region for the environment. */
|
/* Open and/or initialize the lock region for the environment. */
|
||||||
__cold static int mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
|
__cold static int mdbx_setup_lck(MDBX_env *env, pathchar_t *lck_pathname,
|
||||||
mdbx_mode_t mode) {
|
mdbx_mode_t mode) {
|
||||||
mdbx_assert(env, env->me_lazy_fd != INVALID_HANDLE_VALUE);
|
mdbx_assert(env, env->me_lazy_fd != INVALID_HANDLE_VALUE);
|
||||||
mdbx_assert(env, env->me_lfd == INVALID_HANDLE_VALUE);
|
mdbx_assert(env, env->me_lfd == INVALID_HANDLE_VALUE);
|
||||||
@ -12816,6 +12816,21 @@ __cold int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target) {
|
|||||||
|
|
||||||
__cold int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
|
__cold int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
|
||||||
unsigned target_meta, bool writeable) {
|
unsigned target_meta, bool writeable) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
||||||
|
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
||||||
|
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
|
||||||
|
return mdbx_env_open_for_recoveryW(env, pathnameW, target_meta, writeable);
|
||||||
|
}
|
||||||
|
|
||||||
|
__cold int mdbx_env_open_for_recoveryW(MDBX_env *env, const wchar_t *pathname,
|
||||||
|
unsigned target_meta, bool writeable) {
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
if (unlikely(target_meta >= NUM_METAS))
|
if (unlikely(target_meta >= NUM_METAS))
|
||||||
return MDBX_EINVAL;
|
return MDBX_EINVAL;
|
||||||
int rc = check_env(env, false);
|
int rc = check_env(env, false);
|
||||||
@ -12825,35 +12840,49 @@ __cold int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
|
|||||||
return MDBX_EPERM;
|
return MDBX_EPERM;
|
||||||
|
|
||||||
env->me_stuck_meta = (int8_t)target_meta;
|
env->me_stuck_meta = (int8_t)target_meta;
|
||||||
return mdbx_env_open(
|
return
|
||||||
env, pathname, writeable ? MDBX_EXCLUSIVE : MDBX_EXCLUSIVE | MDBX_RDONLY,
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
0);
|
mdbx_env_openW
|
||||||
|
#else
|
||||||
|
mdbx_env_open
|
||||||
|
#endif /* Windows */
|
||||||
|
(env, pathname, writeable ? MDBX_EXCLUSIVE : MDBX_EXCLUSIVE | MDBX_RDONLY,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *buffer_for_free;
|
void *buffer_for_free;
|
||||||
char *lck, *dxb;
|
pathchar_t *lck, *dxb;
|
||||||
size_t ent_len;
|
size_t ent_len;
|
||||||
} MDBX_handle_env_pathname;
|
} MDBX_handle_env_pathname;
|
||||||
|
|
||||||
|
static bool path_equal(const pathchar_t *l, const pathchar_t *r, size_t len) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
while (len > 0) {
|
||||||
|
pathchar_t a = *l++;
|
||||||
|
pathchar_t b = *r++;
|
||||||
|
a = (a == '\\') ? '/' : a;
|
||||||
|
b = (b == '\\') ? '/' : b;
|
||||||
|
if (a != b)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return memcmp(l, r, len * sizeof(pathchar_t)) == 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
__cold static int mdbx_handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
__cold static int mdbx_handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||||
const char *pathname,
|
const pathchar_t *pathname,
|
||||||
MDBX_env_flags_t *flags,
|
MDBX_env_flags_t *flags,
|
||||||
const mdbx_mode_t mode) {
|
const mdbx_mode_t mode) {
|
||||||
int rc;
|
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
if (unlikely(!pathname))
|
if (unlikely(!pathname || !*pathname))
|
||||||
return MDBX_EINVAL;
|
return MDBX_EINVAL;
|
||||||
|
|
||||||
|
int rc;
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
const DWORD dwAttrib = GetFileAttributesW(pathname);
|
||||||
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
|
||||||
return ERROR_INVALID_NAME;
|
|
||||||
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
|
||||||
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
|
||||||
return ERROR_INVALID_NAME;
|
|
||||||
|
|
||||||
const DWORD dwAttrib = GetFileAttributesW(pathnameW);
|
|
||||||
if (dwAttrib == INVALID_FILE_ATTRIBUTES) {
|
if (dwAttrib == INVALID_FILE_ATTRIBUTES) {
|
||||||
rc = GetLastError();
|
rc = GetLastError();
|
||||||
if (rc != MDBX_ENOFILE)
|
if (rc != MDBX_ENOFILE)
|
||||||
@ -12863,8 +12892,7 @@ __cold static int mdbx_handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* auto-create directory if requested */
|
/* auto-create directory if requested */
|
||||||
if ((*flags & MDBX_NOSUBDIR) == 0 &&
|
if ((*flags & MDBX_NOSUBDIR) == 0 && !CreateDirectoryW(pathname, nullptr)) {
|
||||||
!CreateDirectoryW(pathnameW, nullptr)) {
|
|
||||||
rc = GetLastError();
|
rc = GetLastError();
|
||||||
if (rc != ERROR_ALREADY_EXISTS)
|
if (rc != ERROR_ALREADY_EXISTS)
|
||||||
return rc;
|
return rc;
|
||||||
@ -12905,41 +12933,66 @@ __cold static int mdbx_handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char dxb_name[] = MDBX_DATANAME;
|
static const pathchar_t dxb_name[] = MDBX_DATANAME;
|
||||||
static const size_t dxb_name_len = sizeof(dxb_name) - 1;
|
static const pathchar_t lck_name[] = MDBX_LOCKNAME;
|
||||||
static const char lck_name[] = MDBX_LOCKNAME;
|
static const pathchar_t lock_suffix[] = MDBX_LOCK_SUFFIX;
|
||||||
static const char lock_suffix[] = MDBX_LOCK_SUFFIX;
|
|
||||||
|
|
||||||
ctx->ent_len = strlen(pathname);
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
if ((*flags & MDBX_NOSUBDIR) && ctx->ent_len >= dxb_name_len &&
|
assert(dxb_name[0] == '\\' && lck_name[0] == '\\');
|
||||||
!memcmp(dxb_name, pathname + ctx->ent_len - dxb_name_len, dxb_name_len)) {
|
const size_t pathname_len = wcslen(pathname);
|
||||||
|
#else
|
||||||
|
assert(dxb_name[0] == '/' && lck_name[0] == '/');
|
||||||
|
const size_t pathname_len = strlen(pathname);
|
||||||
|
#endif
|
||||||
|
assert(lock_suffix[0] != '\\' && lock_suffix[0] != '/');
|
||||||
|
ctx->ent_len = pathname_len;
|
||||||
|
static const size_t dxb_name_len = ARRAY_LENGTH(dxb_name) - 1;
|
||||||
|
if ((*flags & MDBX_NOSUBDIR) && ctx->ent_len > dxb_name_len &&
|
||||||
|
path_equal(pathname + ctx->ent_len - dxb_name_len, dxb_name,
|
||||||
|
dxb_name_len)) {
|
||||||
*flags -= MDBX_NOSUBDIR;
|
*flags -= MDBX_NOSUBDIR;
|
||||||
ctx->ent_len -= dxb_name_len;
|
ctx->ent_len -= dxb_name_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t bytes_needed =
|
const size_t bytes_needed =
|
||||||
ctx->ent_len * 2 + ((*flags & MDBX_NOSUBDIR)
|
sizeof(pathchar_t) * ctx->ent_len * 2 +
|
||||||
? sizeof(lock_suffix) + 1
|
((*flags & MDBX_NOSUBDIR) ? sizeof(lock_suffix) + sizeof(pathchar_t)
|
||||||
: sizeof(lck_name) + sizeof(dxb_name));
|
: sizeof(lck_name) + sizeof(dxb_name));
|
||||||
ctx->buffer_for_free = mdbx_malloc(bytes_needed);
|
ctx->buffer_for_free = mdbx_malloc(bytes_needed);
|
||||||
if (!ctx->buffer_for_free)
|
if (!ctx->buffer_for_free)
|
||||||
return MDBX_ENOMEM;
|
return MDBX_ENOMEM;
|
||||||
|
|
||||||
ctx->lck = ctx->buffer_for_free;
|
ctx->dxb = ctx->buffer_for_free;
|
||||||
|
ctx->lck = ctx->dxb + ctx->ent_len + 1;
|
||||||
|
memcpy(ctx->dxb, pathname, sizeof(pathchar_t) * (ctx->ent_len + 1));
|
||||||
if (*flags & MDBX_NOSUBDIR) {
|
if (*flags & MDBX_NOSUBDIR) {
|
||||||
ctx->dxb = ctx->lck + ctx->ent_len + sizeof(lock_suffix);
|
memcpy(ctx->lck + ctx->ent_len, lock_suffix, sizeof(lock_suffix));
|
||||||
sprintf(ctx->lck, "%s%s", pathname, lock_suffix);
|
|
||||||
strcpy(ctx->dxb, pathname);
|
|
||||||
} else {
|
} else {
|
||||||
ctx->dxb = ctx->lck + ctx->ent_len + sizeof(lck_name);
|
ctx->lck += dxb_name_len;
|
||||||
sprintf(ctx->lck, "%.*s%s", (int)ctx->ent_len, pathname, lck_name);
|
memcpy(ctx->lck + ctx->ent_len, lck_name, sizeof(lck_name));
|
||||||
sprintf(ctx->dxb, "%.*s%s", (int)ctx->ent_len, pathname, dxb_name);
|
memcpy(ctx->dxb + ctx->ent_len, dxb_name, sizeof(dxb_name));
|
||||||
}
|
}
|
||||||
|
memcpy(ctx->lck, pathname, sizeof(pathchar_t) * ctx->ent_len);
|
||||||
|
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
__cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) {
|
__cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
||||||
|
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
||||||
|
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
|
||||||
|
return mdbx_env_deleteW(pathnameW, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
__cold int mdbx_env_deleteW(const wchar_t *pathname,
|
||||||
|
MDBX_env_delete_mode_t mode) {
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
default:
|
default:
|
||||||
return MDBX_EINVAL;
|
return MDBX_EINVAL;
|
||||||
@ -12959,7 +13012,7 @@ __cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) {
|
|||||||
(mode == MDBX_ENV_ENSURE_UNUSED) ? MDBX_EXCLUSIVE : MDBX_ENV_DEFAULTS;
|
(mode == MDBX_ENV_ENSURE_UNUSED) ? MDBX_EXCLUSIVE : MDBX_ENV_DEFAULTS;
|
||||||
dummy_env->me_os_psize = (unsigned)mdbx_syspagesize();
|
dummy_env->me_os_psize = (unsigned)mdbx_syspagesize();
|
||||||
dummy_env->me_psize = (unsigned)mdbx_default_pagesize();
|
dummy_env->me_psize = (unsigned)mdbx_default_pagesize();
|
||||||
dummy_env->me_pathname = (char *)pathname;
|
dummy_env->me_pathname = (pathchar_t *)pathname;
|
||||||
|
|
||||||
MDBX_handle_env_pathname env_pathname;
|
MDBX_handle_env_pathname env_pathname;
|
||||||
STATIC_ASSERT(sizeof(dummy_env->me_flags) == sizeof(MDBX_env_flags_t));
|
STATIC_ASSERT(sizeof(dummy_env->me_flags) == sizeof(MDBX_env_flags_t));
|
||||||
@ -13021,6 +13074,21 @@ __cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) {
|
|||||||
|
|
||||||
__cold int mdbx_env_open(MDBX_env *env, const char *pathname,
|
__cold int mdbx_env_open(MDBX_env *env, const char *pathname,
|
||||||
MDBX_env_flags_t flags, mdbx_mode_t mode) {
|
MDBX_env_flags_t flags, mdbx_mode_t mode) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
||||||
|
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
||||||
|
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
|
||||||
|
return mdbx_env_openW(env, pathnameW, flags, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
__cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
||||||
|
MDBX_env_flags_t flags, mdbx_mode_t mode) {
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
int rc = check_env(env, false);
|
int rc = check_env(env, false);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
return rc;
|
return rc;
|
||||||
@ -13066,7 +13134,7 @@ __cold int mdbx_env_open(MDBX_env *env, const char *pathname,
|
|||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
env->me_flags = (flags & ~MDBX_FATAL_ERROR) | MDBX_ENV_ACTIVE;
|
env->me_flags = (flags & ~MDBX_FATAL_ERROR) | MDBX_ENV_ACTIVE;
|
||||||
env->me_pathname = mdbx_calloc(env_pathname.ent_len + 1, 1);
|
env->me_pathname = mdbx_calloc(env_pathname.ent_len + 1, sizeof(pathchar_t));
|
||||||
env->me_dbxs = mdbx_calloc(env->me_maxdbs, sizeof(MDBX_dbx));
|
env->me_dbxs = mdbx_calloc(env->me_maxdbs, sizeof(MDBX_dbx));
|
||||||
env->me_dbflags = mdbx_calloc(env->me_maxdbs, sizeof(env->me_dbflags[0]));
|
env->me_dbflags = mdbx_calloc(env->me_maxdbs, sizeof(env->me_dbflags[0]));
|
||||||
env->me_dbiseqs = mdbx_calloc(env->me_maxdbs, sizeof(env->me_dbiseqs[0]));
|
env->me_dbiseqs = mdbx_calloc(env->me_maxdbs, sizeof(env->me_dbiseqs[0]));
|
||||||
@ -13075,7 +13143,8 @@ __cold int mdbx_env_open(MDBX_env *env, const char *pathname,
|
|||||||
rc = MDBX_ENOMEM;
|
rc = MDBX_ENOMEM;
|
||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
memcpy(env->me_pathname, env_pathname.dxb, env_pathname.ent_len);
|
memcpy(env->me_pathname, env_pathname.dxb,
|
||||||
|
env_pathname.ent_len * sizeof(pathchar_t));
|
||||||
env->me_dbxs[FREE_DBI].md_cmp = cmp_int_align4; /* aligned MDBX_INTEGERKEY */
|
env->me_dbxs[FREE_DBI].md_cmp = cmp_int_align4; /* aligned MDBX_INTEGERKEY */
|
||||||
env->me_dbxs[FREE_DBI].md_dcmp = cmp_lenfast;
|
env->me_dbxs[FREE_DBI].md_dcmp = cmp_lenfast;
|
||||||
|
|
||||||
@ -19911,6 +19980,21 @@ __cold int mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
|
|||||||
|
|
||||||
__cold int mdbx_env_copy(MDBX_env *env, const char *dest_path,
|
__cold int mdbx_env_copy(MDBX_env *env, const char *dest_path,
|
||||||
MDBX_copy_flags_t flags) {
|
MDBX_copy_flags_t flags) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
const size_t wlen = mbstowcs(nullptr, dest_path, INT_MAX);
|
||||||
|
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
wchar_t *const dest_pathW = _alloca((wlen + 1) * sizeof(wchar_t));
|
||||||
|
if (wlen != mbstowcs(dest_pathW, dest_path, wlen + 1))
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
|
||||||
|
return mdbx_env_copyW(env, dest_pathW, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBMDBX_API int mdbx_env_copyW(MDBX_env *env, const wchar_t *dest_path,
|
||||||
|
MDBX_copy_flags_t flags) {
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
int rc = check_env(env, true);
|
int rc = check_env(env, true);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
return rc;
|
return rc;
|
||||||
@ -20049,6 +20133,7 @@ __cold int mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !(defined(_WIN32) || defined(_WIN64))
|
||||||
__cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) {
|
__cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) {
|
||||||
int rc = check_env(env, true);
|
int rc = check_env(env, true);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
@ -20060,6 +20145,19 @@ __cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) {
|
|||||||
*arg = env->me_pathname;
|
*arg = env->me_pathname;
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
__cold int mdbx_env_get_pathW(const MDBX_env *env, const wchar_t **arg) {
|
||||||
|
int rc = check_env(env, true);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (unlikely(!arg))
|
||||||
|
return MDBX_EINVAL;
|
||||||
|
|
||||||
|
*arg = env->me_pathname;
|
||||||
|
return MDBX_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
__cold int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *arg) {
|
__cold int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *arg) {
|
||||||
int rc = check_env(env, true);
|
int rc = check_env(env, true);
|
||||||
|
@ -1143,7 +1143,7 @@ struct MDBX_env {
|
|||||||
MDBX_dbi me_maxdbs; /* size of the DB table */
|
MDBX_dbi me_maxdbs; /* size of the DB table */
|
||||||
uint32_t me_pid; /* process ID of this env */
|
uint32_t me_pid; /* process ID of this env */
|
||||||
mdbx_thread_key_t me_txkey; /* thread-key for readers */
|
mdbx_thread_key_t me_txkey; /* thread-key for readers */
|
||||||
char *me_pathname; /* path to the DB files */
|
pathchar_t *me_pathname; /* path to the DB files */
|
||||||
void *me_pbuf; /* scratch area for DUPSORT put() */
|
void *me_pbuf; /* scratch area for DUPSORT put() */
|
||||||
MDBX_txn *me_txn0; /* preallocated write transaction */
|
MDBX_txn *me_txn0; /* preallocated write transaction */
|
||||||
|
|
||||||
|
188
src/mdbx.c++
188
src/mdbx.c++
@ -201,64 +201,6 @@ __cold bug::~bug() noexcept {}
|
|||||||
|
|
||||||
#endif /* Unused*/
|
#endif /* Unused*/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <typename PATH> struct path_to_pchar {
|
|
||||||
const std::string str;
|
|
||||||
path_to_pchar(const PATH &path) : str(path.generic_string()) {}
|
|
||||||
operator const char *() const { return str.c_str(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PATH>
|
|
||||||
MDBX_MAYBE_UNUSED PATH pchar_to_path(const char *c_str) {
|
|
||||||
return PATH(c_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
|
||||||
|
|
||||||
#ifndef WC_ERR_INVALID_CHARS
|
|
||||||
static const DWORD WC_ERR_INVALID_CHARS =
|
|
||||||
(6 /* Windows Vista */ <= /* MajorVersion */ LOBYTE(LOWORD(GetVersion())))
|
|
||||||
? 0x00000080
|
|
||||||
: 0;
|
|
||||||
#endif /* WC_ERR_INVALID_CHARS */
|
|
||||||
|
|
||||||
template <> struct path_to_pchar<std::wstring> {
|
|
||||||
std::string str;
|
|
||||||
path_to_pchar(const std::wstring &path) {
|
|
||||||
if (!path.empty()) {
|
|
||||||
const int chars =
|
|
||||||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, path.data(),
|
|
||||||
int(path.size()), nullptr, 0, nullptr, nullptr);
|
|
||||||
if (chars == 0)
|
|
||||||
mdbx::error::throw_exception(GetLastError());
|
|
||||||
str.append(chars, '\0');
|
|
||||||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, path.data(),
|
|
||||||
int(path.size()), const_cast<char *>(str.data()),
|
|
||||||
chars, nullptr, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
operator const char *() const { return str.c_str(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
MDBX_MAYBE_UNUSED std::wstring pchar_to_path<std::wstring>(const char *c_str) {
|
|
||||||
std::wstring wstr;
|
|
||||||
if (c_str && *c_str) {
|
|
||||||
const int chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, c_str,
|
|
||||||
int(strlen(c_str)), nullptr, 0);
|
|
||||||
if (chars == 0)
|
|
||||||
mdbx::error::throw_exception(GetLastError());
|
|
||||||
wstr.append(chars, '\0');
|
|
||||||
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, c_str,
|
|
||||||
int(strlen(c_str)), const_cast<wchar_t *>(wstr.data()),
|
|
||||||
chars);
|
|
||||||
}
|
|
||||||
return wstr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* Windows */
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -1239,29 +1181,20 @@ bool env::is_pristine() const {
|
|||||||
|
|
||||||
bool env::is_empty() const { return get_stat().ms_leaf_pages == 0; }
|
bool env::is_empty() const { return get_stat().ms_leaf_pages == 0; }
|
||||||
|
|
||||||
#ifdef MDBX_STD_FILESYSTEM_PATH
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
env &env::copy(const MDBX_STD_FILESYSTEM_PATH &destination, bool compactify,
|
env &env::copy(const wchar_t *destination, bool compactify,
|
||||||
bool force_dynamic_size) {
|
bool force_dynamic_size) {
|
||||||
const path_to_pchar<MDBX_STD_FILESYSTEM_PATH> utf8(destination);
|
|
||||||
error::success_or_throw(
|
error::success_or_throw(
|
||||||
::mdbx_env_copy(handle_, utf8,
|
::mdbx_env_copyW(handle_, destination,
|
||||||
(compactify ? MDBX_CP_COMPACT : MDBX_CP_DEFAULTS) |
|
(compactify ? MDBX_CP_COMPACT : MDBX_CP_DEFAULTS) |
|
||||||
(force_dynamic_size ? MDBX_CP_FORCE_DYNAMIC_SIZE
|
(force_dynamic_size ? MDBX_CP_FORCE_DYNAMIC_SIZE
|
||||||
: MDBX_CP_DEFAULTS)));
|
: MDBX_CP_DEFAULTS)));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
|
||||||
env &env::copy(const ::std::wstring &destination, bool compactify,
|
env &env::copy(const ::std::wstring &destination, bool compactify,
|
||||||
bool force_dynamic_size) {
|
bool force_dynamic_size) {
|
||||||
const path_to_pchar<::std::wstring> utf8(destination);
|
return copy(destination.c_str(), compactify, force_dynamic_size);
|
||||||
error::success_or_throw(
|
|
||||||
::mdbx_env_copy(handle_, utf8,
|
|
||||||
(compactify ? MDBX_CP_COMPACT : MDBX_CP_DEFAULTS) |
|
|
||||||
(force_dynamic_size ? MDBX_CP_FORCE_DYNAMIC_SIZE
|
|
||||||
: MDBX_CP_DEFAULTS)));
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
|
|
||||||
@ -1289,26 +1222,33 @@ env &env::copy(filehandle fd, bool compactify, bool force_dynamic_size) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
path env::get_path() const {
|
|
||||||
const char *c_str;
|
|
||||||
error::success_or_throw(::mdbx_env_get_path(handle_, &c_str));
|
|
||||||
return pchar_to_path<path>(c_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MDBX_STD_FILESYSTEM_PATH
|
#ifdef MDBX_STD_FILESYSTEM_PATH
|
||||||
bool env::remove(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
env &env::copy(const MDBX_STD_FILESYSTEM_PATH &destination, bool compactify,
|
||||||
const remove_mode mode) {
|
bool force_dynamic_size) {
|
||||||
const path_to_pchar<MDBX_STD_FILESYSTEM_PATH> utf8(pathname);
|
return copy(destination.native(), compactify, force_dynamic_size);
|
||||||
return error::boolean_or_throw(
|
|
||||||
::mdbx_env_delete(utf8, MDBX_env_delete_mode_t(mode)));
|
|
||||||
}
|
}
|
||||||
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
||||||
|
|
||||||
|
path env::get_path() const {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
bool env::remove(const ::std::wstring &pathname, const remove_mode mode) {
|
const wchar_t *c_wstr;
|
||||||
const path_to_pchar<::std::wstring> utf8(pathname);
|
error::success_or_throw(::mdbx_env_get_pathW(handle_, &c_wstr));
|
||||||
|
return path(c_wstr);
|
||||||
|
#else
|
||||||
|
const char *c_str;
|
||||||
|
error::success_or_throw(::mdbx_env_get_path(handle_, &c_str));
|
||||||
|
return path(c_str);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
bool env::remove(const wchar_t *pathname, const remove_mode mode) {
|
||||||
return error::boolean_or_throw(
|
return error::boolean_or_throw(
|
||||||
::mdbx_env_delete(utf8, MDBX_env_delete_mode_t(mode)));
|
::mdbx_env_deleteW(pathname, MDBX_env_delete_mode_t(mode)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool env::remove(const ::std::wstring &pathname, const remove_mode mode) {
|
||||||
|
return remove(pathname.c_str(), mode);
|
||||||
}
|
}
|
||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
|
|
||||||
@ -1321,6 +1261,13 @@ bool env::remove(const ::std::string &pathname, const remove_mode mode) {
|
|||||||
return remove(pathname.c_str(), mode);
|
return remove(pathname.c_str(), mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MDBX_STD_FILESYSTEM_PATH
|
||||||
|
bool env::remove(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
||||||
|
const remove_mode mode) {
|
||||||
|
return remove(pathname.native(), mode);
|
||||||
|
}
|
||||||
|
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static inline MDBX_env *create_env() {
|
static inline MDBX_env *create_env() {
|
||||||
@ -1357,66 +1304,42 @@ __cold void env_managed::setup(unsigned max_maps, unsigned max_readers) {
|
|||||||
error::success_or_throw(::mdbx_env_set_maxdbs(handle_, max_maps));
|
error::success_or_throw(::mdbx_env_set_maxdbs(handle_, max_maps));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MDBX_STD_FILESYSTEM_PATH
|
|
||||||
__cold env_managed::env_managed(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
|
||||||
const operate_parameters &op, bool accede)
|
|
||||||
: env_managed(create_env()) {
|
|
||||||
setup(op.max_maps, op.max_readers);
|
|
||||||
const path_to_pchar<MDBX_STD_FILESYSTEM_PATH> utf8(pathname);
|
|
||||||
error::success_or_throw(
|
|
||||||
::mdbx_env_open(handle_, utf8, op.make_flags(accede), 0));
|
|
||||||
|
|
||||||
if (op.options.nested_write_transactions &&
|
|
||||||
!get_options().nested_write_transactions)
|
|
||||||
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
__cold env_managed::env_managed(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
|
||||||
const env_managed::create_parameters &cp,
|
|
||||||
const env::operate_parameters &op, bool accede)
|
|
||||||
: env_managed(create_env()) {
|
|
||||||
setup(op.max_maps, op.max_readers);
|
|
||||||
const path_to_pchar<MDBX_STD_FILESYSTEM_PATH> utf8(pathname);
|
|
||||||
set_geometry(cp.geometry);
|
|
||||||
error::success_or_throw(
|
|
||||||
::mdbx_env_open(handle_, utf8, op.make_flags(accede, cp.use_subdirectory),
|
|
||||||
cp.file_mode_bits));
|
|
||||||
|
|
||||||
if (op.options.nested_write_transactions &&
|
|
||||||
!get_options().nested_write_transactions)
|
|
||||||
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
|
||||||
}
|
|
||||||
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
__cold env_managed::env_managed(const ::std::wstring &pathname,
|
__cold env_managed::env_managed(const wchar_t *pathname,
|
||||||
const operate_parameters &op, bool accede)
|
const operate_parameters &op, bool accede)
|
||||||
: env_managed(create_env()) {
|
: env_managed(create_env()) {
|
||||||
setup(op.max_maps, op.max_readers);
|
setup(op.max_maps, op.max_readers);
|
||||||
const path_to_pchar<::std::wstring> utf8(pathname);
|
|
||||||
error::success_or_throw(
|
error::success_or_throw(
|
||||||
::mdbx_env_open(handle_, utf8, op.make_flags(accede), 0));
|
::mdbx_env_openW(handle_, pathname, op.make_flags(accede), 0));
|
||||||
|
|
||||||
if (op.options.nested_write_transactions &&
|
if (op.options.nested_write_transactions &&
|
||||||
!get_options().nested_write_transactions)
|
!get_options().nested_write_transactions)
|
||||||
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
__cold env_managed::env_managed(const ::std::wstring &pathname,
|
__cold env_managed::env_managed(const wchar_t *pathname,
|
||||||
const env_managed::create_parameters &cp,
|
const env_managed::create_parameters &cp,
|
||||||
const env::operate_parameters &op, bool accede)
|
const env::operate_parameters &op, bool accede)
|
||||||
: env_managed(create_env()) {
|
: env_managed(create_env()) {
|
||||||
setup(op.max_maps, op.max_readers);
|
setup(op.max_maps, op.max_readers);
|
||||||
const path_to_pchar<::std::wstring> utf8(pathname);
|
|
||||||
set_geometry(cp.geometry);
|
set_geometry(cp.geometry);
|
||||||
error::success_or_throw(
|
error::success_or_throw(::mdbx_env_openW(
|
||||||
::mdbx_env_open(handle_, utf8, op.make_flags(accede, cp.use_subdirectory),
|
handle_, pathname, op.make_flags(accede, cp.use_subdirectory),
|
||||||
cp.file_mode_bits));
|
cp.file_mode_bits));
|
||||||
|
|
||||||
if (op.options.nested_write_transactions &&
|
if (op.options.nested_write_transactions &&
|
||||||
!get_options().nested_write_transactions)
|
!get_options().nested_write_transactions)
|
||||||
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__cold env_managed::env_managed(const ::std::wstring &pathname,
|
||||||
|
const operate_parameters &op, bool accede)
|
||||||
|
: env_managed(pathname.c_str(), op, accede) {}
|
||||||
|
|
||||||
|
__cold env_managed::env_managed(const ::std::wstring &pathname,
|
||||||
|
const env_managed::create_parameters &cp,
|
||||||
|
const env::operate_parameters &op, bool accede)
|
||||||
|
: env_managed(pathname.c_str(), cp, op, accede) {}
|
||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
|
|
||||||
__cold env_managed::env_managed(const char *pathname,
|
__cold env_managed::env_managed(const char *pathname,
|
||||||
@ -1455,6 +1378,17 @@ __cold env_managed::env_managed(const ::std::string &pathname,
|
|||||||
const env::operate_parameters &op, bool accede)
|
const env::operate_parameters &op, bool accede)
|
||||||
: env_managed(pathname.c_str(), cp, op, accede) {}
|
: env_managed(pathname.c_str(), cp, op, accede) {}
|
||||||
|
|
||||||
|
#ifdef MDBX_STD_FILESYSTEM_PATH
|
||||||
|
__cold env_managed::env_managed(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
||||||
|
const operate_parameters &op, bool accede)
|
||||||
|
: env_managed(pathname.native(), op, accede) {}
|
||||||
|
|
||||||
|
__cold env_managed::env_managed(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
||||||
|
const env_managed::create_parameters &cp,
|
||||||
|
const env::operate_parameters &op, bool accede)
|
||||||
|
: env_managed(pathname.native(), cp, op, accede) {}
|
||||||
|
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
txn_managed txn::start_nested() {
|
txn_managed txn::start_nested() {
|
||||||
|
39
src/osal.c
39
src/osal.c
@ -518,15 +518,9 @@ MDBX_INTERNAL_FUNC int mdbx_fastmutex_release(mdbx_fastmutex_t *fastmutex) {
|
|||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC int mdbx_removefile(const char *pathname) {
|
MDBX_INTERNAL_FUNC int mdbx_removefile(const pathchar_t *pathname) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
return DeleteFileW(pathname) ? MDBX_SUCCESS : (int)GetLastError();
|
||||||
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
|
||||||
return ERROR_INVALID_NAME;
|
|
||||||
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
|
||||||
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
|
||||||
return ERROR_INVALID_NAME;
|
|
||||||
return DeleteFileW(pathnameW) ? MDBX_SUCCESS : (int)GetLastError();
|
|
||||||
#else
|
#else
|
||||||
return unlink(pathname) ? errno : MDBX_SUCCESS;
|
return unlink(pathname) ? errno : MDBX_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
@ -536,34 +530,22 @@ MDBX_INTERNAL_FUNC int mdbx_removefile(const char *pathname) {
|
|||||||
static bool is_valid_fd(int fd) { return !(isatty(fd) < 0 && errno == EBADF); }
|
static bool is_valid_fd(int fd) { return !(isatty(fd) < 0 && errno == EBADF); }
|
||||||
#endif /*! Windows */
|
#endif /*! Windows */
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC int mdbx_removedirectory(const char *pathname) {
|
MDBX_INTERNAL_FUNC int mdbx_removedirectory(const pathchar_t *pathname) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
return RemoveDirectoryW(pathname) ? MDBX_SUCCESS : (int)GetLastError();
|
||||||
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
|
||||||
return ERROR_INVALID_NAME;
|
|
||||||
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
|
||||||
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
|
||||||
return ERROR_INVALID_NAME;
|
|
||||||
return RemoveDirectoryW(pathnameW) ? MDBX_SUCCESS : (int)GetLastError();
|
|
||||||
#else
|
#else
|
||||||
return rmdir(pathname) ? errno : MDBX_SUCCESS;
|
return rmdir(pathname) ? errno : MDBX_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
||||||
const MDBX_env *env, const char *pathname,
|
const MDBX_env *env,
|
||||||
|
const pathchar_t *pathname,
|
||||||
mdbx_filehandle_t *fd,
|
mdbx_filehandle_t *fd,
|
||||||
mdbx_mode_t unix_mode_bits) {
|
mdbx_mode_t unix_mode_bits) {
|
||||||
*fd = INVALID_HANDLE_VALUE;
|
*fd = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
|
||||||
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
|
||||||
return ERROR_INVALID_NAME;
|
|
||||||
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
|
||||||
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
|
||||||
return ERROR_INVALID_NAME;
|
|
||||||
|
|
||||||
DWORD CreationDisposition = unix_mode_bits ? OPEN_ALWAYS : OPEN_EXISTING;
|
DWORD CreationDisposition = unix_mode_bits ? OPEN_ALWAYS : OPEN_EXISTING;
|
||||||
DWORD FlagsAndAttributes =
|
DWORD FlagsAndAttributes =
|
||||||
FILE_FLAG_POSIX_SEMANTICS | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
FILE_FLAG_POSIX_SEMANTICS | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
||||||
@ -608,12 +590,12 @@ MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*fd = CreateFileW(pathnameW, DesiredAccess, ShareMode, NULL,
|
*fd = CreateFileW(pathname, DesiredAccess, ShareMode, NULL,
|
||||||
CreationDisposition, FlagsAndAttributes, NULL);
|
CreationDisposition, FlagsAndAttributes, NULL);
|
||||||
if (*fd == INVALID_HANDLE_VALUE) {
|
if (*fd == INVALID_HANDLE_VALUE) {
|
||||||
int err = (int)GetLastError();
|
int err = (int)GetLastError();
|
||||||
if (err == ERROR_ACCESS_DENIED && purpose == MDBX_OPEN_LCK) {
|
if (err == ERROR_ACCESS_DENIED && purpose == MDBX_OPEN_LCK) {
|
||||||
if (GetFileAttributesW(pathnameW) == INVALID_FILE_ATTRIBUTES &&
|
if (GetFileAttributesW(pathname) == INVALID_FILE_ATTRIBUTES &&
|
||||||
GetLastError() == ERROR_FILE_NOT_FOUND)
|
GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||||
err = ERROR_FILE_NOT_FOUND;
|
err = ERROR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
@ -632,7 +614,7 @@ MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
|||||||
(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
|
(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
|
||||||
FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_COMPRESSED);
|
FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_COMPRESSED);
|
||||||
if (AttributesDiff)
|
if (AttributesDiff)
|
||||||
(void)SetFileAttributesW(pathnameW, info.dwFileAttributes ^ AttributesDiff);
|
(void)SetFileAttributesW(pathname, info.dwFileAttributes ^ AttributesDiff);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
int flags = unix_mode_bits ? O_CREAT : 0;
|
int flags = unix_mode_bits ? O_CREAT : 0;
|
||||||
@ -1089,7 +1071,8 @@ MDBX_INTERNAL_FUNC int mdbx_msync(mdbx_mmap_t *map, size_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC int mdbx_check_fs_rdonly(mdbx_filehandle_t handle,
|
MDBX_INTERNAL_FUNC int mdbx_check_fs_rdonly(mdbx_filehandle_t handle,
|
||||||
const char *pathname, int err) {
|
const pathchar_t *pathname,
|
||||||
|
int err) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
(void)pathname;
|
(void)pathname;
|
||||||
(void)err;
|
(void)err;
|
||||||
|
16
src/osal.h
16
src/osal.h
@ -224,6 +224,12 @@ mdbx_syspagesize(void) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
typedef wchar_t pathchar_t;
|
||||||
|
#else
|
||||||
|
typedef char pathchar_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct mdbx_mmap_param {
|
typedef struct mdbx_mmap_param {
|
||||||
union {
|
union {
|
||||||
void *address;
|
void *address;
|
||||||
@ -365,12 +371,13 @@ enum mdbx_openfile_purpose {
|
|||||||
};
|
};
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
||||||
const MDBX_env *env, const char *pathname,
|
const MDBX_env *env,
|
||||||
|
const pathchar_t *pathname,
|
||||||
mdbx_filehandle_t *fd,
|
mdbx_filehandle_t *fd,
|
||||||
mdbx_mode_t unix_mode_bits);
|
mdbx_mode_t unix_mode_bits);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_closefile(mdbx_filehandle_t fd);
|
MDBX_INTERNAL_FUNC int mdbx_closefile(mdbx_filehandle_t fd);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_removefile(const char *pathname);
|
MDBX_INTERNAL_FUNC int mdbx_removefile(const pathchar_t *pathname);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_removedirectory(const char *pathname);
|
MDBX_INTERNAL_FUNC int mdbx_removedirectory(const pathchar_t *pathname);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_is_pipe(mdbx_filehandle_t fd);
|
MDBX_INTERNAL_FUNC int mdbx_is_pipe(mdbx_filehandle_t fd);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_lockfile(mdbx_filehandle_t fd, bool wait);
|
MDBX_INTERNAL_FUNC int mdbx_lockfile(mdbx_filehandle_t fd, bool wait);
|
||||||
|
|
||||||
@ -398,7 +405,8 @@ MDBX_INTERNAL_FUNC int mdbx_msync(mdbx_mmap_t *map, size_t offset,
|
|||||||
size_t length,
|
size_t length,
|
||||||
enum mdbx_syncmode_bits mode_bits);
|
enum mdbx_syncmode_bits mode_bits);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_check_fs_rdonly(mdbx_filehandle_t handle,
|
MDBX_INTERNAL_FUNC int mdbx_check_fs_rdonly(mdbx_filehandle_t handle,
|
||||||
const char *pathname, int err);
|
const pathchar_t *pathname,
|
||||||
|
int err);
|
||||||
|
|
||||||
MDBX_MAYBE_UNUSED static __inline uint32_t mdbx_getpid(void) {
|
MDBX_MAYBE_UNUSED static __inline uint32_t mdbx_getpid(void) {
|
||||||
STATIC_ASSERT(sizeof(mdbx_pid_t) <= sizeof(uint32_t));
|
STATIC_ASSERT(sizeof(mdbx_pid_t) <= sizeof(uint32_t));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user