Annotation of src/usr.bin/sudo/alloc.c, Revision 1.7
1.1 millert 1: /*
1.5 millert 2: * Copyright (c) 1999-2003 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 millert 3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: *
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: *
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * 3. The name of the author may not be used to endorse or promote products
17: * derived from this software without specific prior written permission.
18: *
19: * 4. Products derived from this software may not be called "Sudo" nor
20: * may "Sudo" appear in their names without specific prior written
21: * permission from the author.
22: *
23: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
26: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.7 ! millert 33: *
! 34: * Sponsored in part by the Defense Advanced Research Projects
! 35: * Agency (DARPA) and Air Force Research Laboratory, Air Force
! 36: * Materiel Command, USAF, under agreement number F39502-99-1-0512.
1.1 millert 37: */
38:
39: #include "config.h"
40:
1.3 millert 41: #include <sys/types.h>
42: #include <sys/param.h>
1.1 millert 43: #include <stdio.h>
44: #ifdef STDC_HEADERS
1.3 millert 45: # include <stdlib.h>
46: # include <stddef.h>
47: #else
48: # ifdef HAVE_STDLIB_H
49: # include <stdlib.h>
50: # endif
1.1 millert 51: #endif /* STDC_HEADERS */
52: #ifdef HAVE_STRING_H
1.3 millert 53: # include <string.h>
54: #else
55: # ifdef HAVE_STRINGS_H
56: # include <strings.h>
57: # endif
1.1 millert 58: #endif /* HAVE_STRING_H */
59: #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
1.3 millert 60: # include <malloc.h>
1.1 millert 61: #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
1.6 millert 62: #ifdef HAVE_ERR_H
63: # include <err.h>
64: #else
65: # include "emul/err.h"
66: #endif /* HAVE_ERR_H */
1.5 millert 67: #include <limits.h>
1.1 millert 68:
69: #include "sudo.h"
70:
71: #ifndef lint
1.7 ! millert 72: static const char rcsid[] = "$Sudo: alloc.c,v 1.20 2003/04/16 00:42:09 millert Exp $";
1.1 millert 73: #endif /* lint */
74:
1.5 millert 75: /*
76: * If there is no SIZE_MAX or SIZE_T_MAX we have to assume that size_t
77: * could be signed (as it is on SunOS 4.x). This just means that
78: * emalloc2() and erealloc3() cannot allocate huge amounts on such a
79: * platform but that is OK since sudo doesn't need to do so anyway.
80: */
81: #ifndef SIZE_MAX
82: # ifdef SIZE_T_MAX
83: # define SIZE_MAX SIZE_T_MAX
84: # else
85: # ifdef INT_MAX
86: # define SIZE_MAX INT_MAX
87: # else
88: # define SIZE_MAX 0x7fffffff
89: # endif /* ULONG_MAX */
90: # endif /* SIZE_T_MAX */
91: #endif /* SIZE_MAX */
92:
1.1 millert 93: /*
94: * emalloc() calls the system malloc(3) and exits with an error if
95: * malloc(3) fails.
96: */
97: VOID *
98: emalloc(size)
99: size_t size;
100: {
101: VOID *ptr;
102:
1.6 millert 103: if (size == 0)
104: errx(1, "internal error, tried to emalloc(0)");
105:
106: if ((ptr = (VOID *) malloc(size)) == NULL)
107: errx(1, "unable to allocate memory");
1.5 millert 108: return(ptr);
109: }
110:
111: /*
112: * emalloc2() allocates nmemb * size bytes and exits with an error
113: * if overflow would occur or if the system malloc(3) fails.
114: */
115: VOID *
116: emalloc2(nmemb, size)
117: size_t nmemb;
118: size_t size;
119: {
120: VOID *ptr;
121:
1.6 millert 122: if (nmemb == 0 || size == 0)
123: errx(1, "internal error, tried to emalloc2(0)");
124: if (nmemb > SIZE_MAX / size)
125: errx(1, "internal error, emalloc2() overflow");
126:
1.5 millert 127: size *= nmemb;
1.6 millert 128: if ((ptr = (VOID *) malloc(size)) == NULL)
129: errx(1, "unable to allocate memory");
1.1 millert 130: return(ptr);
131: }
132:
133: /*
134: * erealloc() calls the system realloc(3) and exits with an error if
135: * realloc(3) fails. You can call erealloc() with a NULL pointer even
136: * if the system realloc(3) does not support this.
137: */
138: VOID *
139: erealloc(ptr, size)
140: VOID *ptr;
141: size_t size;
142: {
143:
1.6 millert 144: if (size == 0)
145: errx(1, "internal error, tried to erealloc(0)");
146:
1.5 millert 147: ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size);
1.6 millert 148: if (ptr == NULL)
149: errx(1, "unable to allocate memory");
1.5 millert 150: return(ptr);
151: }
152:
153: /*
154: * erealloc3() realloc(3)s nmemb * size bytes and exits with an error
155: * if overflow would occur or if the system malloc(3)/realloc(3) fails.
156: * You can call erealloc() with a NULL pointer even if the system realloc(3)
157: * does not support this.
158: */
159: VOID *
160: erealloc3(ptr, nmemb, size)
161: VOID *ptr;
162: size_t nmemb;
163: size_t size;
164: {
165:
1.6 millert 166: if (nmemb == 0 || size == 0)
167: errx(1, "internal error, tried to erealloc3(0)");
168: if (nmemb > SIZE_MAX / size)
169: errx(1, "internal error, erealloc3() overflow");
170:
1.5 millert 171: size *= nmemb;
1.4 millert 172: ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size);
1.6 millert 173: if (ptr == NULL)
174: errx(1, "unable to allocate memory");
1.1 millert 175: return(ptr);
176: }
177:
178: /*
179: * estrdup() is like strdup(3) except that it exits with an error if
180: * malloc(3) fails. NOTE: unlike strdup(3), estrdup(NULL) is legal.
181: */
182: char *
183: estrdup(src)
184: const char *src;
185: {
186: char *dst = NULL;
1.5 millert 187: size_t size;
1.1 millert 188:
189: if (src != NULL) {
1.5 millert 190: size = strlen(src) + 1;
191: dst = (char *) emalloc(size);
192: (void) memcpy(dst, src, size);
1.1 millert 193: }
194: return(dst);
195: }
196:
197: /*
198: * easprintf() calls vasprintf() and exits with an error if vasprintf()
199: * returns -1 (out of memory).
200: */
1.2 millert 201: int
1.1 millert 202: #ifdef __STDC__
203: easprintf(char **ret, const char *fmt, ...)
204: #else
205: easprintf(va_alist)
206: va_dcl
207: #endif
208: {
209: int len;
210: va_list ap;
211: #ifdef __STDC__
212: va_start(ap, fmt);
213: #else
214: char **ret;
215: const char *fmt;
216:
217: va_start(ap);
218: ret = va_arg(ap, char **);
219: fmt = va_arg(ap, const char *);
220: #endif
221: len = vasprintf(ret, fmt, ap);
222: va_end(ap);
223:
1.6 millert 224: if (len == -1)
225: errx(1, "unable to allocate memory");
1.2 millert 226: return(len);
1.1 millert 227: }
228:
229: /*
230: * evasprintf() calls vasprintf() and exits with an error if vasprintf()
231: * returns -1 (out of memory).
232: */
1.2 millert 233: int
1.1 millert 234: evasprintf(ret, format, args)
235: char **ret;
236: const char *format;
237: va_list args;
238: {
1.2 millert 239: int len;
1.1 millert 240:
1.6 millert 241: if ((len = vasprintf(ret, format, args)) == -1)
242: errx(1, "unable to allocate memory");
1.2 millert 243: return(len);
1.1 millert 244: }