diff options
Diffstat (limited to 'src/common/memmgr.c')
-rw-r--r-- | src/common/memmgr.c | 85 |
1 files changed, 74 insertions, 11 deletions
diff --git a/src/common/memmgr.c b/src/common/memmgr.c index 93c23ff18..b80b4d4e9 100644 --- a/src/common/memmgr.c +++ b/src/common/memmgr.c @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify @@ -97,10 +97,10 @@ struct malloc_interface *iMalloc; #ifndef USE_MEMMGR -#ifdef __APPLE__ +#if defined __APPLE__ #include <malloc/malloc.h> #define BUFFER_SIZE(ptr) malloc_size(ptr) -#elif __FreeBSD__ +#elif defined __FreeBSD__ #include <malloc_np.h> #define BUFFER_SIZE(ptr) malloc_usable_size(ptr) #elif defined __linux__ || defined __linux || defined CYGWIN @@ -149,25 +149,25 @@ void* aRealloc_(void *p, size_t size, const char *file, int line, const char *fu void* aReallocz_(void *p, size_t size, const char *file, int line, const char *func) { - void *ret; + unsigned char *ret = NULL; // ShowMessage("%s:%d: in func %s: aReallocz %p %ld\n",file,line,func,p,size); #ifdef USE_MEMMGR ret = REALLOC(p, size, file, line, func); #else - size_t newSize; - if (p) { + if (p != NULL) { + size_t newSize; size_t oldSize = BUFFER_SIZE(p); ret = REALLOC(p, size, file, line, func); newSize = BUFFER_SIZE(ret); - if (ret && newSize > oldSize) + if (ret != NULL && newSize > oldSize) memset(ret + oldSize, 0, newSize - oldSize); } else { ret = REALLOC(p, size, file, line, func); - if (ret) + if (ret != NULL) memset(ret, 0, BUFFER_SIZE(ret)); } #endif - if (ret == NULL){ + if (ret == NULL) { ShowFatalError("%s:%d: in func %s: aRealloc error out of memory!\n",file,line,func); exit(EXIT_FAILURE); } @@ -184,6 +184,36 @@ char* aStrdup_(const char *p, const char *file, int line, const char *func) } return ret; } + +/** + * Copies a string to a newly allocated buffer, setting a maximum length. + * + * The string is always NULL-terminated. If the string is longer than `size`, + * then `size` bytes are copied, not including the appended NULL terminator. + * + * @warning + * If malloc is out of memory, throws a fatal error and aborts the program. + * + * @param p the source string to copy. + * @param size The maximum string length to copy. + * @param file @see ALC_MARK. + * @param line @see ALC_MARK. + * @param func @see ALC_MARK. + * @return the copied string. + */ +char *aStrndup_(const char *p, size_t size, const char *file, int line, const char *func) +{ + size_t len = strnlen(p, size); + char *ret = MALLOC(len + 1, file, line, func); + if (ret == NULL) { + ShowFatalError("%s:%d: in func %s: aStrndup error out of memory!\n", file, line, func); + exit(EXIT_FAILURE); + } + memcpy(ret, p, len); + ret[len] = '\0'; + return ret; +} + void aFree_(void *p, const char *file, int line, const char *func) { // ShowMessage("%s:%d: in func %s: aFree %p\n",file,line,func,p); @@ -305,7 +335,7 @@ void *mmalloc_(size_t size, const char *file, int line, const char *func) { struct unit_head *head; if (((long) size) < 0) { - ShowError("mmalloc_: %"PRIdS"\n", size); + ShowError("mmalloc_: %"PRIuS"\n", size); return NULL; } @@ -478,6 +508,37 @@ char *mstrdup_(const char *p, const char *file, int line, const char *func) { } } +/** + * Copies a string to a newly allocated buffer, setting a maximum length. + * + * The string is always NULL-terminated. If the string is longer than `size`, + * then `size` bytes are copied, not including the appended NULL terminator. + * + * @warning + * If malloc is out of memory, throws a fatal error and aborts the program. + * + * @param p the source string to copy. + * @param size The maximum string length to copy. + * @param file @see ALC_MARK. + * @param line @see ALC_MARK. + * @param func @see ALC_MARK. + * @return the copied string. + * @retval NULL if the source string is NULL or in case of error. + */ +char *mstrndup_(const char *p, size_t size, const char *file, int line, const char *func) +{ + if (p == NULL) { + return NULL; + } else { + size_t len = strnlen(p, size); + char *string = iMalloc->malloc(len + 1, file, line, func); + memcpy(string, p, len); + string[len] = '\0'; + return string; + } +} + + void mfree_(void *ptr, const char *file, int line, const char *func) { struct unit_head *head; @@ -820,7 +881,7 @@ void memmgr_report (int extra) { } for( j = 0; j < 100; j++ ) { if( data[j].size != 0 ) { - ShowMessage("[malloc] : "CL_WHITE"%s"CL_RESET":"CL_WHITE"%d"CL_RESET" %d instances => %.2f MB\n",data[j].file,data[j].line,data[j].count,(double)((data[j].size)/1024)/1024); + ShowMessage("[malloc] : "CL_WHITE"%s"CL_RESET":"CL_WHITE"%d"CL_RESET" %u instances => %.2f MB\n",data[j].file,data[j].line,data[j].count,(double)((data[j].size)/1024)/1024); } } ShowMessage("[malloc] : reporting %u instances | %.2f MB\n",count,(double)((size)/1024)/1024); @@ -947,6 +1008,7 @@ void malloc_defaults(void) { iMalloc->realloc = mrealloc_; iMalloc->reallocz = mreallocz_; iMalloc->astrdup = mstrdup_; + iMalloc->astrndup = mstrndup_; iMalloc->free = mfree_; #else iMalloc->malloc = aMalloc_; @@ -954,6 +1016,7 @@ void malloc_defaults(void) { iMalloc->realloc = aRealloc_; iMalloc->reallocz = aReallocz_;/* not using memory manager huhum o.o perhaps we could still do something about */ iMalloc->astrdup = aStrdup_; + iMalloc->astrndup = aStrndup_; iMalloc->free = aFree_; #endif iMalloc->post_shutdown = NULL; |