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# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) 37# include <memory.h> 38# endif 39# include <string.h> 40#endif /* HAVE_STRING_H */ 41#ifdef HAVE_STRINGS_H 42# include <strings.h> 43#endif /* HAVE_STRING_H */ 44#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) 45# include <malloc.h> 46#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ 47#ifdef HAVE_INTTYPES_H 48# include <inttypes.h> 49#endif 50 51#include "missing.h" 52#include "alloc.h" 53#include "error.h" 54 55/* 56 * If there is no SIZE_MAX or SIZE_T_MAX we have to assume that size_t 57 * could be signed (as it is on SunOS 4.x). This just means that 58 * emalloc2() and erealloc3() cannot allocate huge amounts on such a 59 * platform but that is OK since sudo doesn't need to do so anyway. 60 */ 61#ifndef SIZE_MAX 62# ifdef SIZE_T_MAX 63# define SIZE_MAX SIZE_T_MAX 64# else 65# define SIZE_MAX INT_MAX 66# endif /* SIZE_T_MAX */ 67#endif /* SIZE_MAX */ 68 69/* 70 * emalloc() calls the system malloc(3) and exits with an error if 71 * malloc(3) fails. 72 */ 73void * 74emalloc(size) 75 size_t size; 76{ 77 void *ptr; 78 79 if (size == 0) 80 errorx(1, "internal error, tried to emalloc(0)"); 81 82 if ((ptr = malloc(size)) == NULL) 83 errorx(1, "unable to allocate memory"); 84 return ptr; 85} 86 87/* 88 * emalloc2() allocates nmemb * size bytes and exits with an error 89 * if overflow would occur or if the system malloc(3) fails. 90 */ 91void * 92emalloc2(nmemb, size) 93 size_t nmemb; 94 size_t size; 95{ 96 void *ptr; 97 98 if (nmemb == 0 || size == 0) 99 errorx(1, "internal error, tried to emalloc2(0)"); 100 if (nmemb > SIZE_MAX / size) 101 errorx(1, "internal error, emalloc2() overflow"); 102 103 size *= nmemb; 104 if ((ptr = malloc(size)) == NULL) 105 errorx(1, "unable to allocate memory"); 106 return ptr; 107} 108 109/* 110 * ecalloc() allocates nmemb * size bytes and exits with an error 111 * if overflow would occur or if the system malloc(3) fails. 112 * On success, the allocated space is zero-filled. 113 */ 114void * 115ecalloc(nmemb, size) 116 size_t nmemb; 117 size_t size; 118{ 119 void *ptr; 120 121 if (nmemb == 0 || size == 0) 122 errorx(1, "internal error, tried to ecalloc(0)"); 123 if (nmemb != 1) { 124 if (nmemb > SIZE_MAX / size) 125 errorx(1, "internal error, ecalloc() overflow"); 126 size *= nmemb; 127 } 128 if ((ptr = malloc(size)) == NULL) 129 errorx(1, "unable to allocate memory"); 130 memset(ptr, 0, size); 131 return ptr; 132} 133 134/* 135 * erealloc() calls the system realloc(3) and exits with an error if 136 * realloc(3) fails. You can call erealloc() with a NULL pointer even 137 * if the system realloc(3) does not support this. 138 */ 139void * 140erealloc(ptr, size) 141 void *ptr; 142 size_t size; 143{ 144 145 if (size == 0) 146 errorx(1, "internal error, tried to erealloc(0)"); 147 148 ptr = ptr ? realloc(ptr, size) : malloc(size); 149 if (ptr == NULL) 150 errorx(1, "unable to allocate memory"); 151 return ptr; 152} 153 154/* 155 * erealloc3() realloc(3)s nmemb * size bytes and exits with an error 156 * if overflow would occur or if the system malloc(3)/realloc(3) fails. 157 * You can call erealloc() with a NULL pointer even if the system realloc(3) 158 * does not support this. 159 */ 160void * 161erealloc3(ptr, nmemb, size) 162 void *ptr; 163 size_t nmemb; 164 size_t size; 165{ 166 167 if (nmemb == 0 || size == 0) 168 errorx(1, "internal error, tried to erealloc3(0)"); 169 if (nmemb > SIZE_MAX / size) 170 errorx(1, "internal error, erealloc3() overflow"); 171 172 size *= nmemb; 173 ptr = ptr ? realloc(ptr, size) : malloc(size); 174 if (ptr == NULL) 175 errorx(1, "unable to allocate memory"); 176 return ptr; 177} 178 179/* 180 * estrdup() is like strdup(3) except that it exits with an error if 181 * malloc(3) fails. NOTE: unlike strdup(3), estrdup(NULL) is legal. 182 */ 183char * 184estrdup(src) 185 const char *src; 186{ 187 char *dst = NULL; 188 size_t len; 189 190 if (src != NULL) { 191 len = strlen(src); 192 dst = (char *) emalloc(len + 1); 193 (void) memcpy(dst, src, len); 194 dst[len] = '\0'; 195 } 196 return dst; 197} 198 199/* 200 * estrdup() is like strndup(3) except that it exits with an error if 201 * malloc(3) fails. NOTE: unlike strdup(3), estrdup(NULL) is legal. 202 */ 203char * 204estrndup(src, maxlen) 205 const char *src; 206 size_t maxlen; 207{ 208 char *dst = NULL; 209 size_t len = 0; 210 211 if (src != NULL) { 212 while (maxlen != 0 && src[len] != '\0') { 213 len++; 214 maxlen--; 215 } 216 dst = (char *) emalloc(len + 1); 217 (void) memcpy(dst, src, len); 218 dst[len] = '\0'; 219 } 220 return dst; 221} 222 223/* 224 * easprintf() calls vasprintf() and exits with an error if vasprintf() 225 * returns -1 (out of memory). 226 */ 227int 228#ifdef __STDC__ 229easprintf(char **ret, const char *fmt, ...) 230#else 231easprintf(ret, fmt, va_alist) 232 char **ret; 233 const char *fmt; 234 va_dcl 235#endif 236{ 237 int len; 238 va_list ap; 239#ifdef __STDC__ 240 va_start(ap, fmt); 241#else 242 va_start(ap); 243#endif 244 len = vasprintf(ret, fmt, ap); 245 va_end(ap); 246 247 if (len == -1) 248 errorx(1, "unable to allocate memory"); 249 return len; 250} 251 252/* 253 * evasprintf() calls vasprintf() and exits with an error if vasprintf() 254 * returns -1 (out of memory). 255 */ 256int 257evasprintf(ret, format, args) 258 char **ret; 259 const char *format; 260 va_list args; 261{ 262 int len; 263 264 if ((len = vasprintf(ret, format, args)) == -1) 265 errorx(1, "unable to allocate memory"); 266 return len; 267} 268 269/* 270 * Wrapper for free(3) so we can depend on C89 semantics. 271 */ 272void 273efree(ptr) 274 void *ptr; 275{ 276 if (ptr != NULL) 277 free(ptr); 278} 279