From c04881ef8a6d765cd5d90f81646b737621cec003 Mon Sep 17 00:00:00 2001 From: daan Date: Thu, 13 Feb 2020 17:59:43 -0800 Subject: [PATCH] add getcwd and fullpath wrappers --- include/mimalloc-internal.h | 1 + include/mimalloc-override.h | 18 +++-- include/mimalloc.h | 65 ++++++++------- src/alloc-override.c | 7 ++ src/alloc-posix.c | 157 ++++++++++++++++++++++++++---------- src/alloc.c | 38 +++++---- test/main-override.cpp | 2 +- 7 files changed, 196 insertions(+), 92 deletions(-) diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index 5c989092..cd49e39e 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -127,6 +127,7 @@ void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size MI_SO mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p); bool _mi_free_delayed_block(mi_block_t* block); void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size); +size_t _mi_path_max(void); mi_decl_restrict void* _mi_base_malloc_zero(mi_heap_t* heap, size_t size, bool zero MI_SOURCE_XPARAM) mi_attr_malloc mi_attr_alloc_size(2); void* _mi_base_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero MI_SOURCE_XPARAM) mi_attr_alloc_size(2); diff --git a/include/mimalloc-override.h b/include/mimalloc-override.h index 55041d8f..74202ac3 100644 --- a/include/mimalloc-override.h +++ b/include/mimalloc-override.h @@ -27,17 +27,25 @@ not accidentally mix pointers from different allocators). #define strndup(s) mi_strndup(s) #define realpath(f,n) mi_realpath(f,n) +#define wcsdup(s) mi_wcsdup(s) +#define mbsdup(s) mi_mbsdup(s) +#define getcwd(b,n) mi_getcwd(b,n) + // Microsoft extensions -#define _expand(p,n) mi_expand(p,n) +#define _expand(p,n) mi__expand(p,n) #define _msize(p) mi_usable_size(p) #define _recalloc(p,n,c) mi_recalloc(p,n,c) #define _strdup(s) mi_strdup(s) #define _strndup(s) mi_strndup(s) -#define _wcsdup(s) (wchar_t*)mi_wcsdup((const unsigned short*)(s)) +#define _wcsdup(s) mi_wcsdup(s) #define _mbsdup(s) mi_mbsdup(s) -#define _dupenv_s(b,n,v) mi_dupenv_s(b,n,v) -#define _wdupenv_s(b,n,v) mi_wdupenv_s((unsigned short*)(b),n,(const unsigned short*)(v)) +#define _getcwd(b,n) mi_getcwd(b,n) +#define _dupenv_s(b,n,v) mi__dupenv_s(b,n,v) +#define _wdupenv_s(b,n,v) mi__wdupenv_s(b,n,v) +#define _fullpath(b,p,n) mi__fullpath(b,p,n) +#define _wfullpath(b,p,n) mi__wfullpath(b,p,n) +#define _wgetcwd(b,n) mi__wgetcwd(b,n) // Various Posix and Unix variants #define reallocf(p,n) mi_reallocf(p,n) @@ -56,7 +64,7 @@ not accidentally mix pointers from different allocators). // Microsoft aligned variants #define _aligned_malloc(n,a) mi_malloc_aligned(n,a) #define _aligned_realloc(p,n,a) mi_realloc_aligned(p,n,a) -#define _aligned_recalloc(p,s,n,a) mi_aligned_recalloc(p,s,n,a) +#define _aligned_recalloc(p,s,n,a) mi_recalloc_aligned(p,s,n,a) #define _aligned_msize(p,a,o) mi_usable_size(p) #define _aligned_free(p) mi_free(p) #define _aligned_offset_malloc(n,a,o) mi_malloc_aligned_at(n,a,o) diff --git a/include/mimalloc.h b/include/mimalloc.h index 9ec8fc23..9b161ab8 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -86,6 +86,7 @@ terms of the MIT license. A copy of the license can be found in the file #include // size_t #include // bool +#include // wchar_t #ifdef __cplusplus extern "C" { @@ -110,15 +111,15 @@ mi_decl_export mi_source_t mi_source_loc(const char* fname, int lineno); mi_decl_export void* mi_source_unpack(mi_source_t source, const char** fname, int* lineno); #define mi_declx(tp,name,attrs,...) \ - mi_decl_export tp dbg_##name( __VA_ARGS__, mi_source_t dbg_source) attrs; \ - mi_decl_export tp name(__VA_ARGS__) attrs + tp dbg_##name( __VA_ARGS__, mi_source_t dbg_source) attrs; \ + tp name(__VA_ARGS__) attrs #endif -#define mi_decl_malloc(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_restrict tp, name, mi_attr_noexcept mi_attr_malloc, __VA_ARGS__) -#define mi_decl_new(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_restrict tp, name, mi_attr_malloc, __VA_ARGS__) -#define mi_decl_realloc(tp,name,...) mi_declx(mi_decl_nodiscard tp, name, mi_attr_noexcept, __VA_ARGS__) -#define mi_decl_noexcpt(tp,name,...) mi_declx(tp, name, mi_attr_noexcept, __VA_ARGS__) +#define mi_decl_malloc(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_export mi_decl_restrict tp, name, mi_attr_noexcept mi_attr_malloc, __VA_ARGS__) +#define mi_decl_new(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_export mi_decl_restrict tp, name, mi_attr_malloc, __VA_ARGS__) +#define mi_decl_realloc(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_export tp, name, mi_attr_noexcept, __VA_ARGS__) +#define mi_decl_noexcpt(tp,name,...) mi_declx(mi_decl_export tp, name, mi_attr_noexcept, __VA_ARGS__) // ------------------------------------------------------ @@ -152,8 +153,8 @@ mi_decl_malloc( void*, mi_mallocn, size_t count, size_t size) mi_attr mi_decl_realloc(void*, mi_reallocn, void* p, size_t count, size_t size) mi_attr_alloc_size2(2,3); mi_decl_realloc(void*, mi_reallocf, void* p, size_t newsize) mi_attr_alloc_size(2); -mi_decl_export mi_decl_nodiscard size_t mi_usable_size(const void* p) mi_attr_noexcept; -mi_decl_export mi_decl_nodiscard size_t mi_good_size(size_t size) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept; // ------------------------------------------------------ @@ -206,7 +207,7 @@ mi_decl_realloc(void*, mi_realloc_aligned_at, void* p, size_t newsize, size_t al struct mi_heap_s; typedef struct mi_heap_s mi_heap_t; -mi_decl_export mi_decl_nodiscard mi_heap_t* mi_heap_new(void); +mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new(void); mi_decl_export void mi_heap_delete(mi_heap_t* heap); mi_decl_export void mi_heap_destroy(mi_heap_t* heap); mi_decl_export mi_heap_t* mi_heap_set_default(mi_heap_t* heap); @@ -266,9 +267,9 @@ mi_decl_realloc(void*, mi_heap_recalloc_aligned_at, mi_heap_t* heap, void* p, si // Analysis // ------------------------------------------------------ -mi_decl_export mi_decl_nodiscard bool mi_heap_contains_block(mi_heap_t* heap, const void* p); -mi_decl_export mi_decl_nodiscard bool mi_heap_check_owned(mi_heap_t* heap, const void* p); -mi_decl_export mi_decl_nodiscard bool mi_check_owned(const void* p); +mi_decl_nodiscard mi_decl_export bool mi_heap_contains_block(mi_heap_t* heap, const void* p); +mi_decl_nodiscard mi_decl_export bool mi_heap_check_owned(mi_heap_t* heap, const void* p); +mi_decl_nodiscard mi_decl_export bool mi_check_owned(const void* p); // An area of heap space contains blocks of a single size. typedef struct mi_heap_area_s { @@ -284,8 +285,8 @@ typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_ mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg); // Experimental -mi_decl_export mi_decl_nodiscard bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; -mi_decl_export mi_decl_nodiscard bool mi_is_redirected() mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export bool mi_is_redirected() mi_attr_noexcept; mi_decl_export int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept; mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept; @@ -342,13 +343,13 @@ typedef enum mi_option_e { } mi_option_t; -mi_decl_export mi_decl_nodiscard bool mi_option_is_enabled(mi_option_t option); +mi_decl_nodiscard mi_decl_export bool mi_option_is_enabled(mi_option_t option); mi_decl_export void mi_option_enable(mi_option_t option); mi_decl_export void mi_option_disable(mi_option_t option); mi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable); mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable); -mi_decl_export mi_decl_nodiscard long mi_option_get(mi_option_t option); +mi_decl_nodiscard mi_decl_export long mi_option_get(mi_option_t option); mi_decl_export void mi_option_set(mi_option_t option, long value); mi_decl_export void mi_option_set_default(mi_option_t option, long value); @@ -359,8 +360,8 @@ mi_decl_export void mi_option_set_default(mi_option_t option, long value); // note: we use `mi_cfree` as "checked free" and it checks if the pointer is in our heap before free-ing. // ------------------------------------------------------------------------------------------------------- -mi_decl_export mi_decl_nodiscard size_t mi_malloc_size(const void* p) mi_attr_noexcept; -mi_decl_export mi_decl_nodiscard size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept; mi_decl_export void mi_cfree(void* p) mi_attr_noexcept; mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept; @@ -376,12 +377,17 @@ mi_decl_realloc(void*, mi_reallocarray, void* p, size_t count, size_t size) mi_ mi_decl_realloc(void*, mi_aligned_recalloc, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_alloc_size2(2, 3) mi_attr_alloc_align(4); mi_decl_realloc(void*, mi_aligned_offset_recalloc, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_alloc_size2(2, 3); -mi_decl_malloc( unsigned short*, mi_wcsdup, const unsigned short* s); -mi_decl_malloc( unsigned char*, mi_mbsdup, const unsigned char* s); -mi_decl_noexcpt(int, mi_dupenv_s, char** buf, size_t* size, const char* name); -mi_decl_noexcpt(int, mi_wdupenv_s, unsigned short** buf, size_t* size, const unsigned short* name); -mi_decl_noexcpt(void*, mi__expand, void* p, size_t newsize); +mi_decl_malloc(wchar_t*, mi_wcsdup, const wchar_t* s); +mi_decl_malloc(unsigned char*, mi_mbsdup, const unsigned char* s); +mi_decl_malloc(char*, mi_getcwd, char* buf, size_t buf_len); +mi_decl_noexcpt(int, mi__dupenv_s, char** buf, size_t* size, const char* name); +mi_decl_noexcpt(int, mi__wdupenv_s, wchar_t** buf, size_t* size, const wchar_t* name); +mi_decl_noexcpt(void*, mi__expand, void* p, size_t newsize); +mi_decl_malloc( char*, mi__fullpath, char* buf, const char* path, size_t buf_len); +mi_decl_malloc( wchar_t*, mi__wfullpath, wchar_t* buf, const wchar_t* path, size_t buf_len); +mi_decl_malloc( wchar_t*, mi__wgetcwd, wchar_t* buf, size_t buf_len); +// todo: tempnam, _wgetdcwd, and _wgetdcwd_nolock // The `mi_new` wrappers implement C++ semantics on out-of-memory instead of directly returning `NULL`. // (and call `std::get_new_handler` and potentially raise a `std::bad_alloc` exception). @@ -390,8 +396,8 @@ mi_decl_new(void*, mi_new_aligned, size_t size, size_t alignment) mi_attr_alloc_ mi_decl_new(void*, mi_new_n, size_t count, size_t size) mi_attr_alloc_size2(1, 2); mi_decl_malloc(void*, mi_new_nothrow, size_t size) mi_attr_alloc_size(1); mi_decl_malloc(void*, mi_new_aligned_nothrow, size_t size, size_t alignment) mi_attr_alloc_size(1) mi_attr_alloc_align(2); -mi_declx(mi_decl_nodiscard void*, mi_new_realloc, , void* p, size_t newsize) mi_attr_alloc_size(2) ; -mi_declx(mi_decl_nodiscard void*, mi_new_reallocn, , void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3) ; +mi_declx(mi_decl_nodiscard mi_decl_export void*, mi_new_realloc, , void* p, size_t newsize) mi_attr_alloc_size(2) ; +mi_declx(mi_decl_nodiscard mi_decl_export void*, mi_new_reallocn, , void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3) ; // ---------------------------------------------------------------------- @@ -553,8 +559,13 @@ template bool operator!=(const mi_stl_allocator&, const #define mi_wcsdup(s) MI_SOURCE_LOC(mi_wcsdup,s) #define mi_mbsdup(s) MI_SOURCE_LOC(mi_mbsdup,s) -#define mi_dupenv_s(b,s,n) MI_SOURCE_LOC(mi_dupenv_s,b,s,n) -#define mi_wdupenv_s(b,s,n) MI_SOURCE_LOC(mi_wdupenv_s,b,s,n) +#define mi_getcwd(b,n) MI_SOURCE_LOC(mi_getcwd(b,n) +#define mi__dupenv_s(b,s,n) MI_SOURCE_LOC(mi__dupenv_s,b,s,n) +#define mi__wdupenv_s(b,s,n) MI_SOURCE_LOC(mi__wdupenv_s,b,s,n) +#define mi__expand(p,n) MI_SOURCE_LOC(mi__expand,p,n) +#define mi__fullpath(b,p,n) MI_SOURCE_LOC(mi__fullpath,b,p,n) +#define mi__wfullpath(b,p,n) MI_SOURCE_LOC(mi__wfullpath,b,p,n) +#define mi__wgetcwd(b,n) MI_SOURCE_LOC(mi__wgetcwd,b,n) #define mi_posix_memalign(p,a,s) MI_SOURCE_LOC(mi_posix_memalign,p,a,s) #define mi_memalign(a,s) MI_SOURCE_LOC(mi_memalign,a,s) diff --git a/src/alloc-override.c b/src/alloc-override.c index 36e15187..57329f1d 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -176,6 +176,13 @@ void* memalign(size_t alignment, size_t size) { return MI_SOURCE_R void* aligned_alloc(size_t alignment, size_t size) { return MI_SOURCE_RET(mi_aligned_alloc, alignment, size); } int posix_memalign(void** p, size_t alignment, size_t size) { return MI_SOURCE_RET(mi_posix_memalign, p, alignment, size); } +char* strdup(const char* s) { return MI_SOURCE_RET(mi_strdup, s); } +wchar_t* wcsdup(const wchar_t* s) { return MI_SOURCE_RET(mi_wcsdup, s); } + +// gives compile errors if we override :-( +// char* get_current_dir_name(void) { return MI_SOURCE_RET(mi_getcwd, NULL, 0); } +// char* getcwd(char* buf, size_t buf_len) { return MI_SOURCE_RET(mi_getcwd, buf, buf_len); } + #if defined(__GLIBC__) && defined(__linux__) // forward __libc interface (needed for glibc-based Linux distributions) void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size); diff --git a/src/alloc-posix.c b/src/alloc-posix.c index 09a0c977..06b8c3f9 100644 --- a/src/alloc-posix.c +++ b/src/alloc-posix.c @@ -10,6 +10,7 @@ terms of the MIT license. A copy of the license can be found in the file // for convenience and used when overriding these functions. // ------------------------------------------------------------------------ #define MI_NO_SOURCE_DEBUG +#define _CRT_SECURE_NO_WARNINGS #include "mimalloc.h" #include "mimalloc-internal.h" @@ -20,6 +21,7 @@ terms of the MIT license. A copy of the license can be found in the file #include #include // memcpy #include // getenv +#include // wcslen, wcrcpy #ifndef EINVAL #define EINVAL 22 @@ -97,7 +99,7 @@ MI_SOURCE_API2(mi_decl_restrict void*, aligned_alloc, size_t, alignment, size_t, return p; } -static int mi_base_posix_memalign(void** p, size_t alignment, size_t size MI_SOURCE_XPARAM) +MI_SOURCE_API3(int, posix_memalign, void**, p, size_t, alignment, size_t, size) { // Note: The spec dictates we should not modify `*p` on an error. (issue#27) // @@ -117,24 +119,13 @@ static int mi_base_posix_memalign(void** p, size_t alignment, size_t size MI_SO return 0; } -#ifndef NDEBUG -int dbg_mi_posix_memalign(void** p, size_t alignment, size_t size, mi_source_t __mi_source) mi_attr_noexcept { - UNUSED(__mi_source); - return mi_base_posix_memalign(p, alignment, size MI_SOURCE_XARG); -} -#endif - -int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept { - return mi_base_posix_memalign(p, alignment, size MI_SOURCE_XRET()); -} - -MI_SOURCE_API1(mi_decl_restrict unsigned short*, wcsdup, const unsigned short*, s) +MI_SOURCE_API1(mi_decl_restrict wchar_t*, wcsdup, const wchar_t*, s) { if (s==NULL) return NULL; size_t len; for(len = 0; s[len] != 0; len++) { } - size_t size = (len+1)*sizeof(unsigned short); - unsigned short* p = (unsigned short*)MI_SOURCE_ARG(mi_malloc, size); + size_t size = (len+1)*sizeof(wchar_t); + wchar_t* p = (wchar_t*)MI_SOURCE_ARG(mi_malloc, size); if (p != NULL) { memcpy(p,s,size); } @@ -146,7 +137,112 @@ MI_SOURCE_API1(mi_decl_restrict unsigned char*, mbsdup, const unsigned char*, s) return (unsigned char*)MI_SOURCE_ARG(mi_strdup,(const char*)s); } -static int mi_base_dupenv_s(char** buf, size_t* size, const char* name MI_SOURCE_XPARAM) + +#ifdef _WIN32 +#include // getcwd +#else +#include // getcwd +#endif + +MI_SOURCE_API2(mi_decl_restrict char*, getcwd, char*, buf, size_t, buf_len) { + if (buf!=NULL && buf_len > 0) { + #pragma warning(suppress:4996) + return getcwd(buf, (int)buf_len); + } + else { + size_t pmax = _mi_path_max(); + char* cbuf = (char*)MI_SOURCE_ARG(mi_malloc, pmax+1); + #pragma warning(suppress:4996) + char* res = getcwd(cbuf, (int)pmax); + if (res != NULL) { + res = MI_SOURCE_ARG(mi_strdup, cbuf); // shrink + } + mi_free(cbuf); + return res; + } +} + +MI_SOURCE_API3(mi_decl_restrict char*, _fullpath, char*, buf, const char*, path, size_t, buf_len) { + if (path==NULL) return NULL; + char* full = MI_SOURCE_ARG(mi_realpath, path, NULL); + if (full==NULL) return NULL; + if (buf==NULL) { + return full; + } + else { + size_t len = strlen(full); + if (len < buf_len) { + strcpy(buf, full); + } + mi_free(full); + return (len < buf_len ? buf : NULL); + } +} + + +// ----------------------------------------------------------------------------- +// Microsoft: _wgetcwd, _wfullpath, _(w)dupenv, _aligned_recalloc, _aligned_offset_recalloc +// ----------------------------------------------------------------------------- + +static wchar_t* mi_mbstowcs_dup(const char* s MI_SOURCE_XPARAM) { + if (s==NULL) return NULL; + size_t len = strlen(s); + wchar_t* ws = (wchar_t*)MI_SOURCE_ARG(mi_malloc, (len + 1)*sizeof(wchar_t)); // over allocate by a factor 2 + mbstowcs(ws, s, len + 1); + return ws; +} + +static char* mi_wcstombs_dup(const wchar_t* ws MI_SOURCE_XPARAM) { + if (ws==NULL) return NULL; + size_t len = wcslen(ws); + size_t sz = (len + 1)*sizeof(wchar_t)*2; // over allocate by a factor 4 :( ok for our purposes though + char* s = (char*)MI_SOURCE_ARG(mi_malloc, sz); + wcstombs(s, ws, sz); + return s; +} + +MI_SOURCE_API3(mi_decl_restrict wchar_t*, _wfullpath, wchar_t*, wbuf, const wchar_t*, wpath, size_t, wbuf_len) { + if (wpath==NULL) return NULL; + char* path = mi_wcstombs_dup(wbuf MI_SOURCE_XARG); + char* full = MI_SOURCE_ARG(mi_realpath, path, NULL); + mi_free(path); + if (full==NULL) return NULL; + wchar_t* wfull = mi_mbstowcs_dup( full MI_SOURCE_XARG); + mi_free(full); + if (wbuf==NULL) { + return wfull; + } + else { + size_t len = wcslen(wfull); + if (len < wbuf_len) { + wcscpy(wbuf, wfull); + } + mi_free(wfull); + return (len < wbuf_len ? wbuf : NULL); + } +} + +MI_SOURCE_API2(mi_decl_restrict wchar_t*, _wgetcwd, wchar_t*, wbuf, size_t, wbuf_len) +{ + char* res = MI_SOURCE_ARG(mi_getcwd, NULL, 0); + if (res == NULL) return NULL; + wchar_t* wres = mi_mbstowcs_dup( res MI_SOURCE_XARG); + mi_free(res); + if (wbuf == NULL || wbuf_len == 0) { + return wres; + } + else { + size_t len = wcslen(wres); + if (len < wbuf_len) { + wcscpy(wbuf, wres); + } + mi_free(wres); + return (len < wbuf_len ? wbuf : NULL); + } +} + + +MI_SOURCE_API3(int, _dupenv_s, char**, buf, size_t*, size, const char*, name) { if (buf==NULL || name==NULL) return EINVAL; if (size != NULL) *size = 0; @@ -163,19 +259,7 @@ static int mi_base_dupenv_s(char** buf, size_t* size, const char* name MI_SOURC return 0; } -#ifndef NDEBUG -int dbg_mi_dupenv_s(char** buf, size_t* size, const char* name, mi_source_t __mi_source) mi_attr_noexcept { - UNUSED(__mi_source); - return mi_base_dupenv_s(buf, size, name MI_SOURCE_XARG); -} -#endif - -int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept { - return mi_base_dupenv_s(buf, size, name MI_SOURCE_XRET()); -} - - -static int mi_base_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name MI_SOURCE_XPARAM) +MI_SOURCE_API3(int, _wdupenv_s, wchar_t**, buf, size_t*, size, const wchar_t*, name) { if (buf==NULL || name==NULL) return EINVAL; if (size != NULL) *size = 0; @@ -188,30 +272,19 @@ static int mi_base_wdupenv_s(unsigned short** buf, size_t* size, const unsigned return EINVAL; #else #pragma warning(suppress:4996) - unsigned short* p = (unsigned short*)_wgetenv((const wchar_t*)name); + wchar_t* p = (wchar_t*)_wgetenv(name); if (p==NULL) { *buf = NULL; } else { *buf = MI_SOURCE_ARG(mi_wcsdup, p); if (*buf==NULL) return ENOMEM; - if (size != NULL) *size = wcslen((const wchar_t*)p); + if (size != NULL) *size = wcslen(p); } return 0; #endif } -#ifndef NDEBUG -int dbg_mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name, mi_source_t __mi_source) mi_attr_noexcept { - UNUSED(__mi_source); - return mi_base_wdupenv_s(buf, size, name MI_SOURCE_XARG); -} -#endif - -int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept { - return mi_base_wdupenv_s(buf, size, name MI_SOURCE_XRET()); -} - #ifndef NDEBUG void* dbg_mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset, mi_source_t __mi_source) mi_attr_noexcept { // Microsoft diff --git a/src/alloc.c b/src/alloc.c index f83fd1ae..bb1c884c 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -11,6 +11,7 @@ terms of the MIT license. A copy of the license can be found in the file #include // memset, memcpy, strlen #include // malloc, exit +#include // wcslen #define MI_IN_ALLOC_C #include "alloc-override.c" @@ -599,18 +600,16 @@ MI_ALLOC_API3(void*, recalloc, mi_heap_t*, heap, void*, p, size_t, count, size_t return _mi_base_realloc_zero(heap, p, total, true MI_SOURCE_XARG); } - - -// ------------------------------------------------------ -// strdup, strndup, and realpath -// ------------------------------------------------------ +/*------------------------------------------------------- + strdup, strndup, and realpath +-------------------------------------------------------*/ // `strdup` using mi_malloc -MI_ALLOC_API1(mi_decl_restrict char*, strdup, mi_heap_t*,heap, const char*,s) +MI_ALLOC_API1(mi_decl_restrict char*, strdup, mi_heap_t*, heap, const char*, s) { if (s == NULL) return NULL; size_t n = strlen(s); - char* t = (char*)mi_base_malloc(heap, n+1 MI_SOURCE_XARG); + char* t = (char*)MI_SOURCE_ARG(mi_heap_malloc, heap, n+1); if (t != NULL) memcpy(t, s, n + 1); return t; } @@ -621,20 +620,23 @@ MI_ALLOC_API2(mi_decl_restrict char*, strndup, mi_heap_t*, heap, const char*, s, if (s == NULL) return NULL; size_t m = strlen(s); if (n > m) n = m; - char* t = (char*)mi_base_malloc(heap, n+1 MI_SOURCE_XARG); + char* t = (char*)MI_SOURCE_ARG(mi_heap_malloc, heap, n+1); if (t == NULL) return NULL; memcpy(t, s, n); t[n] = 0; return t; } - #ifndef __wasi__ // `realpath` using mi_malloc #ifdef _WIN32 #ifndef PATH_MAX #define PATH_MAX MAX_PATH #endif +size_t _mi_path_max(void) { + return PATH_MAX; +} + #include MI_ALLOC_API2(mi_decl_restrict char*, realpath, mi_heap_t*, heap, const char*, fname, char*, resolved_name) { @@ -651,15 +653,15 @@ MI_ALLOC_API2(mi_decl_restrict char*, realpath, mi_heap_t*, heap, const char*, f return resolved_name; } else { - return mi_base_strndup(heap, buf, PATH_MAX MI_SOURCE_XARG); + return MI_SOURCE_ARG(mi_heap_strndup, heap, buf, PATH_MAX); } } #else #include // pathconf -static size_t mi_path_max() { +size_t _mi_path_max(void) { static size_t path_max = 0; if (path_max <= 0) { - long m = pathconf("/",_PC_PATH_MAX); + long m = pathconf("/", _PC_PATH_MAX); if (m <= 0) path_max = 4096; // guess else if (m < 256) path_max = 256; // at least 256 else path_max = m; @@ -670,20 +672,22 @@ static size_t mi_path_max() { MI_ALLOC_API2(mi_decl_restrict char*, realpath, mi_heap_t*, heap, const char*, fname, char*, resolved_name) { if (resolved_name != NULL) { - return realpath(fname,resolved_name); + return realpath(fname, resolved_name); } else { - size_t n = mi_path_max(); - char* buf = (char*)mi_malloc(n+1); + size_t n = _mi_path_max(); + char* buf = (char*)MI_SOURCE_ARG(mi_heap_malloc, heap, n+1); if (buf==NULL) return NULL; - char* rname = realpath(fname,buf); - char* result = mi_base_strndup(heap, rname, n MI_SOURCE_XARG); // ok if `rname==NULL` + char* rname = realpath(fname, buf); + char* result = MI_SOURCE_ARG(mi_heap_strndup, heap, rname, n); // ok if `rname==NULL` mi_free(buf); return result; } } #endif +#else // wasi + #endif /*------------------------------------------------------- diff --git a/test/main-override.cpp b/test/main-override.cpp index 5ed04e0d..51eaefd2 100644 --- a/test/main-override.cpp +++ b/test/main-override.cpp @@ -9,7 +9,7 @@ #include #include #include - +#include #ifdef _WIN32 #include