File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / common / alloc.c
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:12:54 2014 UTC (10 years ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_10p3_0, v1_8_10p3, HEAD
sudo v 1.8.10p3

    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: #include <limits.h>
   50: 
   51: #define DEFAULT_TEXT_DOMAIN	"sudo"
   52: #include "gettext.h"		/* must be included before missing.h */
   53: 
   54: #include "missing.h"
   55: #include "alloc.h"
   56: #include "fatal.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: 	fatalx_nodebug(_("internal error, tried to emalloc(0)"));
   83: 
   84:     if ((ptr = malloc(size)) == NULL)
   85: 	fatal_nodebug(NULL);
   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: 	fatalx_nodebug(_("internal error, tried to emalloc2(0)"));
  100:     if (nmemb > SIZE_MAX / size)
  101: 	fatalx_nodebug(_("internal error, %s overflow"), "emalloc2()");
  102: 
  103:     size *= nmemb;
  104:     if ((ptr = malloc(size)) == NULL)
  105: 	fatal_nodebug(NULL);
  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: 	fatalx_nodebug(_("internal error, tried to ecalloc(0)"));
  121:     if (nmemb != 1) {
  122: 	if (nmemb > SIZE_MAX / size)
  123: 	    fatalx_nodebug(_("internal error, %s overflow"), "ecalloc()");
  124: 	size *= nmemb;
  125:     }
  126:     if ((ptr = malloc(size)) == NULL)
  127: 	fatal_nodebug(NULL);
  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: 	fatalx_nodebug(_("internal error, tried to erealloc(0)"));
  143: 
  144:     ptr = ptr ? realloc(ptr, size) : malloc(size);
  145:     if (ptr == NULL)
  146: 	fatal_nodebug(NULL);
  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: 	fatalx_nodebug(_("internal error, tried to erealloc3(0)"));
  162:     if (nmemb > SIZE_MAX / size)
  163: 	fatalx_nodebug(_("internal error, %s overflow"), "erealloc3()");
  164: 
  165:     size *= nmemb;
  166:     ptr = ptr ? realloc(ptr, size) : malloc(size);
  167:     if (ptr == NULL)
  168: 	fatal_nodebug(NULL);
  169:     return ptr;
  170: }
  171: 
  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 erealloc()
  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: 
  199: /*
  200:  * estrdup() is like strdup(3) except that it exits with an error if
  201:  * malloc(3) fails.  NOTE: unlike strdup(3), estrdup(NULL) is legal.
  202:  */
  203: char *
  204: estrdup(const char *src)
  205: {
  206:     char *dst = NULL;
  207:     size_t len;
  208: 
  209:     if (src != NULL) {
  210: 	len = strlen(src);
  211: 	dst = (char *) emalloc(len + 1);
  212: 	(void) memcpy(dst, src, len);
  213: 	dst[len] = '\0';
  214:     }
  215:     return dst;
  216: }
  217: 
  218: /*
  219:  * estrdup() is like strndup(3) except that it exits with an error if
  220:  * malloc(3) fails.  NOTE: unlike strdup(3), estrdup(NULL) is legal.
  221:  */
  222: char *
  223: estrndup(const char *src, size_t maxlen)
  224: {
  225:     char *dst = NULL;
  226:     size_t len = 0;
  227: 
  228:     if (src != NULL) {
  229: 	while (maxlen != 0 && src[len] != '\0') {
  230: 	    len++;
  231: 	    maxlen--;
  232: 	}
  233: 	dst = (char *) emalloc(len + 1);
  234: 	(void) memcpy(dst, src, len);
  235: 	dst[len] = '\0';
  236:     }
  237:     return dst;
  238: }
  239: 
  240: /*
  241:  * easprintf() calls vasprintf() and exits with an error if vasprintf()
  242:  * returns -1 (out of memory).
  243:  */
  244: int
  245: easprintf(char **ret, const char *fmt, ...)
  246: {
  247:     int len;
  248:     va_list ap;
  249: 
  250:     va_start(ap, fmt);
  251:     len = vasprintf(ret, fmt, ap);
  252:     va_end(ap);
  253: 
  254:     if (len == -1)
  255: 	fatal_nodebug(NULL);
  256:     return len;
  257: }
  258: 
  259: /*
  260:  * evasprintf() calls vasprintf() and exits with an error if vasprintf()
  261:  * returns -1 (out of memory).
  262:  */
  263: int
  264: evasprintf(char **ret, const char *format, va_list args)
  265: {
  266:     int len;
  267: 
  268:     if ((len = vasprintf(ret, format, args)) == -1)
  269: 	fatal_nodebug(NULL);
  270:     return len;
  271: }

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