mdbx: add getenv_bool() and fetching debug-options from the process environment.

This commit is contained in:
Леонид Юрьев (Leonid Yuriev)
2025-10-14 23:48:58 +03:00
parent 0d9b59dda1
commit 8b2aa9fb65
4 changed files with 77 additions and 25 deletions

View File

@@ -176,8 +176,29 @@ __cold static __attribute__((__destructor__)) void mdbx_global_destructor(void)
struct libmdbx_globals globals;
static bool getenv_bool(const char *name, bool default_value) {
const char *value = osal_getenv(name, false);
if (value) {
if (*value == 0 /* implied ON */)
return true;
if (strcasecmp(value, "yes") == 0 || strcasecmp(value, "on") == 0 || strcasecmp(value, "true") == 0 ||
strcasecmp(value, "1") == 0)
return true;
if (strcasecmp(value, "no") == 0 || strcasecmp(value, "off") == 0 || strcasecmp(value, "false") == 0 ||
strcasecmp(value, "0") == 0)
return false;
}
return default_value;
}
__cold static void mdbx_init(void) {
globals.runtime_flags = ((MDBX_DEBUG) > 0) * MDBX_DBG_ASSERT + ((MDBX_DEBUG) > 1) * MDBX_DBG_AUDIT;
globals.runtime_flags = (getenv_bool("MDBX_DBG_ASSERT", (MDBX_DEBUG) > 0) ? MDBX_DBG_ASSERT : 0) |
(getenv_bool("MDBX_DBG_AUDIT", (MDBX_DEBUG) > 1) ? MDBX_DBG_AUDIT : 0) |
(getenv_bool("MDBX_DBG_JITTER", false) ? MDBX_DBG_JITTER : 0) |
(getenv_bool("MDBX_DBG_DUMP", false) ? MDBX_DBG_DUMP : 0) |
(getenv_bool("MDBX_DBG_LEGACY_MULTIOPEN", false) ? MDBX_DBG_LEGACY_MULTIOPEN : 0) |
(getenv_bool("MDBX_DBG_LEGACY_OVERLAP", false) ? MDBX_DBG_LEGACY_OVERLAP : 0) |
(getenv_bool("MDBX_DBG_DONT_UPGRADE", false) ? MDBX_DBG_DONT_UPGRADE : 0);
globals.loglevel = MDBX_LOG_FATAL;
ENSURE(nullptr, osal_fastmutex_init(&globals.debug_lock) == 0);
osal_ctor();

View File

@@ -1777,8 +1777,8 @@ int osal_check_fs_incore(mdbx_filehandle_t handle) {
const size_t name_len = 0;
#endif
if (name_len) {
if (osal_strncasecmp("tmpfs", name, 6) == 0 || osal_strncasecmp("mfs", name, 4) == 0 ||
osal_strncasecmp("ramfs", name, 6) == 0 || osal_strncasecmp("romfs", name, 6) == 0)
if (strncasecmp("tmpfs", name, 6) == 0 || strncasecmp("mfs", name, 4) == 0 || strncasecmp("ramfs", name, 6) == 0 ||
strncasecmp("romfs", name, 6) == 0)
return MDBX_RESULT_TRUE;
}
#endif /* !Windows */
@@ -1990,14 +1990,13 @@ int osal_check_fs_local(mdbx_filehandle_t handle, int flags) {
#endif
if (name_len) {
if (((name_len > 2 && osal_strncasecmp("nfs", name, 3) == 0) || osal_strncasecmp("cifs", name, name_len) == 0 ||
osal_strncasecmp("ncpfs", name, name_len) == 0 || osal_strncasecmp("smbfs", name, name_len) == 0 ||
osal_strcasecmp("9P" /* WSL2 */, name) == 0 ||
((name_len > 3 && osal_strncasecmp("fuse", name, 4) == 0) &&
osal_strncasecmp("fuseblk", name, name_len) != 0)) &&
if (((name_len > 2 && strncasecmp("nfs", name, 3) == 0) || strncasecmp("cifs", name, name_len) == 0 ||
strncasecmp("ncpfs", name, name_len) == 0 || strncasecmp("smbfs", name, name_len) == 0 ||
strcasecmp("9P" /* WSL2 */, name) == 0 ||
((name_len > 3 && strncasecmp("fuse", name, 4) == 0) && strncasecmp("fuseblk", name, name_len) != 0)) &&
!(flags & MDBX_EXCLUSIVE))
return MDBX_EREMOTE;
if (osal_strcasecmp("ftp", name) == 0 || osal_strcasecmp("http", name) == 0 || osal_strcasecmp("sshfs", name) == 0)
if (strcasecmp("ftp", name) == 0 || strcasecmp("http", name) == 0 || strcasecmp("sshfs", name) == 0)
return MDBX_EREMOTE;
}
@@ -3475,6 +3474,35 @@ bin128_t osal_guid(const MDBX_env *env) {
return uuid;
}
const char *osal_getenv(const char *name, bool secure) {
(void)secure;
#if defined(_WIN32) || defined(_WIN64)
static char buf[42];
SetLastError(ERROR_OUT_OF_PAPER);
const size_t len = GetEnvironmentVariableA(name, buf, sizeof(buf));
if (len >= sizeof(buf))
/* no idea haw to handle */
return nullptr;
if (len != 0)
return buf;
switch (GetLastError()) {
case ERROR_OUT_OF_PAPER:
return "";
default:
/* no idea to do in case of other error */
case ERROR_ENVVAR_NOT_FOUND:
return nullptr;
}
return (GetLastError() == ERROR_ENVVAR_NOT_FOUND) ? nullptr : "";
#else
#if defined(_GNU_SOURCE) && __GLIBC_PREREQ(2, 17)
if (secure)
return secure_getenv(name);
#endif /* glibc >= 2.17 */
return getenv(name);
#endif
}
/*--------------------------------------------------------------------------*/
void osal_ctor(void) {

View File

@@ -122,8 +122,6 @@ static inline void osal_free(void *ptr) { HeapFree(GetProcessHeap(), 0, ptr); }
#define osal_realloc realloc
#define osal_free free
#define osal_strdup _strdup
#define osal_strcasecmp _stricmp
#define osal_strncasecmp _strnicmp
#endif /* MDBX_WITHOUT_MSVC_CRT */
@@ -135,6 +133,14 @@ static inline void osal_free(void *ptr) { HeapFree(GetProcessHeap(), 0, ptr); }
#define vsnprintf _vsnprintf /* ntdll */
#endif
#ifndef strcasecmp
#define strcasecmp _stricmp /* ntdll */
#endif
#ifndef strncasecmp
#define strncasecmp _strnicmp /* ntdll */
#endif
#else /*----------------------------------------------------------------------*/
typedef pthread_t osal_thread_t;
@@ -152,8 +158,6 @@ typedef pthread_mutex_t osal_fastmutex_t;
#define osal_realloc realloc
#define osal_free free
#define osal_strdup strdup
#define osal_strcasecmp strcasecmp
#define osal_strncasecmp strncasecmp
#endif /* Platform */
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(malloc_usable_size)
@@ -471,6 +475,7 @@ MDBX_MAYBE_UNUSED static inline bool osal_isdirsep(pathchar_t c) {
c == '/';
}
MDBX_INTERNAL const char *osal_getenv(const char *name, bool secure);
MDBX_INTERNAL bool osal_pathequal(const pathchar_t *l, const pathchar_t *r, size_t len);
MDBX_INTERNAL pathchar_t *osal_fileext(const pathchar_t *pathname, size_t len);
MDBX_INTERNAL int osal_fileexists(const pathchar_t *pathname);

View File

@@ -152,21 +152,21 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option, u
if (suffix && *suffix) {
if (scale == no_scale || scale == intkey)
failure("Option '--%s' doesn't accepts suffixes, so '%s' is unexpected\n", option, suffix);
if (strcmp(suffix, "K") == 0 || osal_strcasecmp(suffix, "Kilo") == 0)
if (strcmp(suffix, "K") == 0 || strcasecmp(suffix, "Kilo") == 0)
multiplier = (scale == decimal) ? UINT64_C(1000) : UINT64_C(1024);
else if (strcmp(suffix, "M") == 0 || osal_strcasecmp(suffix, "Mega") == 0)
else if (strcmp(suffix, "M") == 0 || strcasecmp(suffix, "Mega") == 0)
multiplier = (scale == decimal) ? UINT64_C(1000) * 1000 : UINT64_C(1024) * 1024;
else if (strcmp(suffix, "G") == 0 || osal_strcasecmp(suffix, "Giga") == 0)
else if (strcmp(suffix, "G") == 0 || strcasecmp(suffix, "Giga") == 0)
multiplier = (scale == decimal) ? UINT64_C(1000) * 1000 * 1000 : UINT64_C(1024) * 1024 * 1024;
else if (strcmp(suffix, "T") == 0 || osal_strcasecmp(suffix, "Tera") == 0)
else if (strcmp(suffix, "T") == 0 || strcasecmp(suffix, "Tera") == 0)
multiplier = (scale == decimal) ? UINT64_C(1000) * 1000 * 1000 * 1000 : UINT64_C(1024) * 1024 * 1024 * 1024;
else if (scale == duration && (strcmp(suffix, "s") == 0 || osal_strcasecmp(suffix, "Seconds") == 0))
else if (scale == duration && (strcmp(suffix, "s") == 0 || strcasecmp(suffix, "Seconds") == 0))
multiplier = 1;
else if (scale == duration && (strcmp(suffix, "m") == 0 || osal_strcasecmp(suffix, "Minutes") == 0))
else if (scale == duration && (strcmp(suffix, "m") == 0 || strcasecmp(suffix, "Minutes") == 0))
multiplier = 60;
else if (scale == duration && (strcmp(suffix, "h") == 0 || osal_strcasecmp(suffix, "Hours") == 0))
else if (scale == duration && (strcmp(suffix, "h") == 0 || strcasecmp(suffix, "Hours") == 0))
multiplier = 3600;
else if (scale == duration && (strcmp(suffix, "d") == 0 || osal_strcasecmp(suffix, "Days") == 0))
else if (scale == duration && (strcmp(suffix, "d") == 0 || strcasecmp(suffix, "Days") == 0))
multiplier = 3600 * 24;
else
failure("Option '--%s' expects a numeric value with Kilo/Mega/Giga/Tera %s"
@@ -309,14 +309,12 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option, b
return true;
}
if (osal_strcasecmp(value_cstr, "yes") == 0 || osal_strcasecmp(value_cstr, "1") == 0 ||
osal_strcasecmp(value_cstr, "on") == 0) {
if (strcasecmp(value_cstr, "yes") == 0 || strcasecmp(value_cstr, "1") == 0 || strcasecmp(value_cstr, "on") == 0) {
value = true;
return true;
}
if (osal_strcasecmp(value_cstr, "no") == 0 || osal_strcasecmp(value_cstr, "0") == 0 ||
osal_strcasecmp(value_cstr, "off") == 0) {
if (strcasecmp(value_cstr, "no") == 0 || strcasecmp(value_cstr, "0") == 0 || strcasecmp(value_cstr, "off") == 0) {
value = false;
return true;
}