mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-08-25 16:54:47 +03:00
add getcwd and fullpath wrappers
This commit is contained in:
parent
ff2fe673e5
commit
c04881ef8a
7 changed files with 196 additions and 92 deletions
|
@ -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);
|
||||
|
|
|
@ -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 <errno.h>
|
||||
#include <string.h> // memcpy
|
||||
#include <stdlib.h> // getenv
|
||||
#include <wchar.h> // 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)
|
||||
// <http://man7.org/linux/man-pages/man3/posix_memalign.3.html>
|
||||
|
@ -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 <direct.h> // getcwd
|
||||
#else
|
||||
#include <unistd.h> // 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
|
||||
|
|
38
src/alloc.c
38
src/alloc.c
|
@ -11,6 +11,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
|||
|
||||
#include <string.h> // memset, memcpy, strlen
|
||||
#include <stdlib.h> // malloc, exit
|
||||
#include <wchar.h> // 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 <windows.h>
|
||||
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 <unistd.h> // 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
|
||||
|
||||
/*-------------------------------------------------------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue