File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / common / alloc.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:26:49 2012 UTC (12 years, 1 month ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_5p1, HEAD
sudo 1.8.5p1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>