mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-01 22:54:12 +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;
|
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 handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
__cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||||
const pathchar_t *pathname,
|
const pathchar_t *pathname,
|
||||||
MDBX_env_flags_t *flags,
|
MDBX_env_flags_t *flags,
|
||||||
@ -14515,7 +14499,7 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
|||||||
if (rc != MDBX_ENOFILE)
|
if (rc != MDBX_ENOFILE)
|
||||||
return rc;
|
return rc;
|
||||||
if (mode == 0 || (*flags & MDBX_RDONLY) != 0)
|
if (mode == 0 || (*flags & MDBX_RDONLY) != 0)
|
||||||
/* can't open existing */
|
/* can't open non-existing */
|
||||||
return rc /* MDBX_ENOFILE */;
|
return rc /* MDBX_ENOFILE */;
|
||||||
|
|
||||||
/* auto-create directory if requested */
|
/* 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] == '/');
|
assert(dxb_name[0] == '/' && lck_name[0] == '/');
|
||||||
const size_t pathname_len = strlen(pathname);
|
const size_t pathname_len = strlen(pathname);
|
||||||
#endif
|
#endif
|
||||||
assert(lock_suffix[0] != '\\' && lock_suffix[0] != '/');
|
assert(!osal_isdirsep(lock_suffix[0]));
|
||||||
ctx->ent_len = pathname_len;
|
ctx->ent_len = pathname_len;
|
||||||
static const size_t dxb_name_len = ARRAY_LENGTH(dxb_name) - 1;
|
static const size_t dxb_name_len = ARRAY_LENGTH(dxb_name) - 1;
|
||||||
if ((*flags & MDBX_NOSUBDIR) && ctx->ent_len > dxb_name_len &&
|
if (*flags & MDBX_NOSUBDIR) {
|
||||||
path_equal(pathname + ctx->ent_len - dxb_name_len, dxb_name,
|
if (ctx->ent_len > dxb_name_len &&
|
||||||
dxb_name_len)) {
|
osal_pathequal(pathname + ctx->ent_len - dxb_name_len, dxb_name,
|
||||||
*flags -= MDBX_NOSUBDIR;
|
dxb_name_len)) {
|
||||||
ctx->ent_len -= 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 =
|
const size_t suflen_with_NOSUBDIR = sizeof(lock_suffix) + sizeof(pathchar_t);
|
||||||
sizeof(pathchar_t) * ctx->ent_len * 2 +
|
const size_t suflen_without_NOSUBDIR = sizeof(lck_name) + sizeof(dxb_name);
|
||||||
((*flags & MDBX_NOSUBDIR) ? sizeof(lock_suffix) + sizeof(pathchar_t)
|
const size_t enogh4any = (suflen_with_NOSUBDIR > suflen_without_NOSUBDIR)
|
||||||
: sizeof(lck_name) + sizeof(dxb_name));
|
? 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);
|
ctx->buffer_for_free = osal_malloc(bytes_needed);
|
||||||
if (!ctx->buffer_for_free)
|
if (!ctx->buffer_for_free)
|
||||||
return MDBX_ENOMEM;
|
return MDBX_ENOMEM;
|
||||||
|
|
||||||
ctx->dxb = ctx->buffer_for_free;
|
ctx->dxb = ctx->buffer_for_free;
|
||||||
ctx->lck = ctx->dxb + ctx->ent_len + 1;
|
if (ctx->ent_len) {
|
||||||
memcpy(ctx->dxb, pathname, sizeof(pathchar_t) * (ctx->ent_len + 1));
|
ctx->lck = ctx->dxb + ctx->ent_len + 1;
|
||||||
if (*flags & MDBX_NOSUBDIR) {
|
memcpy(ctx->dxb, pathname, sizeof(pathchar_t) * (ctx->ent_len + 1));
|
||||||
memcpy(ctx->lck + ctx->ent_len, lock_suffix, sizeof(lock_suffix));
|
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 {
|
} else {
|
||||||
ctx->lck += dxb_name_len;
|
ctx->lck = ctx->dxb + dxb_name_len;
|
||||||
memcpy(ctx->lck + ctx->ent_len, lck_name, sizeof(lck_name));
|
memcpy(ctx->lck, lck_name + 1, sizeof(lck_name) - sizeof(pathchar_t));
|
||||||
memcpy(ctx->dxb + ctx->ent_len, dxb_name, sizeof(dxb_name));
|
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;
|
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
|
#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,
|
MDBX_INTERNAL_FUNC int osal_openfile(const enum osal_openfile_purpose purpose,
|
||||||
const MDBX_env *env,
|
const MDBX_env *env,
|
||||||
const pathchar_t *pathname,
|
const pathchar_t *pathname,
|
||||||
|
10
src/osal.h
10
src/osal.h
@ -549,6 +549,16 @@ enum osal_openfile_purpose {
|
|||||||
MDBX_OPEN_DELETE
|
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,
|
MDBX_INTERNAL_FUNC int osal_openfile(const enum osal_openfile_purpose purpose,
|
||||||
const MDBX_env *env,
|
const MDBX_env *env,
|
||||||
const pathchar_t *pathname,
|
const pathchar_t *pathname,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user