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