src/nmalloc.c

/* [<][>]
[^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. nc_XMmalloc
  2. nc_XMcalloc
  3. nc_XMstrdup
  4. nc_XMfree
  5. bad_mmalloc
  6. init_mmalloc
  7. open_mmap
  8. writeMmapBase
  9. nc_strXMListAdd
  10. 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);
        }
}

/* [<][>][^][v][top][bottom][index][help] */