Imported Upstream version 1.6.8p5
[debian/sudo] / alloc.c
1 /*
2  * Copyright (c) 1999-2003 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
50 #include "sudo.h"
51
52 #ifndef lint
53 static const char rcsid[] = "$Sudo: alloc.c,v 1.23 2004/06/01 16:23:32 millert Exp $";
54 #endif /* lint */
55
56 /*
57  * If there is no SIZE_MAX or SIZE_T_MAX we have to assume that size_t
58  * could be signed (as it is on SunOS 4.x).  This just means that
59  * emalloc2() and erealloc3() cannot allocate huge amounts on such a
60  * platform but that is OK since sudo doesn't need to do so anyway.
61  */
62 #ifndef SIZE_MAX
63 # ifdef SIZE_T_MAX
64 #  define SIZE_MAX      SIZE_T_MAX
65 # else
66 #  define SIZE_MAX      INT_MAX
67 # endif /* SIZE_T_MAX */
68 #endif /* SIZE_MAX */
69
70 /*
71  * emalloc() calls the system malloc(3) and exits with an error if
72  * malloc(3) fails.
73  */
74 VOID *
75 emalloc(size)
76     size_t size;
77 {
78     VOID *ptr;
79
80     if (size == 0)
81         errx(1, "internal error, tried to emalloc(0)");
82
83     if ((ptr = (VOID *) malloc(size)) == NULL)
84         errx(1, "unable to allocate memory");
85     return(ptr);
86 }
87
88 /*
89  * emalloc2() allocates nmemb * size bytes and exits with an error
90  * if overflow would occur or if the system malloc(3) fails.
91  */
92 VOID *
93 emalloc2(nmemb, size)
94     size_t nmemb;
95     size_t size;
96 {
97     VOID *ptr;
98
99     if (nmemb == 0 || size == 0)
100         errx(1, "internal error, tried to emalloc2(0)");
101     if (nmemb > SIZE_MAX / size)
102         errx(1, "internal error, emalloc2() overflow");
103
104     size *= nmemb;
105     if ((ptr = (VOID *) malloc(size)) == NULL)
106         errx(1, "unable to allocate memory");
107     return(ptr);
108 }
109
110 /*
111  * erealloc() calls the system realloc(3) and exits with an error if
112  * realloc(3) fails.  You can call erealloc() with a NULL pointer even
113  * if the system realloc(3) does not support this.
114  */
115 VOID *
116 erealloc(ptr, size)
117     VOID *ptr;
118     size_t size;
119 {
120
121     if (size == 0)
122         errx(1, "internal error, tried to erealloc(0)");
123
124     ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size);
125     if (ptr == NULL)
126         errx(1, "unable to allocate memory");
127     return(ptr);
128 }
129
130 /*
131  * erealloc3() realloc(3)s nmemb * size bytes and exits with an error
132  * if overflow would occur or if the system malloc(3)/realloc(3) fails.
133  * You can call erealloc() with a NULL pointer even if the system realloc(3)
134  * does not support this.
135  */
136 VOID *
137 erealloc3(ptr, nmemb, size)
138     VOID *ptr;
139     size_t nmemb;
140     size_t size;
141 {
142
143     if (nmemb == 0 || size == 0)
144         errx(1, "internal error, tried to erealloc3(0)");
145     if (nmemb > SIZE_MAX / size)
146         errx(1, "internal error, erealloc3() overflow");
147
148     size *= nmemb;
149     ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size);
150     if (ptr == NULL)
151         errx(1, "unable to allocate memory");
152     return(ptr);
153 }
154
155 /*
156  * estrdup() is like strdup(3) except that it exits with an error if
157  * malloc(3) fails.  NOTE: unlike strdup(3), estrdup(NULL) is legal.
158  */
159 char *
160 estrdup(src)
161     const char *src;
162 {
163     char *dst = NULL;
164     size_t size;
165
166     if (src != NULL) {
167         size = strlen(src) + 1;
168         dst = (char *) emalloc(size);
169         (void) memcpy(dst, src, size);
170     }
171     return(dst);
172 }
173
174 /*
175  * easprintf() calls vasprintf() and exits with an error if vasprintf()
176  * returns -1 (out of memory).
177  */
178 int
179 #ifdef __STDC__
180 easprintf(char **ret, const char *fmt, ...)
181 #else
182 easprintf(va_alist)
183     va_dcl
184 #endif
185 {
186     int len;
187     va_list ap;
188 #ifdef __STDC__
189     va_start(ap, fmt);
190 #else
191     char **ret;
192     const char *fmt;
193
194     va_start(ap);
195     ret = va_arg(ap, char **);
196     fmt = va_arg(ap, const char *);
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 }