mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-30 01:34:14 +08:00
mdbx: корректировка отключения MDBX_NOSUBDIR
при открытии mdbx.dat
без директории.
This commit is contained in:
parent
f2a49b687a
commit
08fb7d5838
71
src/core.c
71
src/core.c
@ -14461,22 +14461,6 @@ typedef struct {
|
||||
size_t ent_len;
|
||||
} 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 handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||
const pathchar_t *pathname,
|
||||
MDBX_env_flags_t *flags,
|
||||
@ -14515,7 +14499,7 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||
if (rc != MDBX_ENOFILE)
|
||||
return rc;
|
||||
if (mode == 0 || (*flags & MDBX_RDONLY) != 0)
|
||||
/* can't open existing */
|
||||
/* can't open non-existing */
|
||||
return rc /* MDBX_ENOFILE */;
|
||||
|
||||
/* auto-create directory if requested */
|
||||
@ -14549,36 +14533,51 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||
assert(dxb_name[0] == '/' && lck_name[0] == '/');
|
||||
const size_t pathname_len = strlen(pathname);
|
||||
#endif
|
||||
assert(lock_suffix[0] != '\\' && lock_suffix[0] != '/');
|
||||
assert(!osal_isdirsep(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;
|
||||
ctx->ent_len -= dxb_name_len;
|
||||
if (*flags & MDBX_NOSUBDIR) {
|
||||
if (ctx->ent_len > dxb_name_len &&
|
||||
osal_pathequal(pathname + ctx->ent_len - dxb_name_len, dxb_name,
|
||||
dxb_name_len)) {
|
||||
*flags -= MDBX_NOSUBDIR;
|
||||
ctx->ent_len -= dxb_name_len;
|
||||
} else if (ctx->ent_len == dxb_name_len - 1 && osal_isdirsep(dxb_name[0]) &&
|
||||
osal_isdirsep(lck_name[0]) &&
|
||||
osal_pathequal(pathname + ctx->ent_len - dxb_name_len + 1,
|
||||
dxb_name + 1, dxb_name_len - 1)) {
|
||||
*flags -= MDBX_NOSUBDIR;
|
||||
ctx->ent_len -= dxb_name_len - 1;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t bytes_needed =
|
||||
sizeof(pathchar_t) * ctx->ent_len * 2 +
|
||||
((*flags & MDBX_NOSUBDIR) ? sizeof(lock_suffix) + sizeof(pathchar_t)
|
||||
: sizeof(lck_name) + sizeof(dxb_name));
|
||||
const size_t suflen_with_NOSUBDIR = sizeof(lock_suffix) + sizeof(pathchar_t);
|
||||
const size_t suflen_without_NOSUBDIR = sizeof(lck_name) + sizeof(dxb_name);
|
||||
const size_t enogh4any = (suflen_with_NOSUBDIR > suflen_without_NOSUBDIR)
|
||||
? suflen_with_NOSUBDIR
|
||||
: suflen_without_NOSUBDIR;
|
||||
const size_t bytes_needed = sizeof(pathchar_t) * ctx->ent_len * 2 + enogh4any;
|
||||
ctx->buffer_for_free = osal_malloc(bytes_needed);
|
||||
if (!ctx->buffer_for_free)
|
||||
return MDBX_ENOMEM;
|
||||
|
||||
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) {
|
||||
memcpy(ctx->lck + ctx->ent_len, lock_suffix, sizeof(lock_suffix));
|
||||
if (ctx->ent_len) {
|
||||
ctx->lck = ctx->dxb + ctx->ent_len + 1;
|
||||
memcpy(ctx->dxb, pathname, sizeof(pathchar_t) * (ctx->ent_len + 1));
|
||||
if (*flags & MDBX_NOSUBDIR) {
|
||||
memcpy(ctx->lck + ctx->ent_len, lock_suffix, sizeof(lock_suffix));
|
||||
} else {
|
||||
ctx->lck += dxb_name_len;
|
||||
memcpy(ctx->lck + ctx->ent_len, lck_name, sizeof(lck_name));
|
||||
memcpy(ctx->dxb + ctx->ent_len, dxb_name, sizeof(dxb_name));
|
||||
}
|
||||
memcpy(ctx->lck, pathname, sizeof(pathchar_t) * ctx->ent_len);
|
||||
} else {
|
||||
ctx->lck += dxb_name_len;
|
||||
memcpy(ctx->lck + ctx->ent_len, lck_name, sizeof(lck_name));
|
||||
memcpy(ctx->dxb + ctx->ent_len, dxb_name, sizeof(dxb_name));
|
||||
ctx->lck = ctx->dxb + dxb_name_len;
|
||||
memcpy(ctx->lck, lck_name + 1, sizeof(lck_name) - sizeof(pathchar_t));
|
||||
memcpy(ctx->dxb, dxb_name + 1, sizeof(dxb_name) - sizeof(pathchar_t));
|
||||
}
|
||||
memcpy(ctx->lck, pathname, sizeof(pathchar_t) * ctx->ent_len);
|
||||
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
|
17
src/osal.c
17
src/osal.c
@ -1185,6 +1185,23 @@ MDBX_INTERNAL_FUNC int osal_removedirectory(const pathchar_t *pathname) {
|
||||
#endif
|
||||
}
|
||||
|
||||
MDBX_INTERNAL_FUNC bool osal_pathequal(const pathchar_t *l, const pathchar_t *r,
|
||||
size_t len) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
pathchar_t a = l[i];
|
||||
pathchar_t b = r[i];
|
||||
a = (a == '\\') ? '/' : a;
|
||||
b = (b == '\\') ? '/' : b;
|
||||
if (a != b)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return memcmp(l, r, len * sizeof(pathchar_t)) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
MDBX_INTERNAL_FUNC int osal_openfile(const enum osal_openfile_purpose purpose,
|
||||
const MDBX_env *env,
|
||||
const pathchar_t *pathname,
|
||||
|
10
src/osal.h
10
src/osal.h
@ -549,6 +549,16 @@ enum osal_openfile_purpose {
|
||||
MDBX_OPEN_DELETE
|
||||
};
|
||||
|
||||
MDBX_MAYBE_UNUSED static __inline bool osal_isdirsep(pathchar_t c) {
|
||||
return
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
c == '\\' ||
|
||||
#endif
|
||||
c == '/';
|
||||
}
|
||||
|
||||
MDBX_INTERNAL_FUNC bool osal_pathequal(const pathchar_t *l, const pathchar_t *r,
|
||||
size_t len);
|
||||
MDBX_INTERNAL_FUNC int osal_openfile(const enum osal_openfile_purpose purpose,
|
||||
const MDBX_env *env,
|
||||
const pathchar_t *pathname,
|
||||
|
Loading…
x
Reference in New Issue
Block a user