version 1.4, 2002/01/14 00:11:44 |
version 1.5, 2003/03/15 21:23:53 |
|
|
/* |
/* |
* Copyright (c) 1999-2002 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 1999-2003 Todd C. Miller <Todd.Miller@courtesan.com> |
* All rights reserved. |
* All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
|
|
#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) |
#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) |
# include <malloc.h> |
# include <malloc.h> |
#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ |
#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ |
|
#include <limits.h> |
|
|
#include "sudo.h" |
#include "sudo.h" |
|
|
#ifndef lint |
#ifndef lint |
static const char rcsid[] = "$Sudo: alloc.c,v 1.11 2002/01/09 16:56:04 millert Exp $"; |
static const char rcsid[] = "$Sudo: alloc.c,v 1.18 2003/03/15 20:31:01 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
|
/* |
|
* If there is no SIZE_MAX or SIZE_T_MAX we have to assume that size_t |
|
* could be signed (as it is on SunOS 4.x). This just means that |
|
* emalloc2() and erealloc3() cannot allocate huge amounts on such a |
|
* platform but that is OK since sudo doesn't need to do so anyway. |
|
*/ |
|
#ifndef SIZE_MAX |
|
# ifdef SIZE_T_MAX |
|
# define SIZE_MAX SIZE_T_MAX |
|
# else |
|
# ifdef INT_MAX |
|
# define SIZE_MAX INT_MAX |
|
# else |
|
# define SIZE_MAX 0x7fffffff |
|
# endif /* ULONG_MAX */ |
|
# endif /* SIZE_T_MAX */ |
|
#endif /* SIZE_MAX */ |
|
|
extern char **Argv; /* from sudo.c */ |
extern char **Argv; /* from sudo.c */ |
|
|
/* |
/* |
|
|
{ |
{ |
VOID *ptr; |
VOID *ptr; |
|
|
|
if (size == 0) { |
|
(void) fprintf(stderr, "%s: internal error, tried to emalloc(0)\n", |
|
Argv[0]); |
|
exit(1); |
|
} |
if ((ptr = (VOID *) malloc(size)) == NULL) { |
if ((ptr = (VOID *) malloc(size)) == NULL) { |
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); |
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); |
exit(1); |
exit(1); |
|
|
} |
} |
|
|
/* |
/* |
|
* emalloc2() allocates nmemb * size bytes and exits with an error |
|
* if overflow would occur or if the system malloc(3) fails. |
|
*/ |
|
VOID * |
|
emalloc2(nmemb, size) |
|
size_t nmemb; |
|
size_t size; |
|
{ |
|
VOID *ptr; |
|
|
|
if (nmemb == 0 || size == 0) { |
|
(void) fprintf(stderr, "%s: internal error, tried to emalloc2(0)\n", |
|
Argv[0]); |
|
exit(1); |
|
} |
|
if (nmemb > SIZE_MAX / size) { |
|
(void) fprintf(stderr, "%s: internal error, emalloc2() overflow\n", |
|
Argv[0]); |
|
exit(1); |
|
} |
|
size *= nmemb; |
|
if ((ptr = (VOID *) malloc(size)) == NULL) { |
|
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); |
|
exit(1); |
|
} |
|
return(ptr); |
|
} |
|
|
|
/* |
* erealloc() calls the system realloc(3) and exits with an error if |
* erealloc() calls the system realloc(3) and exits with an error if |
* realloc(3) fails. You can call erealloc() with a NULL pointer even |
* realloc(3) fails. You can call erealloc() with a NULL pointer even |
* if the system realloc(3) does not support this. |
* if the system realloc(3) does not support this. |
|
|
size_t size; |
size_t size; |
{ |
{ |
|
|
|
if (size == 0) { |
|
(void) fprintf(stderr, "%s: internal error, tried to erealloc(0)\n", |
|
Argv[0]); |
|
exit(1); |
|
} |
ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size); |
ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size); |
if (ptr == NULL) { |
if (ptr == NULL) { |
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); |
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); |
|
|
} |
} |
|
|
/* |
/* |
|
* erealloc3() realloc(3)s nmemb * size bytes and exits with an error |
|
* if overflow would occur or if the system malloc(3)/realloc(3) fails. |
|
* You can call erealloc() with a NULL pointer even if the system realloc(3) |
|
* does not support this. |
|
*/ |
|
VOID * |
|
erealloc3(ptr, nmemb, size) |
|
VOID *ptr; |
|
size_t nmemb; |
|
size_t size; |
|
{ |
|
|
|
if (nmemb == 0 || size == 0) { |
|
(void) fprintf(stderr, "%s: internal error, tried to erealloc3(0)\n", |
|
Argv[0]); |
|
exit(1); |
|
} |
|
if (nmemb > SIZE_MAX / size) { |
|
(void) fprintf(stderr, "%s: internal error, erealloc3() overflow\n", |
|
Argv[0]); |
|
exit(1); |
|
} |
|
size *= nmemb; |
|
ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size); |
|
if (ptr == NULL) { |
|
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]); |
|
exit(1); |
|
} |
|
return(ptr); |
|
} |
|
|
|
/* |
* estrdup() is like strdup(3) except that it exits with an error if |
* estrdup() is like strdup(3) except that it exits with an error if |
* malloc(3) fails. NOTE: unlike strdup(3), estrdup(NULL) is legal. |
* malloc(3) fails. NOTE: unlike strdup(3), estrdup(NULL) is legal. |
*/ |
*/ |
|
|
const char *src; |
const char *src; |
{ |
{ |
char *dst = NULL; |
char *dst = NULL; |
|
size_t size; |
|
|
if (src != NULL) { |
if (src != NULL) { |
dst = (char *) emalloc(strlen(src) + 1); |
size = strlen(src) + 1; |
(void) strcpy(dst, src); |
dst = (char *) emalloc(size); |
|
(void) memcpy(dst, src, size); |
} |
} |
return(dst); |
return(dst); |
} |
} |