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.
This commit is contained in:
Jim Warner 2011-11-16 10:49:02 -06:00 committed by Craig Small
parent f9ab2fec43
commit 7126cc4491
5 changed files with 60 additions and 19 deletions

View File

@ -5,19 +5,37 @@
// General Public License, version 2, or any later version. // General Public License, version 2, or any later version.
// See file COPYING for information on distribution conditions. // See file COPYING for information on distribution conditions.
#include <stdlib.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "alloc.h" #include "alloc.h"
void *xcalloc(void *pointer, int size) {
void * ret; static void xdefault_error(const char *restrict fmts, ...) __attribute__((format(printf,1,2)));
if (pointer) static void xdefault_error(const char *restrict fmts, ...) {
free(pointer); va_list va;
if (!(ret = calloc(1, size))) {
fprintf(stderr, "xcalloc: allocation error, size = %d\n", size); va_start(va, fmts);
exit(1); fprintf(stderr, fmts, va);
va_end(va);
} }
return ret;
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 p;
} }
void *xmalloc(unsigned int size) { void *xmalloc(unsigned int size) {
@ -27,9 +45,8 @@ void *xmalloc(unsigned int size) {
++size; ++size;
p = malloc(size); p = malloc(size);
if (!p) { if (!p) {
fprintf(stderr, "xmalloc: malloc(%d) failed", size); xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size);
perror(NULL); exit(EXIT_FAILURE);
exit(1);
} }
return(p); return(p);
} }
@ -41,9 +58,23 @@ void *xrealloc(void *oldp, unsigned int size) {
++size; ++size;
p = realloc(oldp, size); p = realloc(oldp, size);
if (!p) { if (!p) {
fprintf(stderr, "xrealloc: realloc(%d) failed", size); xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size);
perror(NULL); exit(EXIT_FAILURE);
exit(1); }
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); return(p);
} }

View File

@ -5,9 +5,13 @@
EXTERN_C_BEGIN 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 *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 EXTERN_C_END

View File

@ -71,6 +71,11 @@ global:
vm_pswpin; vm_pswpin;
vm_pswpout; vm_pswpout;
vminfo; vminfo;
xalloc_err_handler;
xcalloc;
xmalloc;
xrealloc;
xstrdup;
local: local:
*; *;
}; };

View File

@ -109,4 +109,7 @@
#define HIDDEN_ALIAS(x) extern __typeof(x) x##_direct __attribute__((alias(#x))) #define HIDDEN_ALIAS(x) extern __typeof(x) x##_direct __attribute__((alias(#x)))
#endif #endif
typedef void (*message_fn)(const char *restrict, ...) __attribute__((format(printf,1,2)));
#endif #endif

View File

@ -5,8 +5,6 @@
EXTERN_C_BEGIN 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 const char * lookup_wchan(unsigned KLONG address, unsigned pid);
extern int open_psdb(const char *restrict override); extern int open_psdb(const char *restrict override);
extern int open_psdb_message(const char *restrict override, message_fn message); extern int open_psdb_message(const char *restrict override, message_fn message);