the WHATSNEW file is gone
[debian/sudo] / alloc.c
1 /*
2  * Copyright (c) 1999-2005, 2007, 2010
3  *      Todd C. Miller <Todd.Miller@courtesan.com>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  *
17  * Sponsored in part by the Defense Advanced Research Projects
18  * Agency (DARPA) and Air Force Research Laboratory, Air Force
19  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
20  */
21
22 #include <config.h>
23
24 #include <sys/types.h>
25 #include <sys/param.h>
26 #include <stdio.h>
27 #ifdef STDC_HEADERS
28 # include <stdlib.h>
29 # include <stddef.h>
30 #else
31 # ifdef HAVE_STDLIB_H
32 #  include <stdlib.h>
33 # endif
34 #endif /* STDC_HEADERS */
35 #ifdef HAVE_STRING_H
36 # include <string.h>
37 #endif /* HAVE_STRING_H */
38 #ifdef HAVE_STRINGS_H
39 # include <strings.h>
40 #endif /* HAVE_STRING_H */
41 #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
42 # include <malloc.h>
43 #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
44 #ifdef HAVE_INTTYPES_H
45 # include <inttypes.h>
46 #endif
47
48 #include "sudo.h"
49
50 /*
51  * If there is no SIZE_MAX or SIZE_T_MAX we have to assume that size_t
52  * could be signed (as it is on SunOS 4.x).  This just means that
53  * emalloc2() and erealloc3() cannot allocate huge amounts on such a
54  * platform but that is OK since sudo doesn't need to do so anyway.
55  */
56 #ifndef SIZE_MAX
57 # ifdef SIZE_T_MAX
58 #  define SIZE_MAX      SIZE_T_MAX
59 # else
60 #  define SIZE_MAX      INT_MAX
61 # endif /* SIZE_T_MAX */
62 #endif /* SIZE_MAX */
63
64 /*
65  * emalloc() calls the system malloc(3) and exits with an error if
66  * malloc(3) fails.
67  */
68 void *
69 emalloc(size)
70     size_t size;
71 {
72     void *ptr;
73
74     if (size == 0)
75         errorx(1, "internal error, tried to emalloc(0)");
76
77     if ((ptr = malloc(size)) == NULL)
78         errorx(1, "unable to allocate memory");
79     return(ptr);
80 }
81
82 /*
83  * emalloc2() allocates nmemb * size bytes and exits with an error
84  * if overflow would occur or if the system malloc(3) fails.
85  */
86 void *
87 emalloc2(nmemb, size)
88     size_t nmemb;
89     size_t size;
90 {
91     void *ptr;
92
93     if (nmemb == 0 || size == 0)
94         errorx(1, "internal error, tried to emalloc2(0)");
95     if (nmemb > SIZE_MAX / size)
96         errorx(1, "internal error, emalloc2() overflow");
97
98     size *= nmemb;
99     if ((ptr = malloc(size)) == NULL)
100         errorx(1, "unable to allocate memory");
101     return(ptr);
102 }
103
104 /*
105  * erealloc() calls the system realloc(3) and exits with an error if
106  * realloc(3) fails.  You can call erealloc() with a NULL pointer even
107  * if the system realloc(3) does not support this.
108  */
109 void *
110 erealloc(ptr, size)
111     void *ptr;
112     size_t size;
113 {
114
115     if (size == 0)
116         errorx(1, "internal error, tried to erealloc(0)");
117
118     ptr = ptr ? realloc(ptr, size) : malloc(size);
119     if (ptr == NULL)
120         errorx(1, "unable to allocate memory");
121     return(ptr);
122 }
123
124 /*
125  * erealloc3() realloc(3)s nmemb * size bytes and exits with an error
126  * if overflow would occur or if the system malloc(3)/realloc(3) fails.
127  * You can call erealloc() with a NULL pointer even if the system realloc(3)
128  * does not support this.
129  */
130 void *
131 erealloc3(ptr, nmemb, size)
132     void *ptr;
133     size_t nmemb;
134     size_t size;
135 {
136
137     if (nmemb == 0 || size == 0)
138         errorx(1, "internal error, tried to erealloc3(0)");
139     if (nmemb > SIZE_MAX / size)
140         errorx(1, "internal error, erealloc3() overflow");
141
142     size *= nmemb;
143     ptr = ptr ? realloc(ptr, size) : malloc(size);
144     if (ptr == NULL)
145         errorx(1, "unable to allocate memory");
146     return(ptr);
147 }
148
149 /*
150  * estrdup() is like strdup(3) except that it exits with an error if
151  * malloc(3) fails.  NOTE: unlike strdup(3), estrdup(NULL) is legal.
152  */
153 char *
154 estrdup(src)
155     const char *src;
156 {
157     char *dst = NULL;
158     size_t size;
159
160     if (src != NULL) {
161         size = strlen(src) + 1;
162         dst = (char *) emalloc(size);
163         (void) memcpy(dst, src, size);
164     }
165     return(dst);
166 }
167
168 /*
169  * easprintf() calls vasprintf() and exits with an error if vasprintf()
170  * returns -1 (out of memory).
171  */
172 int
173 #ifdef __STDC__
174 easprintf(char **ret, const char *fmt, ...)
175 #else
176 easprintf(ret, fmt, va_alist)
177     char **ret;
178     const char *fmt;
179     va_dcl
180 #endif
181 {
182     int len;
183     va_list ap;
184 #ifdef __STDC__
185     va_start(ap, fmt);
186 #else
187     va_start(ap);
188 #endif
189     len = vasprintf(ret, fmt, ap);
190     va_end(ap);
191
192     if (len == -1)
193         errorx(1, "unable to allocate memory");
194     return(len);
195 }
196
197 /*
198  * evasprintf() calls vasprintf() and exits with an error if vasprintf()
199  * returns -1 (out of memory).
200  */
201 int
202 evasprintf(ret, format, args)
203     char **ret;
204     const char *format;
205     va_list args;
206 {
207     int len;
208
209     if ((len = vasprintf(ret, format, args)) == -1)
210         errorx(1, "unable to allocate memory");
211     return(len);
212 }
213
214 /*
215  * Wrapper for free(3) so we can depend on C89 semantics.
216  */
217 void
218 efree(ptr)
219     void *ptr;
220 {
221     if (ptr != NULL)
222         free(ptr);
223 }