]> granicus.if.org Git - procps-ng/commitdiff
library: expanded/generalized memory allocation provisions
authorJim Warner <james.warner@comcast.net>
Wed, 16 Nov 2011 16:49:02 +0000 (10:49 -0600)
committerCraig Small <csmall@enc.com.au>
Sun, 11 Dec 2011 11:26:49 +0000 (22:26 +1100)
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
proc/alloc.h
proc/library.map
proc/procps.h
proc/wchan.h

index 4a0aca75e58bc0ee949caa7930847f75f98399b5..0bc71a5224c056487e60c96cfcb9b713018eee17 100644 (file)
@@ -5,19 +5,37 @@
 // General Public License, version 2, or any later version.
 // See file COPYING for information on distribution conditions.
 
-#include <stdlib.h>
+#include <stdarg.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 #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);
 }
index 8c5016de43a8ced20e0b5cd70edbe55e90fe7bfd..82b53592a785e95136ded39bff9b9f8f5b77853d 100644 (file)
@@ -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
 
index f5b96c8321d33416938487b9da40ec3471334577..cde6aa94df149f7051cf84cd17506b0d3dc29b61 100644 (file)
@@ -71,6 +71,11 @@ global:
        vm_pswpin;
        vm_pswpout;
        vminfo;
+       xalloc_err_handler;
+       xcalloc;
+       xmalloc;
+       xrealloc;
+       xstrdup;
 local:
        *;
 };
index 42d02b45016d1f0417900f1d48f5d6118c6ddc10..4c6866e3369e924083ddeeab3f8ab06adf64015a 100644 (file)
 #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
index 93d4e708215463a7c12df9b0ce7a61a7b53b8d6d..aa50fc5f529f33d9fe3a4f000f52464125e04df2 100644 (file)
@@ -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);