src/nmalloc.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- nc_XMmalloc
- nc_XMcalloc
- nc_XMstrdup
- nc_XMfree
- bad_mmalloc
- init_mmalloc
- open_mmap
- writeMmapBase
- nc_strXMListAdd
- strXMListFree
/* $Id: nmalloc.c,v 1.5 2002/04/04 11:14:54 proff Exp $ */
#include "nglobal.h"
#include "mmap.h"
#include "mmalloc.h"
#include "nmalloc.h"
EXPORT void *nc_XMmalloc(int size, char *desc)
/* [<][>][^][v][top][bottom][index][help] */
{
void *ret=mmalloc_check(Mbase, size, desc);
if (!ret)
{
loge (("XMcalloc call from %s for %d bytes failed", desc, size));
Exit(1);
}
return ret;
}
EXPORT void *nc_XMcalloc(int num, int size, char *desc)
/* [<][>][^][v][top][bottom][index][help] */
{
void *ret=mcalloc_check(Mbase, num, size, desc);
if (!ret)
{
loge (("XMcalloc call from %s for %d bytes failed", desc, size));
Exit(1);
}
return ret;
}
EXPORT char *nc_XMstrdup(char *s, char *desc)
/* [<][>][^][v][top][bottom][index][help] */
{
int len=strlen(s)+1;
char *p=nc_XMmalloc(len, desc);
memcpy(p, s, len);
return p;
}
EXPORT void nc_XMfree(void *p, char *desc)
/* [<][>][^][v][top][bottom][index][help] */
{
mfree_check(Mbase, p, desc);
}
static void bad_mmalloc(void *addr, char *desc, int what)
/* [<][>][^][v][top][bottom][index][help] */
{
char *type;
switch (what)
{
case -1: type = "already freed"; break;
case 0: type = "memory underrun"; break;
case 1: type = "memory overrun"; break;
default: NOTREACHED;
}
loge (("%s detected at %p, allocated by %.64s", type, addr, desc));
Exit(1);
}
static void init_mmalloc(POINTER m)
/* [<][>][^][v][top][bottom][index][help] */
{
mmcheck(m, bad_mmalloc);
}
EXPORT void open_mmap()
/* [<][>][^][v][top][bottom][index][help] */
{
int fd = -1;
bool f_retried = FALSE;
mmapAnon =
#if defined(HAVE_MMAP_ANON)
# ifdef HAVE_MMAP_FILE
con->anonMmap? TRUE: FALSE
# else
TRUE
# endif
#else
#if defined(HAVE_MMAP_DEV_ZERO)
# ifdef HAVE_MMAP_FILE
con->anonMmap? TRUE: FALSE
# else
TRUE
# endif
#else
#if defined(HAVE_MMAP_FILE)
FALSE
#else
# error no valid mmaping type
#endif
#endif
#endif
;
if (mmapAnon)
f_cleanSlate = TRUE;
else
{
if (con->refreshMmap)
unlink(con->mmapFile);
else
fd=open(con->mmapFile, O_RDWR);
if (fd<0)
{
if (!con->refreshMmap)
loge (("unable to open %s", con->mmapFile));
retry:
logw (("re-creating %s", con->mmapFile));
fd=open(con->mmapFile, O_RDWR|O_CREAT|O_TRUNC, 0664);
if (fd<0)
{
loge (("unable to open '%s'", con->mmapFile));
Exit(1);
}
} else
{
int fb;
struct mmap_base mb;
fb = open(con->mmapBaseFile, O_RDONLY);
if (fb<0 || read(fb, &mb, sizeof mb) != sizeof mb)
{
loge (("missing or bad mbase pointer file '%s'", con->mmapBaseFile));
f_cleanSlate = TRUE;
}
else
{
Mbase = mb.mmap_base;
f_cleanSlate = FALSE;
}
close (fb);
}
}
Mbase = mmalloc_attach (mmapAnon? -1: fd, mmapAnon? 0: Mbase, con->maxMmap);
if (!Mbase)
{
if (fd<0 || f_retried)
{
loge (("couldn't attach mmap() region. abort."));
Exit(1);
}
close (fd);
loge (("mmap() attach to %s failed (probably corrupted...removing it and trying again)", con->mmapFile));
unlink(con->mmapFile);
f_retried = TRUE;
goto retry;
}
init_mmalloc(Mbase);
if (f_cleanSlate)
{
Ni=XMcalloc (1, sizeof *Ni);
mmalloc_setkey (Mbase, 0, Ni); /* save pointer to Ni structure */
f_cleanSlate = TRUE;
} else
{
Ni=mmalloc_getkey (Mbase, 0);
}
if (!Ni)
{
loge (("invalid getkey/setkey in %s", con->mmapFile));
Exit(1);
}
}
EXPORT void writeMmapBase()
/* [<][>][^][v][top][bottom][index][help] */
{
chdir(con->cacheDir);
if (!mmapAnon)
{
int fd;
struct mmap_base mb;
bzero(&mb, sizeof mb);
mb.mmap_base = Mbase;
fd = open(con->mmapBaseFile, O_WRONLY|O_TRUNC|O_CREAT, 0664);
if (fd<0 || write(fd, &mb, sizeof mb)!=sizeof mb)
{
loge (("couldn't write '%s'", con->mmapBaseFile));
unlink (con->mmapBaseFile);
}
close (fd);
}
}
EXPORT struct strList * nc_strXMListAdd (struct strList *l, char *s, char *desc)
/* [<][>][^][v][top][bottom][index][help] */
{
if (l)
{
l->next = (struct strList *) nc_XMmalloc (sizeof *l, desc);
l->next->head = l->head;
l = l->next;
} else
{
l = (struct strList *) nc_XMmalloc (sizeof *l, desc);
l->head = l;
}
l->next = NULL;
l->data = nc_XMstrdup (s, desc);
return l;
}
EXPORT void strXMListFree (struct strList *l)
/* [<][>][^][v][top][bottom][index][help] */
{
l = l->head;
while (l)
{
struct strList *t = l;
t = l;
l = l->next;
XMfree (t->data);
XMfree (t);
}
}