]> git.deb.at Git - pkg/abook.git/commitdiff
- replace abook_malloc, abook_realloc and my_free with new xmalloc routines
authorJaakko Heinonen <jheinonen@users.sourceforge.net>
Wed, 27 Jul 2005 06:28:22 +0000 (06:28 +0000)
committerJaakko Heinonen <jheinonen@users.sourceforge.net>
Wed, 27 Jul 2005 06:28:22 +0000 (06:28 +0000)
12 files changed:
ChangeLog
Makefile.am
Makefile.in
abook.c
abook.h
database.c
edit.c
filter.c
misc.c
options.c
xmalloc.c [new file with mode: 0644]
xmalloc.h [new file with mode: 0644]

index 1cec4783b5ff04112f33e7ad117cbf6f8f4aeed0..0ecaeb411ad7891586200b655bf3433109d6cdbe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 0.5.4
  - add show_cursor config option (idea from Cheryl Homiak)
  - autoconf/automake update
+ - replace abook_malloc, abook_realloc and my_free with new xmalloc routines
 
 0.5.3
  - add allcvs filters (Christoph Sobotka)
index 342465d6d7ae4822a1b3e77d611bec1b597a6634..d98743c1b0e52427fafc16d9f37e348f70ddd8a9 100644 (file)
@@ -4,9 +4,11 @@ bin_PROGRAMS = abook
 abook_SOURCES = abook.c database.c filter.c list.c misc.c \
                options.c edit.c ldif.c ui.c getname.c \
                getopt.c getopt1.c abook_rl.c mbswidth.c \
+               xmalloc.c \
                abook.h database.h filter.h list.h misc.h help.h \
                options.h edit.h ldif.h abook_curses.h ui.h getname.h \
-               getopt.h abook_rl.h mbswidth.h
+               getopt.h abook_rl.h mbswidth.h \
+               xmallloc.h
 
 EXTRA_DIST = ANNOUNCE BUGS FAQ abook.1 abookrc.5 sample.abookrc abook.spec \
        contrib
index 63bd2dfff1159ac79f7edf3ada9c66ac317c6f0a..0e700d32579636cb02e1bb6c800bedf2a102b79b 100644 (file)
@@ -61,7 +61,8 @@ PROGRAMS = $(bin_PROGRAMS)
 am_abook_OBJECTS = abook.$(OBJEXT) database.$(OBJEXT) filter.$(OBJEXT) \
        list.$(OBJEXT) misc.$(OBJEXT) options.$(OBJEXT) edit.$(OBJEXT) \
        ldif.$(OBJEXT) ui.$(OBJEXT) getname.$(OBJEXT) getopt.$(OBJEXT) \
-       getopt1.$(OBJEXT) abook_rl.$(OBJEXT) mbswidth.$(OBJEXT)
+       getopt1.$(OBJEXT) abook_rl.$(OBJEXT) mbswidth.$(OBJEXT) \
+       xmalloc.$(OBJEXT)
 abook_OBJECTS = $(am_abook_OBJECTS)
 abook_LDADD = $(LDADD)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
@@ -169,9 +170,11 @@ target_alias = @target_alias@
 abook_SOURCES = abook.c database.c filter.c list.c misc.c \
                options.c edit.c ldif.c ui.c getname.c \
                getopt.c getopt1.c abook_rl.c mbswidth.c \
+               xmalloc.c \
                abook.h database.h filter.h list.h misc.h help.h \
                options.h edit.h ldif.h abook_curses.h ui.h getname.h \
-               getopt.h abook_rl.h mbswidth.h
+               getopt.h abook_rl.h mbswidth.h \
+               xmallloc.h
 
 EXTRA_DIST = ANNOUNCE BUGS FAQ abook.1 abookrc.5 sample.abookrc abook.spec \
        contrib
@@ -280,6 +283,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmalloc.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
diff --git a/abook.c b/abook.c
index ee4160ad94d0610e0f5b210a375d93865e12d946..06c4ea788ccd2f0d2d82569bfa481792b4794aac 100644 (file)
--- a/abook.c
+++ b/abook.c
@@ -6,20 +6,21 @@
  * Copyright (C) Jaakko Heinonen
  */
 
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/stat.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
 #ifdef HAVE_CONFIG_H
 #      include "config.h"
 #endif
 #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
 #      include <locale.h>
 #endif
+#include <assert.h>
 #include "abook.h"
 #include "ui.h"
 #include "database.h"
@@ -30,7 +31,7 @@
 #include "options.h"
 #include "getname.h"
 #include "getopt.h"
-#include <assert.h>
+#include "xmalloc.h"
 
 static void             init_abook();
 static void            quit_abook_sig(int i);
@@ -99,6 +100,16 @@ check_abook_directory()
        free(dir);
 }
 
+static void
+xmalloc_error_handler(int err)
+{
+       if(is_ui_initialized())
+               quit_abook(QUIT_SAVE);
+
+       fprintf(stderr, "Memory allocation failure: %s\n", strerror(err));
+       exit(EXIT_FAILURE);
+}
+
 static void
 init_abook()
 {
@@ -168,6 +179,7 @@ main(int argc, char **argv)
 #if defined(HAVE_SETLOCALE) && defined(HAVE_LOCALE_H)
        setlocale(LC_ALL, "");
 #endif
+       xmalloc_set_error_handler(xmalloc_error_handler);
 
        parse_command_line(argc, argv);
 
@@ -183,8 +195,8 @@ main(int argc, char **argv)
 static void
 free_filenames()
 {
-       my_free(rcfile);
-       my_free(datafile);
+       xfree(rcfile);
+       xfree(datafile);
 }
 
 
@@ -574,39 +586,6 @@ launch_wwwbrowser(int item)
        ui_init_curses();
 }
 
-void *
-abook_malloc(size_t size)
-{
-       void *ptr;
-
-       if ( (ptr = malloc(size)) == NULL ) {
-               if( is_ui_initialized() )
-                       quit_abook(QUIT_SAVE);
-               perror("malloc() failed");
-               exit(1);
-       }
-
-       return ptr;
-}
-
-void *
-abook_realloc(void *ptr, size_t size)
-{
-       ptr = realloc(ptr, size);
-
-       if(size == 0)
-               return NULL;
-
-       if(ptr == NULL) {
-               if(is_ui_initialized())
-                       quit_abook(QUIT_SAVE);
-               perror("realloc() failed");
-               exit(1);
-       }
-
-       return ptr;
-}
-
 FILE *
 abook_fopen (const char *path, const char *mode)
 {      
@@ -791,10 +770,10 @@ add_email(int quiet)
                        getname(line, &name, &email);
                        add_email_count += add_email_add_item(quiet,
                                        name, email);
-                       my_free(name);
-                       my_free(email);
+                       xfree(name);
+                       xfree(email);
                }
-               my_free(line);
+               xfree(line);
        } while( !feof(stdin) );
 
        quit_add_email();
diff --git a/abook.h b/abook.h
index 20bad884ebc49c8b8969037475abec016cb9921f..b5e7c7627bbd291d101bef9080d473b5c37fb0ab 100644 (file)
--- a/abook.h
+++ b/abook.h
@@ -3,8 +3,6 @@
 
 #include <stdio.h>
 
-void           *abook_malloc(size_t size);
-void           *abook_realloc(void *ptr, size_t size);
 FILE           *abook_fopen (const char *path, const char *mode);
 void           quit_abook(int save_db);
 void           launch_wwwbrowser(int item);
@@ -39,7 +37,6 @@ int           strncasecmp (const char *, const char *, size_t);
 #define show_cursor()  curs_set(1)
 
 #define safe_atoi(X)    ((X == NULL) ? 0 : atoi(X))
-#define my_free(X)     do {free(X); X=NULL;} while(0)
 #define safe_str(X)    ((X == NULL) ? "" : X)
 #define safe_strdup(X) ((X == NULL) ? NULL : strdup(X))
 
index add1db02ec475a8eaf312b89baf683e1f6c2cbc0..5da2e93eced4b440c54ac3accaa2713d9a92d264 100644 (file)
@@ -19,6 +19,7 @@
 #include "misc.h"
 #include "options.h"
 #include "filter.h"
+#include "xmalloc.h"
 #ifdef HAVE_CONFIG_H
 #      include "config.h"
 #endif
@@ -223,7 +224,7 @@ free_list_item(list_item item)
        int i;
 
        for(i=0; i<ITEM_FIELDS; i++)
-               my_free(item[i]);
+               xfree(item[i]);
 }
 
 void
@@ -278,9 +279,8 @@ adjust_list_capacity()
        else
                return;
 
-       database = (list_item *)abook_realloc(database,
-                       sizeof(list_item) * list_capacity);
-       selected = (char *)abook_realloc(selected, list_capacity);
+       database = xrealloc(database, sizeof(list_item) * list_capacity);
+       selected = xrealloc(selected, list_capacity);
 }
 
 int
@@ -454,7 +454,7 @@ find_item(char *str, int start, int search_fields[])
                                ret = e.item;
                                goto out;
                        }
-                       my_free(tmp);
+                       xfree(tmp);
                }
        }
 
@@ -532,9 +532,9 @@ assign_fieldname(const char *name, int i)
                 * check if we are overwriting statically allocated default
                 */
                if(strcasecmp(abook_fields[i].name, abook_fields[i].key))
-                       my_free(abook_fields[i].name);
+                       xfree(abook_fields[i].name);
                
-               s = abook_malloc(MAX_FIELDNAME_LEN + 1);
+               s = xmalloc_inc(MAX_FIELDNAME_LEN, 1);
                snprintf(s, MAX_FIELDNAME_LEN, "%s", name);
                abook_fields[i].name = s;
        }
diff --git a/edit.c b/edit.c
index 8a2e1e98f247f28fbd1068fc7f99cbbedb8cfaa8..7a4004a71ffd60342a81008ca7b724b15c95d2da 100644 (file)
--- a/edit.c
+++ b/edit.c
@@ -17,6 +17,7 @@
 #include "list.h"
 #include "edit.h"
 #include "misc.h"
+#include "xmalloc.h"
 #ifdef HAVE_CONFIG_H
 #      include "config.h"
 #endif
@@ -135,7 +136,7 @@ print_editor_header(int item)
        char *header;
        char email[MAX_EMAIL_LEN];
 
-       if( (header = (char *)malloc(EDITW_COLS)) == NULL )
+       if( (header = xmalloc(EDITW_COLS)) == NULL )
                return;
 
        get_first_email(email, item);
@@ -228,7 +229,7 @@ change_field(char *msg, char **field)
        if(*field) {
                free(old);
                if(!**field)
-                       my_free(*field);
+                       xfree(*field);
        } else {
                *field = old;
                ret = 1;
@@ -249,11 +250,11 @@ change_name_field(char **field)
        change_field("Name: ", field);
 
        if( *field == NULL || ! **field ) {
-               my_free(*field);
+               xfree(*field);
                *field = strdup(tmp);
        }
 
-       my_free(tmp);
+       xfree(tmp);
 }
 
 static void
@@ -284,7 +285,7 @@ edit_emails(char c, int item)
        } else
                *emails[email_num] = 0;
 
-       my_free(database[item][EMAIL]);
+       xfree(database[item][EMAIL]);
 
        for(i = 0; i < MAX_EMAILS; i++) {
                if( *emails[i] ) {
@@ -353,15 +354,15 @@ edit_undo(int item, int mode)
                case CLEAR_UNDO:
                        if(backup) {
                                free_list_item(backup[0]);
-                               my_free(backup);
+                               xfree(backup);
                        }
                        break;
                case BACKUP_ITEM:
                        if(backup) {
                                free_list_item(backup[0]);
-                               my_free(backup);
+                               xfree(backup);
                        }
-                       backup = (list_item *)abook_malloc(sizeof(list_item));
+                       backup = xmalloc(sizeof(list_item));
                        for(i = 0; i < ITEM_FIELDS; i++)
                                backup[0][i] = safe_strdup(database[item][i]);
                        break;
@@ -369,7 +370,7 @@ edit_undo(int item, int mode)
                        if(backup) {
                                free_list_item(database[item]);
                                itemcpy(database[item], backup[0]);
-                               my_free(backup);
+                               xfree(backup);
                        }
                        break;
                default:
index e5a6005885d53e1ce74c2693beeafb4a1814f7f1..e11a60e18ee9bfb35a26ead350449e67677a21cb 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -22,6 +22,7 @@
 #include "list.h"
 #include "misc.h"
 #include "options.h"
+#include "xmalloc.h"
 #include <assert.h>
 
 extern int items;
@@ -538,7 +539,7 @@ ldif_add_item(ldif_item ldif_item)
 
 bail_out:
        for(i=0; i < LDIF_ITEM_FIELDS; i++)
-               my_free(ldif_item[i]);
+               xfree(ldif_item[i]);
 
 }
 
@@ -558,7 +559,7 @@ ldif_convert(ldif_item item, char *type, char *value)
                                if( safe_strcmp("person", value))
                                        break;
                        if(item[i])
-                               my_free(item[i]);
+                               xfree(item[i]);
                        item[i] = strdup(value);
                }
        }
@@ -579,7 +580,7 @@ ldif_parse_file(FILE *handle)
                        continue;
 
                if( -1 == ( str_parse_line(line, &type, &value, &vlen)) ) {
-                       my_free(line);
+                       xfree(line);
                        continue; /* just skip the errors */
                }
 
@@ -587,7 +588,7 @@ ldif_parse_file(FILE *handle)
 
                ldif_convert(item, type, value);
 
-               my_free(line);
+               xfree(line);
        } while ( !feof(handle) );
 
        ldif_convert(item, "dn", "");
@@ -648,7 +649,7 @@ mutt_read_line(FILE *in, char **alias, char **rest)
        /* includes also the trailing zero */
        alias_len = (size_t)(ptr - tmp + 1);
 
-       if( (*alias = (char *)malloc(alias_len)) == NULL) {
+       if( (*alias = xmalloc(alias_len)) == NULL) {
                free(line);
                return 1;
        }
@@ -725,7 +726,7 @@ mutt_parse_email(list_item item)
                                free(item[EMAIL]);
                                item[EMAIL] = tmp;
                        } else {
-                               my_free(email);
+                               xfree(email);
                        }
                }
        }
@@ -937,7 +938,7 @@ pine_parse_buf(char *buf)
        int i, len, last;
        int pine_conv_table[]= {NICK, NAME, EMAIL, -1, NOTES};
 
-       memset(&item, 0, sizeof(item) );
+       memset(&item, 0, sizeof(item));
        
        for(i=0, last=0; !last ; i++) {
                if( ! (end = strchr(start, '\t')) )
@@ -975,7 +976,7 @@ pine_parse_file(FILE *in)
 
        while(!feof(in)) {
                for(i = 2;;i++) {
-                       buf = (char *) realloc(buf, i*LINESIZE);
+                       buf = xrealloc(buf, i*LINESIZE);
                        if(i == 2)
                                strcpy(buf, line);
                        fgets(line, LINESIZE, in);
@@ -989,14 +990,14 @@ pine_parse_file(FILE *in)
                        strcat(buf, ptr);
                }
                if( *buf == '#' ) {
-                       my_free(buf);
+                       xfree(buf);
                        continue;
                }
                pine_fixbuf(buf);
 
                pine_parse_buf(buf);
 
-               my_free(buf);
+               xfree(buf);
        }
 
        return 0;
@@ -1107,7 +1108,7 @@ csv_remove_quotes(char *s)
        len = strlen(trimmed);
        if(trimmed[len - 1] == '\"' && *trimmed == '\"') {
                if(len < 3) {
-                       my_free(copy);
+                       xfree(copy);
                        return NULL;
                }
                trimmed[len - 1] = 0;
@@ -1117,7 +1118,7 @@ csv_remove_quotes(char *s)
                return trimmed;
        }
 
-       my_free(copy);
+       xfree(copy);
        return strdup(s);
 }
 
@@ -1136,7 +1137,7 @@ csv_store_field(list_item item, char *s, int field)
                        && csv_conv_table[field] >= 0) {
                item[csv_conv_table[field]] = newstr;
        } else {
-               my_free(newstr);
+               xfree(newstr);
        }
 }
 
@@ -1155,7 +1156,7 @@ allcsv_store_field(list_item item, char *s, int field)
                        && allcsv_conv_table[field] >= 0) {
                item[allcsv_conv_table[field]] = newstr;
        } else {
-               my_free(newstr);
+               xfree(newstr);
        }
 }
 
@@ -1272,7 +1273,7 @@ csv_parse_file(FILE *in)
                if(line && *line && *line != CSV_COMMENT_CHAR)
                        csv_parse_line(line);
 
-               my_free(line);
+               xfree(line);
        }
 
        return 0;
@@ -1289,7 +1290,7 @@ allcsv_parse_file(FILE *in)
                if(line && *line && *line != CSV_COMMENT_CHAR)
                        allcsv_parse_line(line);
 
-               my_free(line);
+               xfree(line);
        }
 
        return 0;
@@ -1605,7 +1606,7 @@ mutt_alias_export(FILE *out, struct db_enumerator e)
                                alias,
                                database[e.item][NAME],
                                email);
-               my_free(alias);
+               xfree(alias);
        }
 
        return 0;
@@ -1772,7 +1773,7 @@ elm_alias_export(FILE *out, struct db_enumerator e)
                                alias,
                                database[e.item][NAME],
                                email);
-               my_free(alias);
+               xfree(alias);
        }
 
        return 0;
diff --git a/misc.c b/misc.c
index 4bfe3d353cd710f5a5abb4f54fead49c16b888b0..6c96c5acbc6b65b5f43b18dad749460fc9a4da9d 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -7,9 +7,6 @@
  * Copyright (C) Jaakko Heinonen
  */
 
-#define ABOOK_SRC      1
-/*#undef ABOOK_SRC*/
-
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -23,9 +20,7 @@
 #      include <mbswidth.h>
 #endif
 #include "misc.h"
-#ifdef ABOOK_SRC
-#      include "abook.h"
-#endif
+#include "xmalloc.h"
 
 #ifndef DEBUG
 #      define NDEBUG   1
@@ -55,12 +50,12 @@ strtrim(char *s)
 
        assert(s != NULL);
 
-       for(t = s; ISSPACE(*t); t++);
+       for(t = s; isspace(*t); t++);
 
        memmove(s, t, strlen(t)+1);
 
        for (tt = t = s; *t != '\0'; t++)
-               if(!ISSPACE(*t))
+               if(!isspace(*t))
                        tt = t+1;
 
        *tt = '\0';
@@ -89,12 +84,7 @@ mkstr (const char *format, ... )
 {
        MY_VA_LOCAL_DECL;
        size_t size = 100;
-       char *buffer =
-#ifdef ABOOK_SRC
-               (char *) abook_malloc (size);
-#else
-               (char *) xmalloc (size);
-#endif
+       char *buffer = xmalloc (size);
        
        assert(format != NULL);
 
@@ -113,12 +103,7 @@ mkstr (const char *format, ... )
                else
                        size *= 2;
                
-               buffer =
-#ifdef ABOOK_SRC
-                       (char *) abook_realloc (buffer, size);
-#else
-                       (char *) xrealloc (buffer, size);
-#endif
+               buffer = xrealloc (buffer, size);
        }
 }
 
@@ -142,11 +127,7 @@ strconcat (const char *str, ...)
        MY_VA_END;
        
        concat = (char *)
-#ifdef ABOOK_SRC
-       abook_malloc(l);
-#else
        xmalloc(l);
-#endif
        if(concat == NULL)
                return NULL;
 
@@ -193,23 +174,19 @@ my_getcwd()
        char *dir = NULL;
        size_t size = 100;
 
-       if( (dir = (char *)malloc(size)) == NULL)
+       if( (dir = xmalloc(size)) == NULL)
                return NULL;
 
        *dir = 0;
        
        while( getcwd(dir, size) == NULL && errno == ERANGE )
-               if( (dir = (char *)realloc(dir, size *=2)) == NULL)
+               if( (dir = xrealloc(dir, size *=2)) == NULL)
                        return NULL;
 
        return dir;
 }
 
 #define INITIAL_SIZE   128
-#ifndef ABOOK_SRC
-#      define abook_malloc(X) xmalloc(X)
-#      define abook_realloc(X, XX) xrealloc(X, XX)
-#endif
 
 char *
 getaline(FILE *f)
@@ -233,7 +210,7 @@ getaline(FILE *f)
 
        len = 0;
        size = thres;
-       buf = (char *)abook_malloc(size);
+       buf = xmalloc(size);
 
        while (fgets(buf+len, size-len, f) != NULL) {
                len += strlen(buf+len);
@@ -241,7 +218,7 @@ getaline(FILE *f)
                        break;          /* the whole line has been read */
 
                for (inc = size, p = NULL; inc > mininc; inc /= 2)
-                       if ((p = (char *)abook_realloc(buf, size + inc)) !=
+                       if ((p = xrealloc(buf, size + inc)) !=
                                        NULL)
                                break;
 
@@ -250,7 +227,7 @@ getaline(FILE *f)
        }
 
        if (len == 0) {
-               free(buf);
+               xfree(buf);
                return NULL;    /* nothing read (eof or error) */
        }
 
@@ -258,7 +235,7 @@ getaline(FILE *f)
                buf[--len] = '\0';
 
        if (size - len > mucho) { /* a plenitude of unused memory? */
-               p = (char *)abook_realloc(buf, len+1);
+               p = xrealloc(buf, len+1);
                if (p != NULL) {
                        buf = p;
                        size = len+1;
index 81fecde44fe7015f2802f3b43e9061e60e068c6a..d43f0e725793683162fcbd0b5ce31595afeda445 100644 (file)
--- a/options.c
+++ b/options.c
@@ -388,7 +388,8 @@ load_opts(char *filename)
                                err += opt_parse_line(line, n, filename) ? 1:0;
                }
 
-               my_free(line);
+               free(line);
+               line = NULL;
        }
 
        free(line);
diff --git a/xmalloc.c b/xmalloc.c
new file mode 100644 (file)
index 0000000..086f3fb
--- /dev/null
+++ b/xmalloc.c
@@ -0,0 +1,124 @@
+/*
+ * $Id$
+ *
+ * Common xmalloc memory allocation routines
+ *
+ * written by Jaakko Heinonen <jheinonen@users.sourceforge.net>
+ */
+
+/*
+ * Copyright (c) 2005 Jaakko Heinonen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void
+xmalloc_default_error_handler(int err)
+{
+       fprintf(stderr, "Memory allocation failure: %s\n", strerror(err));
+       exit(EXIT_FAILURE);
+}
+
+static void (*xmalloc_handle_error)(int err) = xmalloc_default_error_handler;
+
+void
+xmalloc_set_error_handler(void (*func)(int err))
+{
+       if(func)
+               xmalloc_handle_error = func;
+       else
+               xmalloc_handle_error = xmalloc_default_error_handler;
+}
+
+void *
+xmalloc(size_t size)
+{
+       void *p;
+
+       if((p = malloc(size)) == NULL)
+               (*xmalloc_handle_error)(errno);
+
+       return p;
+}
+
+void *
+xmalloc0(size_t size)
+{
+       void *p;
+
+       p = xmalloc(size);
+       if(p)
+               memset(p, 0, size);
+
+       return p;
+}
+
+void *
+xrealloc(void *ptr, size_t size)
+{
+       if((ptr = realloc(ptr, size)) == NULL)
+               (*xmalloc_handle_error)(errno);
+
+       return ptr;
+}
+
+void
+xfree(void *ptr)
+{
+       free(ptr);
+       ptr = NULL;
+}
+
+static void *
+_xmalloc_inc(size_t size, size_t inc, int zero)
+{
+       size_t total_size = size + inc;
+
+       /*
+        * check if the calculation overflowed
+        */
+       if(total_size < size) {
+               (*xmalloc_handle_error)(EINVAL);
+               return NULL;
+       }
+
+       return zero ? xmalloc0(total_size) : xmalloc(total_size);
+}
+
+void *
+xmalloc_inc(size_t size, size_t inc)
+{
+       return _xmalloc_inc(size, inc, 0);
+}
+
+void *
+xmalloc0_inc(size_t size, size_t inc)
+{
+       return _xmalloc_inc(size, inc, 1);
+}
+
diff --git a/xmalloc.h b/xmalloc.h
new file mode 100644 (file)
index 0000000..f8e0bc1
--- /dev/null
+++ b/xmalloc.h
@@ -0,0 +1,13 @@
+#ifndef _XMALLOC_H
+#define _XMALLOC_H
+
+#include <stdlib.h> /* for size_t */
+
+void           xmalloc_set_error_handler(void (*)(int));
+void *         xmalloc(size_t);
+void *         xmalloc0(size_t);
+void *         xmalloc_inc(size_t, size_t);
+void *         xrealloc(void *, size_t);
+void           xfree(void *);
+
+#endif