[BACK]Return to alloc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / sudo

Annotation of src/usr.bin/sudo/alloc.c, Revision 1.5

1.1       millert     1: /*
1.5     ! millert     2:  * Copyright (c) 1999-2003 Todd C. Miller <Todd.Miller@courtesan.com>
1.1       millert     3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  *
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  *
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * 3. The name of the author may not be used to endorse or promote products
                     17:  *    derived from this software without specific prior written permission.
                     18:  *
                     19:  * 4. Products derived from this software may not be called "Sudo" nor
                     20:  *    may "Sudo" appear in their names without specific prior written
                     21:  *    permission from the author.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
                     24:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
                     25:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
                     26:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     27:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     28:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     29:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     30:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     31:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     32:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include "config.h"
                     36:
1.3       millert    37: #include <sys/types.h>
                     38: #include <sys/param.h>
1.1       millert    39: #include <stdio.h>
                     40: #ifdef STDC_HEADERS
1.3       millert    41: # include <stdlib.h>
                     42: # include <stddef.h>
                     43: #else
                     44: # ifdef HAVE_STDLIB_H
                     45: #  include <stdlib.h>
                     46: # endif
1.1       millert    47: #endif /* STDC_HEADERS */
                     48: #ifdef HAVE_STRING_H
1.3       millert    49: # include <string.h>
                     50: #else
                     51: # ifdef HAVE_STRINGS_H
                     52: #  include <strings.h>
                     53: # endif
1.1       millert    54: #endif /* HAVE_STRING_H */
                     55: #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
1.3       millert    56: # include <malloc.h>
1.1       millert    57: #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
1.5     ! millert    58: #include <limits.h>
1.1       millert    59:
                     60: #include "sudo.h"
                     61:
                     62: #ifndef lint
1.5     ! millert    63: static const char rcsid[] = "$Sudo: alloc.c,v 1.18 2003/03/15 20:31:01 millert Exp $";
1.1       millert    64: #endif /* lint */
                     65:
1.5     ! millert    66: /*
        !            67:  * If there is no SIZE_MAX or SIZE_T_MAX we have to assume that size_t
        !            68:  * could be signed (as it is on SunOS 4.x).  This just means that
        !            69:  * emalloc2() and erealloc3() cannot allocate huge amounts on such a
        !            70:  * platform but that is OK since sudo doesn't need to do so anyway.
        !            71:  */
        !            72: #ifndef SIZE_MAX
        !            73: # ifdef SIZE_T_MAX
        !            74: #  define SIZE_MAX     SIZE_T_MAX
        !            75: # else
        !            76: #  ifdef INT_MAX
        !            77: #   define SIZE_MAX    INT_MAX
        !            78: #  else
        !            79: #   define SIZE_MAX    0x7fffffff
        !            80: #  endif /* ULONG_MAX */
        !            81: # endif /* SIZE_T_MAX */
        !            82: #endif /* SIZE_MAX */
        !            83:
1.4       millert    84: extern char **Argv;            /* from sudo.c */
1.1       millert    85:
                     86: /*
                     87:  * emalloc() calls the system malloc(3) and exits with an error if
                     88:  * malloc(3) fails.
                     89:  */
                     90: VOID *
                     91: emalloc(size)
                     92:     size_t size;
                     93: {
                     94:     VOID *ptr;
                     95:
1.5     ! millert    96:     if (size == 0) {
        !            97:        (void) fprintf(stderr, "%s: internal error, tried to emalloc(0)\n",
        !            98:            Argv[0]);
        !            99:        exit(1);
        !           100:     }
        !           101:     if ((ptr = (VOID *) malloc(size)) == NULL) {
        !           102:        (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
        !           103:        exit(1);
        !           104:     }
        !           105:     return(ptr);
        !           106: }
        !           107:
        !           108: /*
        !           109:  * emalloc2() allocates nmemb * size bytes and exits with an error
        !           110:  * if overflow would occur or if the system malloc(3) fails.
        !           111:  */
        !           112: VOID *
        !           113: emalloc2(nmemb, size)
        !           114:     size_t nmemb;
        !           115:     size_t size;
        !           116: {
        !           117:     VOID *ptr;
        !           118:
        !           119:     if (nmemb == 0 || size == 0) {
        !           120:        (void) fprintf(stderr, "%s: internal error, tried to emalloc2(0)\n",
        !           121:            Argv[0]);
        !           122:        exit(1);
        !           123:     }
        !           124:     if (nmemb > SIZE_MAX / size) {
        !           125:        (void) fprintf(stderr, "%s: internal error, emalloc2() overflow\n",
        !           126:            Argv[0]);
        !           127:        exit(1);
        !           128:     }
        !           129:     size *= nmemb;
1.4       millert   130:     if ((ptr = (VOID *) malloc(size)) == NULL) {
1.1       millert   131:        (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
                    132:        exit(1);
                    133:     }
                    134:     return(ptr);
                    135: }
                    136:
                    137: /*
                    138:  * erealloc() calls the system realloc(3) and exits with an error if
                    139:  * realloc(3) fails.  You can call erealloc() with a NULL pointer even
                    140:  * if the system realloc(3) does not support this.
                    141:  */
                    142: VOID *
                    143: erealloc(ptr, size)
                    144:     VOID *ptr;
                    145:     size_t size;
                    146: {
                    147:
1.5     ! millert   148:     if (size == 0) {
        !           149:        (void) fprintf(stderr, "%s: internal error, tried to erealloc(0)\n",
        !           150:            Argv[0]);
        !           151:        exit(1);
        !           152:     }
        !           153:     ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size);
        !           154:     if (ptr == NULL) {
        !           155:        (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
        !           156:        exit(1);
        !           157:     }
        !           158:     return(ptr);
        !           159: }
        !           160:
        !           161: /*
        !           162:  * erealloc3() realloc(3)s nmemb * size bytes and exits with an error
        !           163:  * if overflow would occur or if the system malloc(3)/realloc(3) fails.
        !           164:  * You can call erealloc() with a NULL pointer even if the system realloc(3)
        !           165:  * does not support this.
        !           166:  */
        !           167: VOID *
        !           168: erealloc3(ptr, nmemb, size)
        !           169:     VOID *ptr;
        !           170:     size_t nmemb;
        !           171:     size_t size;
        !           172: {
        !           173:
        !           174:     if (nmemb == 0 || size == 0) {
        !           175:        (void) fprintf(stderr, "%s: internal error, tried to erealloc3(0)\n",
        !           176:            Argv[0]);
        !           177:        exit(1);
        !           178:     }
        !           179:     if (nmemb > SIZE_MAX / size) {
        !           180:        (void) fprintf(stderr, "%s: internal error, erealloc3() overflow\n",
        !           181:            Argv[0]);
        !           182:        exit(1);
        !           183:     }
        !           184:     size *= nmemb;
1.4       millert   185:     ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size);
                    186:     if (ptr == NULL) {
1.1       millert   187:        (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
                    188:        exit(1);
                    189:     }
                    190:     return(ptr);
                    191: }
                    192:
                    193: /*
                    194:  * estrdup() is like strdup(3) except that it exits with an error if
                    195:  * malloc(3) fails.  NOTE: unlike strdup(3), estrdup(NULL) is legal.
                    196:  */
                    197: char *
                    198: estrdup(src)
                    199:     const char *src;
                    200: {
                    201:     char *dst = NULL;
1.5     ! millert   202:     size_t size;
1.1       millert   203:
                    204:     if (src != NULL) {
1.5     ! millert   205:        size = strlen(src) + 1;
        !           206:        dst = (char *) emalloc(size);
        !           207:        (void) memcpy(dst, src, size);
1.1       millert   208:     }
                    209:     return(dst);
                    210: }
                    211:
                    212: /*
                    213:  * easprintf() calls vasprintf() and exits with an error if vasprintf()
                    214:  * returns -1 (out of memory).
                    215:  */
1.2       millert   216: int
1.1       millert   217: #ifdef __STDC__
                    218: easprintf(char **ret, const char *fmt, ...)
                    219: #else
                    220: easprintf(va_alist)
                    221:     va_dcl
                    222: #endif
                    223: {
                    224:     int len;
                    225:     va_list ap;
                    226: #ifdef __STDC__
                    227:     va_start(ap, fmt);
                    228: #else
                    229:     char **ret;
                    230:     const char *fmt;
                    231:
                    232:     va_start(ap);
                    233:     ret = va_arg(ap, char **);
                    234:     fmt = va_arg(ap, const char *);
                    235: #endif
                    236:     len = vasprintf(ret, fmt, ap);
                    237:     va_end(ap);
                    238:
                    239:     if (len == -1) {
                    240:        (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
                    241:        exit(1);
                    242:     }
1.2       millert   243:     return(len);
1.1       millert   244: }
                    245:
                    246: /*
                    247:  * evasprintf() calls vasprintf() and exits with an error if vasprintf()
                    248:  * returns -1 (out of memory).
                    249:  */
1.2       millert   250: int
1.1       millert   251: evasprintf(ret, format, args)
                    252:     char **ret;
                    253:     const char *format;
                    254:     va_list args;
                    255: {
1.2       millert   256:     int len;
1.1       millert   257:
1.2       millert   258:     if ((len = vasprintf(ret, format, args)) == -1) {
1.1       millert   259:        (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
                    260:        exit(1);
                    261:     }
1.2       millert   262:     return(len);
1.1       millert   263: }