summaryrefslogtreecommitdiff
path: root/src/common/memmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/memmgr.c')
-rw-r--r--src/common/memmgr.c85
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;