blob: 8ed367934bcb7d069773bf35944f7aec948d6155 [file] [log] [blame]
/*
* Copyright 1996-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "misc/malloc.h"
#include "misc/misc.h"
#include <stdlib.h>
#include <string.h>
#define MEM_BEGIN "_mem_begin_"
#define MEM_END "mem_end"
#define MEM_FREED "__free_"
#define CONTROL_SIZE (strlen (MEM_BEGIN) + 1 + sizeof (int) + strlen (MEM_END) + 1)
unsigned int misc_memsize(char *p) {
char *begin;
begin = p - strlen (MEM_BEGIN) - 1 - sizeof(int);
return *(int *)(begin + strlen (MEM_BEGIN) + 1);
}
void misc_checkmem (char * p, int size)
{
char * begin;
char * end;
begin = p - strlen (MEM_BEGIN) - 1 - sizeof (int);
if (strcmp (begin, MEM_BEGIN))
misc_die ("misc_checkmem: memory corrupted - invalid head sign");
if (*(int *)(begin + strlen (MEM_BEGIN) + 1) != size)
misc_die ("misc_checkmem: memory corrupted - invalid size");
end = begin + size + CONTROL_SIZE - strlen (MEM_END) - 1;
if (strcmp (end, MEM_END))
misc_die ("misc_checkmem: memory corrupted - invalid end sign");
}
void *misc_getmem (int size)
{
char * mem;
if ((mem = misc_malloc(size)) == NULL)
misc_die ("misc_getmem: no more memory (%d)", size);
memset (mem, 0, size);
// misc_checkmem (mem, size);
return mem;
}
void *misc_malloc(int size) {
char * p;
char * mem;
p = (char *)malloc (CONTROL_SIZE + size);
if (!p)
misc_die ("misc_getmem: no more memory (%d)", size);
/* Write the MEM_BEGIN magic in the beginning of allocated memory. */
strcpy (p, MEM_BEGIN);
p += strlen (MEM_BEGIN) + 1;
/* Write the size after the magic. */
*(int *)p = size;
p += sizeof (int);
mem = p;
p += size;
strcpy (p, MEM_END);
return mem;
}
void * misc_expandmem (void * vp, int size, int by)
{
int allocated;
char * mem, * p = vp;
int expand_by = by;
if (p) {
misc_checkmem (p, size);
allocated = CONTROL_SIZE + size;
p -= (strlen (MEM_BEGIN) + 1 + sizeof (int));
} else {
allocated = 0;
/* add control bytes to the new allocated area */
expand_by += CONTROL_SIZE;
}
p = realloc (p, allocated + expand_by);
if (!p)
misc_die ("misc_expandmem: no more memory (%d)", size);
if (!vp) {
strcpy (p, MEM_BEGIN);
}
mem = p + strlen (MEM_BEGIN) + 1 + sizeof (int);
*(int *)(p + strlen (MEM_BEGIN) + 1) = size + by;
/* fill new allocated area by 0s */
if(by > 0)
memset (mem + size, 0, by);
strcpy (mem + size + by, MEM_END);
// misc_checkmem (mem, size + by);
return mem;
}
void misc_freemem (void * vp)
{
char * p = vp;
int size;
if (!p)
return;
size = misc_memsize (vp);
misc_checkmem (p, size);
p -= (strlen (MEM_BEGIN) + 1 + sizeof (int));
strcpy (p, MEM_FREED);
strcpy (p + size + CONTROL_SIZE - strlen (MEM_END) - 1, MEM_FREED);
free (p);
}