Annotation of embedaddon/sudo/common/alloc.c, revision 1.1.1.5

1.1       misho       1: /*
1.1.1.4   misho       2:  * Copyright (c) 1999-2005, 2007, 2010-2013
1.1       misho       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"
1.1.1.5 ! misho      52: #include "fatal.h"
1.1       misho      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)
1.1.1.4   misho      81:        fatalx_nodebug(_("internal error, tried to emalloc(0)"));
1.1       misho      82: 
                     83:     if ((ptr = malloc(size)) == NULL)
1.1.1.5 ! misho      84:        fatal_nodebug(NULL);
1.1       misho      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)
1.1.1.4   misho      98:        fatalx_nodebug(_("internal error, tried to emalloc2(0)"));
1.1       misho      99:     if (nmemb > SIZE_MAX / size)
1.1.1.4   misho     100:        fatalx_nodebug(_("internal error, %s overflow"), "emalloc2()");
1.1       misho     101: 
                    102:     size *= nmemb;
                    103:     if ((ptr = malloc(size)) == NULL)
1.1.1.5 ! misho     104:        fatal_nodebug(NULL);
1.1.1.2   misho     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)
1.1.1.4   misho     119:        fatalx_nodebug(_("internal error, tried to ecalloc(0)"));
1.1.1.2   misho     120:     if (nmemb != 1) {
                    121:        if (nmemb > SIZE_MAX / size)
1.1.1.4   misho     122:            fatalx_nodebug(_("internal error, %s overflow"), "ecalloc()");
1.1.1.2   misho     123:        size *= nmemb;
                    124:     }
                    125:     if ((ptr = malloc(size)) == NULL)
1.1.1.5 ! misho     126:        fatal_nodebug(NULL);
1.1.1.2   misho     127:     memset(ptr, 0, size);
1.1       misho     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)
1.1.1.4   misho     141:        fatalx_nodebug(_("internal error, tried to erealloc(0)"));
1.1       misho     142: 
                    143:     ptr = ptr ? realloc(ptr, size) : malloc(size);
                    144:     if (ptr == NULL)
1.1.1.5 ! misho     145:        fatal_nodebug(NULL);
1.1       misho     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)
1.1.1.4   misho     160:        fatalx_nodebug(_("internal error, tried to erealloc3(0)"));
1.1       misho     161:     if (nmemb > SIZE_MAX / size)
1.1.1.4   misho     162:        fatalx_nodebug(_("internal error, %s overflow"), "erealloc3()");
1.1       misho     163: 
                    164:     size *= nmemb;
                    165:     ptr = ptr ? realloc(ptr, size) : malloc(size);
                    166:     if (ptr == NULL)
1.1.1.5 ! misho     167:        fatal_nodebug(NULL);
1.1.1.2   misho     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)
1.1.1.4   misho     184:        fatalx_nodebug(_("internal error, tried to erecalloc(0)"));
1.1.1.2   misho     185:     if (nmemb > SIZE_MAX / msize)
1.1.1.4   misho     186:        fatalx_nodebug(_("internal error, %s overflow"), "erecalloc()");
1.1.1.2   misho     187: 
                    188:     size = nmemb * msize;
                    189:     ptr = ptr ? realloc(ptr, size) : malloc(size);
                    190:     if (ptr == NULL)
1.1.1.5 ! misho     191:        fatal_nodebug(NULL);
1.1.1.2   misho     192:     if (nmemb > onmemb) {
                    193:        size = (nmemb - onmemb) * msize;
                    194:        memset((char *)ptr + (onmemb * msize), 0, size);
                    195:     }
1.1       misho     196:     return ptr;
                    197: }
1.1.1.2   misho     198: #endif
1.1       misho     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;
1.1.1.2   misho     227:     size_t len = 0;
1.1       misho     228: 
                    229:     if (src != NULL) {
1.1.1.2   misho     230:        while (maxlen != 0 && src[len] != '\0') {
                    231:            len++;
                    232:            maxlen--;
                    233:        }
1.1       misho     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;
1.1.1.4   misho     250: 
1.1       misho     251:     va_start(ap, fmt);
                    252:     len = vasprintf(ret, fmt, ap);
                    253:     va_end(ap);
                    254: 
                    255:     if (len == -1)
1.1.1.5 ! misho     256:        fatal_nodebug(NULL);
1.1       misho     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)
1.1.1.5 ! misho     270:        fatal_nodebug(NULL);
1.1       misho     271:     return len;
                    272: }

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