diff --git a/lib/alloc.h b/lib/alloc.h index 9b1f8dc0..979588b4 100644 --- a/lib/alloc.h +++ b/lib/alloc.h @@ -1,13 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2023, Alejandro Colomar + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + #ifndef SHADOW_INCLUDE_LIB_MALLOC_H_ #define SHADOW_INCLUDE_LIB_MALLOC_H_ -#include +#include -/* xmalloc.c */ -extern /*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/void *xmalloc (size_t size) - /*@ensures MaxSet(result) == (size - 1); @*/; -extern /*@maynotreturn@*/ /*@only@*//*@notnull@*/char *xstrdup (const char *); +#include +#include +#include +#include +#include + +#include "defines.h" + + +ATTR_MALLOC(free) +inline void *xmalloc(size_t size); +ATTR_MALLOC(free) +inline void *xmallocarray(size_t nmemb, size_t size); +ATTR_MALLOC(free) +inline void *mallocarray(size_t nmemb, size_t size); +ATTR_MALLOC(free) +inline void *reallocarrayf(void *p, size_t nmemb, size_t size); +ATTR_MALLOC(free) +inline char *xstrdup(const char *str); + +ATTR_MALLOC(free) +void *xcalloc(size_t nmemb, size_t size); +ATTR_MALLOC(free) +void *xreallocarray(void *p, size_t nmemb, size_t size); + + +inline void * +xmalloc(size_t size) +{ + return xmallocarray(1, size); +} + + +inline void * +xmallocarray(size_t nmemb, size_t size) +{ + return xreallocarray(NULL, nmemb, size); +} + + +inline void * +mallocarray(size_t nmemb, size_t size) +{ + return reallocarray(NULL, nmemb, size); +} + + +inline void * +reallocarrayf(void *p, size_t nmemb, size_t size) +{ + void *q; + + q = reallocarray(p, nmemb, size); + + /* realloc(p, 0) is equivalent to free(p); avoid double free. */ + if (q == NULL && nmemb != 0 && size != 0) + free(p); + return q; +} + + +inline char * +xstrdup(const char *str) +{ + return strcpy(XMALLOCARRAY(strlen(str) + 1, char), str); +} #endif // include guard diff --git a/libmisc/alloc.c b/libmisc/alloc.c index 056d472f..962f45a1 100644 --- a/libmisc/alloc.c +++ b/libmisc/alloc.c @@ -3,6 +3,7 @@ * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz * SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko * SPDX-FileCopyrightText: 2008 , Nicolas François + * SPDX-FileCopyrightText: 2023 , Alejandro Colomar * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +12,7 @@ to be worth copyrighting :-). I did that because a lot of code used malloc and strdup without checking for NULL pointer, and I like some message better than a core dump... --marekm - + Yeh, but. Remember that bailing out might leave the system in some bizarre state. You really want to put in error checking, then add some back-out failure recovery code. -- jfh */ @@ -20,27 +21,53 @@ #ident "$Id$" -#include +#include "alloc.h" + #include +#include +#include + #include "defines.h" #include "prototypes.h" #include "shadowlog.h" -/*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/void *xmalloc (size_t size) -{ - void *ptr; - ptr = malloc (size); - if (NULL == ptr) { - (void) fprintf (log_get_logfd(), - _("%s: failed to allocate memory: %s\n"), - log_get_progname(), strerror (errno)); - exit (13); - } - return ptr; +extern inline void *xmalloc(size_t size); +extern inline void *xmallocarray(size_t nmemb, size_t size); +extern inline void *mallocarray(size_t nmemb, size_t size); +extern inline void *reallocarrayf(void *p, size_t nmemb, size_t size); +extern inline char *xstrdup(const char *str); + + +void * +xcalloc(size_t nmemb, size_t size) +{ + void *p; + + p = calloc(nmemb, size); + if (p == NULL) + goto x; + + return p; + +x: + fprintf(log_get_logfd(), _("%s: %s\n"), + log_get_progname(), strerror(errno)); + exit(13); } -/*@maynotreturn@*/ /*@only@*//*@notnull@*/char *xstrdup (const char *str) + +void * +xreallocarray(void *p, size_t nmemb, size_t size) { - return strcpy (xmalloc (strlen (str) + 1), str); + p = reallocarrayf(p, nmemb, size); + if (p == NULL) + goto x; + + return p; + +x: + fprintf(log_get_logfd(), _("%s: %s\n"), + log_get_progname(), strerror(errno)); + exit(13); }