File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / common / alloc.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 07:56:33 2013 UTC (10 years, 8 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, HEAD
v 1.8.8

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

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