]> git.deb.at Git - pkg/abook.git/blob - xmalloc.c
Upload 0.6.1-2 to unstable
[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 "gettext.h"
40 #include "xmalloc.h"
41
42 static void
43 xmalloc_default_error_handler(int err)
44 {
45         fprintf(stderr, _("Memory allocation failure: %s\n"), strerror(err));
46         exit(EXIT_FAILURE);
47 }
48
49 static void (*xmalloc_handle_error)(int err) = xmalloc_default_error_handler;
50
51 void
52 xmalloc_set_error_handler(void (*func)(int err))
53 {
54         if(func)
55                 xmalloc_handle_error = func;
56         else
57                 xmalloc_handle_error = xmalloc_default_error_handler;
58 }
59
60 void *
61 xmalloc(size_t size)
62 {
63         void *p;
64
65         if((p = malloc(size)) == NULL)
66                 (*xmalloc_handle_error)(errno);
67
68         return p;
69 }
70
71 void *
72 xmalloc0(size_t size)
73 {
74         void *p;
75
76         p = xmalloc(size);
77         if(p)
78                 memset(p, 0, size);
79
80         return p;
81 }
82
83 static void *
84 _xmalloc_inc(size_t size, size_t inc, int zero)
85 {
86         size_t total_size = size + inc;
87
88         /*
89          * check if the calculation overflowed
90          */
91         if(total_size < size) {
92                 (*xmalloc_handle_error)(EINVAL);
93                 return NULL;
94         }
95
96         return zero ? xmalloc0(total_size) : xmalloc(total_size);
97 }
98
99 void *
100 xmalloc_inc(size_t size, size_t inc)
101 {
102         return _xmalloc_inc(size, inc, 0);
103 }
104
105 void *
106 xmalloc0_inc(size_t size, size_t inc)
107 {
108         return _xmalloc_inc(size, inc, 1);
109 }
110
111 void *
112 xrealloc(void *ptr, size_t size)
113 {
114         if((ptr = realloc(ptr, size)) == NULL)
115                 (*xmalloc_handle_error)(errno);
116
117         return ptr;
118 }
119
120 void *
121 xrealloc_inc(void *ptr, size_t size, size_t inc)
122 {
123         size_t total_size = size + inc;
124
125         /*
126          * check if the calculation overflowed
127          */
128         if(total_size < size) {
129                 (*xmalloc_handle_error)(EINVAL);
130                 return NULL;
131         }
132
133         if((ptr = realloc(ptr, total_size)) == NULL)
134                 (*xmalloc_handle_error)(errno);
135
136         return ptr;
137 }
138
139 char *
140 xstrdup(const char *s)
141 {
142         size_t len = strlen(s);
143         void *new;
144
145         new = xmalloc_inc(len, 1);
146         if(new == NULL)
147                 return NULL;
148
149         return (char *)memcpy(new, s, len + 1);
150 }
151
152 char *
153 xstrndup(const char *s, size_t len)
154 {
155         char *new;
156         size_t n = strlen(s);
157
158         if(n > len)
159                 n = len;
160
161         new = xmalloc_inc(n, 1);
162         if(new == NULL)
163                 return NULL;
164
165         memcpy(new, s, n);
166         new[n] = '\0';
167
168         return new;
169 }