From 7126cc4491847ce5d50e603fe48666f94bfc60bf Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Wed, 16 Nov 2011 10:49:02 -0600 Subject: [PATCH] library: expanded/generalized memory allocation provisions A callback provision in the form of xalloc_err_handler (of type message_fn) was added to the alloc module. This change allowed a program like top, who alters the termios structure, to override the default fprint(stderr...) behavior in the event of an error. The new function xstrdup was also added for symmetry. --- proc/alloc.c | 61 ++++++++++++++++++++++++++++++++++++------------ proc/alloc.h | 8 +++++-- proc/library.map | 5 ++++ proc/procps.h | 3 +++ proc/wchan.h | 2 -- 5 files changed, 60 insertions(+), 19 deletions(-) diff --git a/proc/alloc.c b/proc/alloc.c index 4a0aca75..0bc71a52 100644 --- a/proc/alloc.c +++ b/proc/alloc.c @@ -5,19 +5,37 @@ // General Public License, version 2, or any later version. // See file COPYING for information on distribution conditions. -#include +#include #include +#include +#include + #include "alloc.h" -void *xcalloc(void *pointer, int size) { - void * ret; - if (pointer) - free(pointer); - if (!(ret = calloc(1, size))) { - fprintf(stderr, "xcalloc: allocation error, size = %d\n", size); - exit(1); + +static void xdefault_error(const char *restrict fmts, ...) __attribute__((format(printf,1,2))); +static void xdefault_error(const char *restrict fmts, ...) { + va_list va; + + va_start(va, fmts); + fprintf(stderr, fmts, va); + va_end(va); +} + +message_fn xalloc_err_handler = xdefault_error; + + +void *xcalloc(unsigned int size) { + void * p; + + if (size == 0) + ++size; + p = calloc(1, size); + if (!p) { + xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); + exit(EXIT_FAILURE); } - return ret; + return p; } void *xmalloc(unsigned int size) { @@ -27,9 +45,8 @@ void *xmalloc(unsigned int size) { ++size; p = malloc(size); if (!p) { - fprintf(stderr, "xmalloc: malloc(%d) failed", size); - perror(NULL); - exit(1); + xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); + exit(EXIT_FAILURE); } return(p); } @@ -41,9 +58,23 @@ void *xrealloc(void *oldp, unsigned int size) { ++size; p = realloc(oldp, size); if (!p) { - fprintf(stderr, "xrealloc: realloc(%d) failed", size); - perror(NULL); - exit(1); + xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); + exit(EXIT_FAILURE); + } + return(p); +} + +char *xstrdup(const char *str) { + char *p = NULL; + + if (str) { + unsigned int size = strlen(str) + 1; + p = malloc(size); + if (!p) { + xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); + exit(EXIT_FAILURE); + } + strcpy(p, str); } return(p); } diff --git a/proc/alloc.h b/proc/alloc.h index 8c5016de..82b53592 100644 --- a/proc/alloc.h +++ b/proc/alloc.h @@ -5,9 +5,13 @@ EXTERN_C_BEGIN -extern void *xrealloc(void *oldp, unsigned int size) MALLOC; + /* change xalloc_err_handler to override the default fprintf(stderr... */ +extern message_fn xalloc_err_handler; + +extern void *xcalloc(unsigned int size) MALLOC; extern void *xmalloc(unsigned int size) MALLOC; -extern void *xcalloc(void *pointer, int size) MALLOC; +extern void *xrealloc(void *oldp, unsigned int size) MALLOC; +extern char *xstrdup(const char *str) MALLOC; EXTERN_C_END diff --git a/proc/library.map b/proc/library.map index f5b96c83..cde6aa94 100644 --- a/proc/library.map +++ b/proc/library.map @@ -71,6 +71,11 @@ global: vm_pswpin; vm_pswpout; vminfo; + xalloc_err_handler; + xcalloc; + xmalloc; + xrealloc; + xstrdup; local: *; }; diff --git a/proc/procps.h b/proc/procps.h index 42d02b45..4c6866e3 100644 --- a/proc/procps.h +++ b/proc/procps.h @@ -109,4 +109,7 @@ #define HIDDEN_ALIAS(x) extern __typeof(x) x##_direct __attribute__((alias(#x))) #endif + +typedef void (*message_fn)(const char *restrict, ...) __attribute__((format(printf,1,2))); + #endif diff --git a/proc/wchan.h b/proc/wchan.h index 93d4e708..aa50fc5f 100644 --- a/proc/wchan.h +++ b/proc/wchan.h @@ -5,8 +5,6 @@ EXTERN_C_BEGIN -typedef void (*message_fn)(const char *restrict, ...) __attribute__((format(printf,1,2))); - extern const char * lookup_wchan(unsigned KLONG address, unsigned pid); extern int open_psdb(const char *restrict override); extern int open_psdb_message(const char *restrict override, message_fn message);