]> git.deb.at Git - pkg/abook.git/blob - xmalloc.c
- add xstrdup to have proper checking for memory allocation failures
[pkg/abook.git] / xmalloc.c
1 /*
2  * $Id$
3  *
4  * Common xmalloc memory allocation routines
5  *
6  * written by Jaakko Heinonen <jheinonen@users.sourceforge.net>
7  */
8
9 /*
10  * Copyright (c) 2005 Jaakko Heinonen
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer
18  *    in this position and unchanged.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include <errno.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include "xmalloc.h"
40
41 static void
42 xmalloc_default_error_handler(int err)
43 {
44         fprintf(stderr, "Memory allocation failure: %s\n", strerror(err));
45         exit(EXIT_FAILURE);
46 }
47
48 static void (*xmalloc_handle_error)(int err) = xmalloc_default_error_handler;
49
50 void
51 xmalloc_set_error_handler(void (*func)(int err))
52 {
53         if(func)
54                 xmalloc_handle_error = func;
55         else
56                 xmalloc_handle_error = xmalloc_default_error_handler;
57 }
58
59 void *
60 xmalloc(size_t size)
61 {
62         void *p;
63
64         if((p = malloc(size)) == NULL)
65                 (*xmalloc_handle_error)(errno);
66
67         return p;
68 }
69
70 void *
71 xmalloc0(size_t size)
72 {
73         void *p;
74
75         p = xmalloc(size);
76         if(p)
77                 memset(p, 0, size);
78
79         return p;
80 }
81
82 static void *
83 _xmalloc_inc(size_t size, size_t inc, int zero)
84 {
85         size_t total_size = size + inc;
86
87         /*
88          * check if the calculation overflowed
89          */
90         if(total_size < size) {
91                 (*xmalloc_handle_error)(EINVAL);
92                 return NULL;
93         }
94
95         return zero ? xmalloc0(total_size) : xmalloc(total_size);
96 }
97
98 void *
99 xmalloc_inc(size_t size, size_t inc)
100 {
101         return _xmalloc_inc(size, inc, 0);
102 }
103
104 void *
105 xmalloc0_inc(size_t size, size_t inc)
106 {
107         return _xmalloc_inc(size, inc, 1);
108 }
109
110 void *
111 xrealloc(void *ptr, size_t size)
112 {
113         if((ptr = realloc(ptr, size)) == NULL)
114                 (*xmalloc_handle_error)(errno);
115
116         return ptr;
117 }
118
119 void *
120 xrealloc_inc(void *ptr, size_t size, size_t inc)
121 {
122         size_t total_size = size + inc;
123
124         /*
125          * check if the calculation overflowed
126          */
127         if(total_size < size) {
128                 (*xmalloc_handle_error)(EINVAL);
129                 return NULL;
130         }
131
132         if((ptr = realloc(ptr, total_size)) == NULL)
133                 (*xmalloc_handle_error)(errno);
134
135         return ptr;
136 }
137
138 char *
139 xstrdup(const char *s)
140 {
141         size_t len = strlen(s);
142         void *new;
143
144         new = xmalloc_inc(len, 1);
145         if(new == NULL)
146                 return NULL;
147
148         return (char *)memcpy(new, s, len + 1);
149 }
150