]> xenbits.xensource.com Git - libvirt.git/commitdiff
Added safer lowlevel memory allocation APis. Converted hash.c and capabilities.c...
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 28 Apr 2008 21:44:54 +0000 (21:44 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 28 Apr 2008 21:44:54 +0000 (21:44 +0000)
ChangeLog
proxy/Makefile.am
src/Makefile.am
src/capabilities.c
src/hash.c
src/internal.h
src/memory.c [new file with mode: 0644]
src/memory.h [new file with mode: 0644]

index 9b1ba0eccba27903b3a8b0261c1fd877d71dd67e..0f3938f26396e4c7a64786fdebddf0c60fb93b9f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Mon Apr 28 17:24:22 EST 2008 Daniel P. Berrange <berrange@redhat.com>
+
+       * src/memory.h, src/memory.c: Added safer APIs for dealing
+       with low level memory allocation.
+       * src/hash.c, src/capabilities.c: Convert to new memory
+       allocation APIs
+       * src/internal.h: Define ATTRIBUTE_RETURN_CHECK and fix
+       type in virDebug no-op impl
+       * proxy/Makefile.am: Build and link against memory.c
+
 Mon Apr 28 10:24:22 EST 2008 Daniel P. Berrange <berrange@redhat.com>
 
        * src/buf.c, src/buf.h: Change API to move errors checks to
index 789a6429fab33e4c82e36e0620622f29ec87d696..2fe77c8209eae2b5cead95d46783b254ae49c95c 100644 (file)
@@ -14,6 +14,7 @@ libvirt_proxy_SOURCES = libvirt_proxy.c @top_srcdir@/src/xend_internal.c \
            @top_srcdir@/src/sexpr.c @top_srcdir@/src/xml.c \
             @top_srcdir@/src/xs_internal.c @top_srcdir@/src/buf.c \
             @top_srcdir@/src/capabilities.c \
+            @top_srcdir@/src/memory.c \
             @top_srcdir@/src/util.c \
            @top_srcdir@/src/uuid.c
 libvirt_proxy_LDFLAGS = $(WARN_CFLAGS)
index 7110420914697549cb06d006ab801158cbe3d134..2898a8e1987ec4f3e6f744a8f7add88c2778fd47 100644 (file)
@@ -33,6 +33,7 @@ CLIENT_SOURCES =                                              \
                libvirt.c internal.h                            \
                gnutls_1_0_compat.h                             \
                socketcompat.h                                  \
+                memory.c memory.h                              \
                hash.c hash.h                                   \
                test.c test.h                                   \
                 buf.c buf.h                                    \
index 8965c11cb53a045b3ee0fc1236cfc6788819f225..cf95751ea99e97a242347d73000cc79c065a708e 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "capabilities.h"
 #include "buf.h"
+#include "memory.h"
 
 
 /**
@@ -42,7 +43,7 @@ virCapabilitiesNew(const char *arch,
 {
     virCapsPtr caps;
 
-    if ((caps = calloc(1, sizeof(*caps))) == NULL)
+    if (VIR_ALLOC(caps) < 0)
         goto no_memory;
 
     if ((caps->host.arch = strdup(arch)) == NULL)
@@ -60,53 +61,53 @@ virCapabilitiesNew(const char *arch,
 static void
 virCapabilitiesFreeHostNUMACell(virCapsHostNUMACellPtr cell)
 {
-    free(cell->cpus);
-    free(cell);
+    VIR_FREE(cell->cpus);
+    VIR_FREE(cell);
 }
 
 static void
 virCapabilitiesFreeGuestDomain(virCapsGuestDomainPtr dom)
 {
     int i;
-    free(dom->info.emulator);
-    free(dom->info.loader);
+    VIR_FREE(dom->info.emulator);
+    VIR_FREE(dom->info.loader);
     for (i = 0 ; i < dom->info.nmachines ; i++)
-        free(dom->info.machines[i]);
-    free(dom->info.machines);
-    free(dom->type);
+        VIR_FREE(dom->info.machines[i]);
+    VIR_FREE(dom->info.machines);
+    VIR_FREE(dom->type);
 
-    free(dom);
+    VIR_FREE(dom);
 }
 
 static void
 virCapabilitiesFreeGuestFeature(virCapsGuestFeaturePtr feature)
 {
-    free(feature->name);
-    free(feature);
+    VIR_FREE(feature->name);
+    VIR_FREE(feature);
 }
 
 static void
 virCapabilitiesFreeGuest(virCapsGuestPtr guest)
 {
     int i;
-    free(guest->ostype);
+    VIR_FREE(guest->ostype);
 
-    free(guest->arch.name);
-    free(guest->arch.defaultInfo.emulator);
-    free(guest->arch.defaultInfo.loader);
+    VIR_FREE(guest->arch.name);
+    VIR_FREE(guest->arch.defaultInfo.emulator);
+    VIR_FREE(guest->arch.defaultInfo.loader);
     for (i = 0 ; i < guest->arch.defaultInfo.nmachines ; i++)
-        free(guest->arch.defaultInfo.machines[i]);
-    free(guest->arch.defaultInfo.machines);
+        VIR_FREE(guest->arch.defaultInfo.machines[i]);
+    VIR_FREE(guest->arch.defaultInfo.machines);
 
     for (i = 0 ; i < guest->arch.ndomains ; i++)
         virCapabilitiesFreeGuestDomain(guest->arch.domains[i]);
-    free(guest->arch.domains);
+    VIR_FREE(guest->arch.domains);
 
     for (i = 0 ; i < guest->nfeatures ; i++)
         virCapabilitiesFreeGuestFeature(guest->features[i]);
-    free(guest->features);
+    VIR_FREE(guest->features);
 
-    free(guest);
+    VIR_FREE(guest);
 }
 
 
@@ -122,21 +123,21 @@ virCapabilitiesFree(virCapsPtr caps) {
 
     for (i = 0 ; i < caps->nguests ; i++)
         virCapabilitiesFreeGuest(caps->guests[i]);
-    free(caps->guests);
+    VIR_FREE(caps->guests);
 
     for (i = 0 ; i < caps->host.nfeatures ; i++)
-        free(caps->host.features[i]);
-    free(caps->host.features);
+        VIR_FREE(caps->host.features[i]);
+    VIR_FREE(caps->host.features);
     for (i = 0 ; i < caps->host.nnumaCell ; i++)
         virCapabilitiesFreeHostNUMACell(caps->host.numaCell[i]);
-    free(caps->host.numaCell);
+    VIR_FREE(caps->host.numaCell);
 
     for (i = 0 ; i < caps->host.nmigrateTrans ; i++)
-        free(caps->host.migrateTrans[i]);
-    free(caps->host.migrateTrans);
+        VIR_FREE(caps->host.migrateTrans[i]);
+    VIR_FREE(caps->host.migrateTrans);
 
-    free(caps->host.arch);
-    free(caps);
+    VIR_FREE(caps->host.arch);
+    VIR_FREE(caps);
 }
 
 
@@ -151,12 +152,9 @@ int
 virCapabilitiesAddHostFeature(virCapsPtr caps,
                               const char *name)
 {
-    char **features;
-
-    if ((features = realloc(caps->host.features,
-                            sizeof(*features) * (caps->host.nfeatures+1))) == NULL)
+    if (VIR_REALLOC_N(caps->host.features,
+                      caps->host.nfeatures + 1) < 0)
         return -1;
-    caps->host.features = features;
 
     if ((caps->host.features[caps->host.nfeatures] = strdup(name)) == NULL)
         return -1;
@@ -177,12 +175,9 @@ int
 virCapabilitiesAddHostMigrateTransport(virCapsPtr caps,
                                        const char *name)
 {
-    char **migrateTrans;
-
-    if ((migrateTrans = realloc(caps->host.migrateTrans,
-                                sizeof(*migrateTrans) * (caps->host.nmigrateTrans+1))) == NULL)
+    if (VIR_REALLOC_N(caps->host.migrateTrans,
+                      caps->host.nmigrateTrans + 1) < 0)
         return -1;
-    caps->host.migrateTrans = migrateTrans;
 
     if ((caps->host.migrateTrans[caps->host.nmigrateTrans] = strdup(name)) == NULL)
         return -1;
@@ -208,19 +203,18 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
                                int ncpus,
                                const int *cpus)
 {
-    virCapsHostNUMACellPtr cell, *cells;
+    virCapsHostNUMACellPtr cell;
 
-    if ((cells = realloc(caps->host.numaCell,
-                         sizeof(*cells) * (caps->host.nnumaCell+1))) == NULL)
+    if (VIR_REALLOC_N(caps->host.numaCell,
+                      caps->host.nnumaCell + 1) < 0)
         return -1;
-    caps->host.numaCell = cells;
 
-    if ((cell = calloc(1, sizeof(cell))) == NULL)
+    if (VIR_ALLOC(cell) < 0)
         return -1;
     caps->host.numaCell[caps->host.nnumaCell] = cell;
 
-    if ((caps->host.numaCell[caps->host.nnumaCell]->cpus =
-         malloc(ncpus * sizeof(*cpus))) == NULL)
+    if (VIR_ALLOC_N(caps->host.numaCell[caps->host.nnumaCell]->cpus,
+                    ncpus) < 0)
         return -1;
     memcpy(caps->host.numaCell[caps->host.nnumaCell]->cpus,
            cpus,
@@ -259,10 +253,10 @@ virCapabilitiesAddGuest(virCapsPtr caps,
                         int nmachines,
                         const char *const *machines)
 {
-    virCapsGuestPtr guest, *guests;
+    virCapsGuestPtr guest;
     int i;
 
-    if ((guest = calloc(1, sizeof(*guest))) == NULL)
+    if (VIR_ALLOC(guest) < 0)
         goto no_memory;
 
     if ((guest->ostype = strdup(ostype)) == NULL)
@@ -279,8 +273,8 @@ virCapabilitiesAddGuest(virCapsPtr caps,
         (guest->arch.defaultInfo.loader = strdup(loader)) == NULL)
         goto no_memory;
     if (nmachines) {
-        if ((guest->arch.defaultInfo.machines =
-             calloc(nmachines, sizeof(*guest->arch.defaultInfo.machines))) == NULL)
+        if (VIR_ALLOC_N(guest->arch.defaultInfo.machines,
+                        nmachines) < 0)
             goto no_memory;
         for (i = 0 ; i < nmachines ; i++) {
             if ((guest->arch.defaultInfo.machines[i] = strdup(machines[i])) == NULL)
@@ -289,11 +283,9 @@ virCapabilitiesAddGuest(virCapsPtr caps,
         }
     }
 
-    if ((guests = realloc(caps->guests,
-                          sizeof(*guests) *
-                          (caps->nguests + 1))) == NULL)
+    if (VIR_REALLOC_N(caps->guests,
+                      caps->nguests + 1) < 0)
         goto no_memory;
-    caps->guests = guests;
     caps->guests[caps->nguests] = guest;
     caps->nguests++;
 
@@ -325,10 +317,10 @@ virCapabilitiesAddGuestDomain(virCapsGuestPtr guest,
                               int nmachines,
                               const char *const *machines)
 {
-    virCapsGuestDomainPtr dom, *doms;
+    virCapsGuestDomainPtr dom;
     int i;
 
-    if ((dom = calloc(1, sizeof(*dom))) == NULL)
+    if (VIR_ALLOC(dom) < 0)
         goto no_memory;
 
     if ((dom->type = strdup(hvtype)) == NULL)
@@ -341,8 +333,7 @@ virCapabilitiesAddGuestDomain(virCapsGuestPtr guest,
         (dom->info.loader = strdup(loader)) == NULL)
         goto no_memory;
     if (nmachines) {
-        if ((dom->info.machines =
-             calloc(nmachines, sizeof(*dom->info.machines))) == NULL)
+        if (VIR_ALLOC_N(dom->info.machines, nmachines) < 0)
             goto no_memory;
         for (i = 0 ; i < nmachines ; i++) {
             if ((dom->info.machines[i] = strdup(machines[i])) == NULL)
@@ -351,11 +342,9 @@ virCapabilitiesAddGuestDomain(virCapsGuestPtr guest,
         }
     }
 
-    if ((doms = realloc(guest->arch.domains,
-                        sizeof(*doms) *
-                        (guest->arch.ndomains + 1))) == NULL)
+    if (VIR_REALLOC_N(guest->arch.domains,
+                      guest->arch.ndomains + 1) < 0)
         goto no_memory;
-    guest->arch.domains = doms;
     guest->arch.domains[guest->arch.ndomains] = dom;
     guest->arch.ndomains++;
 
@@ -383,9 +372,9 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest,
                                int defaultOn,
                                int toggle)
 {
-    virCapsGuestFeaturePtr feature, *features;
+    virCapsGuestFeaturePtr feature;
 
-    if ((feature = calloc(1, sizeof(*feature))) == NULL)
+    if (VIR_ALLOC(feature) < 0)
         goto no_memory;
 
     if ((feature->name = strdup(name)) == NULL)
@@ -393,11 +382,9 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest,
     feature->defaultOn = defaultOn;
     feature->toggle = toggle;
 
-    if ((features = realloc(guest->features,
-                            sizeof(*features) *
-                            (guest->nfeatures + 1))) == NULL)
+    if (VIR_REALLOC_N(guest->features,
+                      guest->nfeatures + 1) < 0)
         goto no_memory;
-    guest->features = features;
     guest->features[guest->nfeatures] = feature;
     guest->nfeatures++;
 
index 2cb60b2a6100c772d9916a309a2cc7e4fd030879..4c11456f00fab76f9198e0db8199777acb431b09 100644 (file)
@@ -25,6 +25,7 @@
 #include <libxml/threads.h>
 #include "internal.h"
 #include "hash.h"
+#include "memory.h"
 
 #define MAX_HASH_LEN 8
 
@@ -85,22 +86,22 @@ virHashComputeKey(virHashTablePtr table, const char *name)
 virHashTablePtr
 virHashCreate(int size)
 {
-    virHashTablePtr table;
+    virHashTablePtr table = NULL;
 
     if (size <= 0)
         size = 256;
 
-    table = malloc(sizeof(*table));
-    if (table) {
-        table->size = size;
-        table->nbElems = 0;
-        table->table = calloc(1, size * sizeof(*(table->table)));
-        if (table->table) {
-            return (table);
-        }
-        free(table);
+    if (VIR_ALLOC(table) < 0)
+        return NULL;
+
+    table->size = size;
+    table->nbElems = 0;
+    if (VIR_ALLOC_N(table->table, size) < 0) {
+        VIR_FREE(table);
+        return NULL;
     }
-    return (NULL);
+
+    return table;
 }
 
 /**
@@ -136,8 +137,7 @@ virHashGrow(virHashTablePtr table, int size)
     if (oldtable == NULL)
         return (-1);
 
-    table->table = calloc(1, size * sizeof(*(table->table)));
-    if (table->table == NULL) {
+    if (VIR_ALLOC_N(table->table, size) < 0) {
         table->table = oldtable;
         return (-1);
     }
@@ -170,7 +170,7 @@ virHashGrow(virHashTablePtr table, int size)
             if (table->table[key].valid == 0) {
                 memcpy(&(table->table[key]), iter, sizeof(virHashEntry));
                 table->table[key].next = NULL;
-                free(iter);
+                VIR_FREE(iter);
             } else {
                 iter->next = table->table[key].next;
                 table->table[key].next = iter;
@@ -184,7 +184,7 @@ virHashGrow(virHashTablePtr table, int size)
         }
     }
 
-    free(oldtable);
+    VIR_FREE(oldtable);
 
 #ifdef DEBUG_GROW
     xmlGenericError(xmlGenericErrorContext,
@@ -225,19 +225,19 @@ virHashFree(virHashTablePtr table, virHashDeallocator f)
                 next = iter->next;
                 if ((f != NULL) && (iter->payload != NULL))
                     f(iter->payload, iter->name);
-                free(iter->name);
+                VIR_FREE(iter->name);
                 iter->payload = NULL;
                 if (!inside_table)
-                    free(iter);
+                    VIR_FREE(iter);
                 nbElems--;
                 inside_table = 0;
                 iter = next;
             }
             inside_table = 0;
         }
-        free(table->table);
+        VIR_FREE(table->table);
     }
-    free(table);
+    VIR_FREE(table);
 }
 
 /**
@@ -281,8 +281,7 @@ virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
     if (insert == NULL) {
         entry = &(table->table[key]);
     } else {
-        entry = malloc(sizeof(*entry));
-        if (entry == NULL)
+        if (VIR_ALLOC(entry) < 0)
             return (-1);
     }
 
@@ -354,8 +353,7 @@ virHashUpdateEntry(virHashTablePtr table, const char *name,
     if (insert == NULL) {
         entry = &(table->table[key]);
     } else {
-        entry = malloc(sizeof(*entry));
-        if (entry == NULL)
+        if (VIR_ALLOC(entry) < 0)
             return (-1);
     }
 
@@ -451,10 +449,10 @@ virHashRemoveEntry(virHashTablePtr table, const char *name,
                 if ((f != NULL) && (entry->payload != NULL))
                     f(entry->payload, entry->name);
                 entry->payload = NULL;
-                free(entry->name);
+                VIR_FREE(entry->name);
                 if (prev) {
                     prev->next = entry->next;
-                    free(entry);
+                    VIR_FREE(entry);
                 } else {
                     if (entry->next == NULL) {
                         entry->valid = 0;
@@ -462,7 +460,7 @@ virHashRemoveEntry(virHashTablePtr table, const char *name,
                         entry = entry->next;
                         memcpy(&(table->table[key]), entry,
                                sizeof(virHashEntry));
-                        free(entry);
+                        VIR_FREE(entry);
                     }
                 }
                 table->nbElems--;
@@ -535,11 +533,11 @@ int virHashRemoveSet(virHashTablePtr table, virHashSearcher iter, virHashDealloc
             if (iter(entry->payload, entry->name, data)) {
                 count++;
                 f(entry->payload, entry->name);
-                free(entry->name);
+                VIR_FREE(entry->name);
                 table->nbElems--;
                 if (prev) {
                     prev->next = entry->next;
-                    free(entry);
+                    VIR_FREE(entry);
                     entry = prev;
                 } else {
                     if (entry->next == NULL) {
@@ -549,7 +547,7 @@ int virHashRemoveSet(virHashTablePtr table, virHashSearcher iter, virHashDealloc
                         entry = entry->next;
                         memcpy(&(table->table[i]), entry,
                                sizeof(virHashEntry));
-                        free(entry);
+                        VIR_FREE(entry);
                         entry = &(table->table[i]);
                         continue;
                     }
@@ -689,8 +687,7 @@ virConnectPtr
 virGetConnect(void) {
     virConnectPtr ret;
 
-    ret = calloc(1, sizeof(*ret));
-    if (ret == NULL) {
+    if (VIR_ALLOC(ret) < 0) {
         virHashError(NULL, VIR_ERR_NO_MEMORY, _("allocating connection"));
         goto failed;
     }
@@ -729,7 +726,7 @@ failed:
             virHashFree(ret->storageVols, (virHashDeallocator) virStorageVolFreeName);
 
         pthread_mutex_destroy(&ret->lock);
-        free(ret);
+        VIR_FREE(ret);
     }
     return(NULL);
 }
@@ -759,11 +756,11 @@ virReleaseConnect(virConnectPtr conn) {
     if (__lastErr.conn == conn)
         __lastErr.conn = NULL;
 
-    free(conn->name);
+    VIR_FREE(conn->name);
 
     pthread_mutex_unlock(&conn->lock);
     pthread_mutex_destroy(&conn->lock);
-    free(conn);
+    VIR_FREE(conn);
 }
 
 /**
@@ -824,8 +821,8 @@ __virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid)
     ret = (virDomainPtr) virHashLookup(conn->domains, name);
     /* TODO check the UUID */
     if (ret == NULL) {
-        ret = (virDomainPtr) calloc(1, sizeof(*ret));
-        if (ret == NULL) {
+        VIR_ALLOC(ret);
+        if (0) {
             virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating domain"));
             goto error;
         }
@@ -854,8 +851,8 @@ __virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid)
  error:
     pthread_mutex_unlock(&conn->lock);
     if (ret != NULL) {
-        free(ret->name );
-        free(ret);
+        VIR_FREE(ret->name);
+        VIR_FREE(ret);
     }
     return(NULL);
 }
@@ -888,8 +885,8 @@ virReleaseDomain(virDomainPtr domain) {
         __lastErr.dom = NULL;
     domain->magic = -1;
     domain->id = -1;
-    free(domain->name);
-    free(domain);
+    VIR_FREE(domain->name);
+    VIR_FREE(domain);
 
     DEBUG("unref connection %p %s %d", conn, conn->name, conn->refs);
     conn->refs--;
@@ -962,8 +959,7 @@ __virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid)
     ret = (virNetworkPtr) virHashLookup(conn->networks, name);
     /* TODO check the UUID */
     if (ret == NULL) {
-        ret = (virNetworkPtr) calloc(1, sizeof(*ret));
-        if (ret == NULL) {
+        if (VIR_ALLOC(ret) < 0) {
             virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating network"));
             goto error;
         }
@@ -991,8 +987,8 @@ __virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid)
  error:
     pthread_mutex_unlock(&conn->lock);
     if (ret != NULL) {
-        free(ret->name );
-        free(ret);
+        VIR_FREE(ret->name);
+        VIR_FREE(ret);
     }
     return(NULL);
 }
@@ -1025,8 +1021,8 @@ virReleaseNetwork(virNetworkPtr network) {
         __lastErr.net = NULL;
 
     network->magic = -1;
-    free(network->name);
-    free(network);
+    VIR_FREE(network->name);
+    VIR_FREE(network);
 
     DEBUG("unref connection %p %s %d", conn, conn->name, conn->refs);
     conn->refs--;
@@ -1100,8 +1096,7 @@ __virGetStoragePool(virConnectPtr conn, const char *name, const unsigned char *u
     ret = (virStoragePoolPtr) virHashLookup(conn->storagePools, name);
     /* TODO check the UUID */
     if (ret == NULL) {
-        ret = (virStoragePoolPtr) calloc(1, sizeof(*ret));
-        if (ret == NULL) {
+        if (VIR_ALLOC(ret) < 0) {
             virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating storage pool"));
             goto error;
         }
@@ -1129,8 +1124,8 @@ __virGetStoragePool(virConnectPtr conn, const char *name, const unsigned char *u
 error:
     pthread_mutex_unlock(&conn->lock);
     if (ret != NULL) {
-        free(ret->name);
-        free(ret);
+        VIR_FREE(ret->name);
+        VIR_FREE(ret);
     }
     return(NULL);
 }
@@ -1159,8 +1154,8 @@ virReleaseStoragePool(virStoragePoolPtr pool) {
                      _("pool missing from connection hash table"));
 
     pool->magic = -1;
-    free(pool->name);
-    free(pool);
+    VIR_FREE(pool->name);
+    VIR_FREE(pool);
 
     DEBUG("unref connection %p %s %d", conn, conn->name, conn->refs);
     conn->refs--;
@@ -1232,8 +1227,7 @@ __virGetStorageVol(virConnectPtr conn, const char *pool, const char *name, const
 
     ret = (virStorageVolPtr) virHashLookup(conn->storageVols, key);
     if (ret == NULL) {
-        ret = (virStorageVolPtr) calloc(1, sizeof(*ret));
-        if (ret == NULL) {
+        if (VIR_ALLOC(ret) < 0) {
             virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating storage vol"));
             goto error;
         }
@@ -1266,9 +1260,9 @@ __virGetStorageVol(virConnectPtr conn, const char *pool, const char *name, const
 error:
     pthread_mutex_unlock(&conn->lock);
     if (ret != NULL) {
-        free(ret->name);
-        free(ret->pool);
-        free(ret);
+        VIR_FREE(ret->name);
+        VIR_FREE(ret->pool);
+        VIR_FREE(ret);
     }
     return(NULL);
 }
@@ -1297,9 +1291,9 @@ virReleaseStorageVol(virStorageVolPtr vol) {
                      _("vol missing from connection hash table"));
 
     vol->magic = -1;
-    free(vol->name);
-    free(vol->pool);
-    free(vol);
+    VIR_FREE(vol->name);
+    VIR_FREE(vol->pool);
+    VIR_FREE(vol);
 
     DEBUG("unref connection %p %s %d", conn, conn->name, conn->refs);
     conn->refs--;
index 02cd3584a1e62472d114ba8747adbe54a79bc3a6..7df866154e8ebba2e05d51aaeac88e7c882b444f 100644 (file)
@@ -78,7 +78,7 @@ extern int debugFlag;
 #define VIR_DEBUG(category, fmt,...)                                    \
     do { if (debugFlag) fprintf (stderr, "DEBUG: %s: %s (" fmt ")\n", category, __func__, __VA_ARGS__); } while (0)
 #else
-#define VIR_DEBUG(category, fmt,...)
+#define VIR_DEBUG(category, fmt,...) \
     do { } while (0)
 #endif /* !ENABLE_DEBUG */
 
@@ -88,6 +88,11 @@ extern int debugFlag;
 #endif
 
 #ifdef __GNUC__
+
+#ifndef __GNUC_PREREQ
+#define __GNUC_PREREQ(maj,min) 0
+#endif
+
 /**
  * ATTRIBUTE_UNUSED:
  *
@@ -107,9 +112,18 @@ extern int debugFlag;
 #define ATTRIBUTE_FORMAT(args...) __attribute__((__format__ (args)))
 #endif
 
+#ifndef ATTRIBUTE_RETURN_CHECK
+#if __GNUC_PREREQ (3, 4)
+#define ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__))
+#else
+#define ATTRIBUTE_RETURN_CHECK
+#endif
+#endif
+
 #else
 #define ATTRIBUTE_UNUSED
 #define ATTRIBUTE_FORMAT(...)
+#define ATTRIBUTE_RETURN_CHECK
 #endif                         /* __GNUC__ */
 
 /**
diff --git a/src/memory.c b/src/memory.c
new file mode 100644 (file)
index 0000000..fe41e38
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * memory.c: safer memory allocation
+ *
+ * Copyright (C) 2008 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <stdlib.h>
+
+#include "memory.h"
+
+
+/* Return 1 if an array of N objects, each of size S, cannot exist due
+   to size arithmetic overflow.  S must be positive and N must be
+   nonnegative.  This is a macro, not an inline function, so that it
+   works correctly even when SIZE_MAX < N.
+
+   By gnulib convention, SIZE_MAX represents overflow in size
+   calculations, so the conservative dividend to use here is
+   SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
+   However, malloc (SIZE_MAX) fails on all known hosts where
+   sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
+   exactly-SIZE_MAX allocations on such hosts; this avoids a test and
+   branch when S is known to be 1.  */
+# define xalloc_oversized(n, s) \
+    ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
+
+
+/**
+ * virAlloc:
+ * @ptrptr: pointer to pointer for address of allocated memory
+ * @size: number of bytes to allocate
+ *
+ * Allocate  'size' bytes of memory. Return the address of the
+ * allocated memory in 'ptrptr'. The newly allocated memory is
+ * filled with zeros.
+ *
+ * Returns -1 on failure to allocate, zero on success
+ */
+int virAlloc(void *ptrptr, size_t size)
+{
+    if (size == 0) {
+        *(void **)ptrptr = NULL;
+        return 0;
+    }
+
+
+
+    *(void **)ptrptr = calloc(1, size);
+    if (*(void **)ptrptr == NULL)
+        return -1;
+    return 0;
+}
+
+/**
+ * virAllocN:
+ * @ptrptr: pointer to pointer for address of allocated memory
+ * @size: number of bytes to allocate
+ * @count: number of elements to allocate
+ *
+ * Allocate an array of memory 'count' elements long, 
+ * each with 'size' bytes. Return the address of the
+ * allocated memory in 'ptrptr'.  The newly allocated
+ * memory is filled with zeros.
+ *
+ * Returns -1 on failure to allocate, zero on success
+ */
+int virAllocN(void *ptrptr, size_t size, size_t count)
+{
+    if (size == 0 || count == 0) {
+        *(void **)ptrptr = NULL;
+        return 0;
+    }
+
+    *(void**)ptrptr = calloc(count, size);
+    if (*(void**)ptrptr == NULL)
+        return -1;
+    return 0;
+}
+
+/**
+ * virReallocN:
+ * @ptrptr: pointer to pointer for address of allocated memory
+ * @size: number of bytes to allocate
+ * @count: number of elements in array
+ *
+ * Resize the block of memory in 'ptrptr' to be an array of
+ * 'count' elements, each 'size' bytes in length. Update 'ptrptr'
+ * with the address of the newly allocated memory. On failure,
+ * 'ptrptr' is not changed and still points to the original memory 
+ * block. The newly allocated memory is filled with zeros.
+ *
+ * Returns -1 on failure to allocate, zero on success
+ */
+int virReallocN(void *ptrptr, size_t size, size_t count)
+{
+    void *tmp;
+    if (size == 0 || count == 0) {
+        free(*(void **)ptrptr);
+        *(void **)ptrptr = NULL;
+        return 0;
+    }
+    if (xalloc_oversized(count, size)) {
+        errno = ENOMEM;
+        return -1;
+    }
+    tmp = realloc(*(void**)ptrptr, size * count);
+    if (!tmp)
+        return -1;
+    *(void**)ptrptr = tmp;
+    return 0;
+}
+
+/**
+ * virFree:
+ * @ptrptr: pointer to pointer for address of memory to be freed
+ *
+ * Release the chunk of memory in the pointer pointed to by
+ * the 'ptrptr' variable. After release, 'ptrptr' will be
+ * updated to point to NULL.
+ */
+void virFree(void *ptrptr)
+{
+    free(*(void**)ptrptr);
+    *(void**)ptrptr = NULL;
+}
diff --git a/src/memory.h b/src/memory.h
new file mode 100644 (file)
index 0000000..872fd8c
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * memory.c: safer memory allocation
+ *
+ * Copyright (C) 2008 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+
+#ifndef __VIR_MEMORY_H_
+#define __VIR_MEMORY_H_
+
+#include "internal.h"
+
+/* Don't call these directly - use the macros below */
+int virAlloc(void *ptrptr, size_t size) ATTRIBUTE_RETURN_CHECK;
+int virAllocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK;
+int virReallocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK;
+void virFree(void *ptrptr);
+
+
+/**
+ * VIR_ALLOC:
+ * @ptr: pointer to hold address of allocated memory
+ *
+ * Allocate sizeof(*ptr) bytes of memory and store
+ * the address of allocated memory in 'ptr'. Fill the
+ * newly allocated memory with zeros.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+#define VIR_ALLOC(ptr) virAlloc(&(ptr), sizeof(*(ptr)))
+
+/**
+ * VIR_ALLOC_N:
+ * @ptr: pointer to hold address of allocated memory
+ * @count: number of elements to allocate
+ *
+ * Allocate an array of 'count' elements, each sizeof(*ptr)
+ * bytes long and store the address of allocated memory in
+ * 'ptr'. Fill the newly allocated memory with zeros.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+#define VIR_ALLOC_N(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count))
+
+/**
+ * VIR_REALLOC_N:
+ * @ptr: pointer to hold address of allocated memory
+ * @count: number of elements to allocate
+ *
+ * Re-allocate an array of 'count' elements, each sizeof(*ptr)
+ * bytes long and store the address of allocated memory in
+ * 'ptr'. Fill the newly allocated memory with zeros
+ *
+ * Returns -1 on failure, 0 on success
+ */
+#define VIR_REALLOC_N(ptr, count) virReallocN(&(ptr), sizeof(*(ptr)), (count))
+
+/**
+ * VIR_FREE:
+ * @ptr: pointer holding address to be freed
+ *
+ * Free the memory stored in 'ptr' and update to point
+ * to NULL.
+ */
+#define VIR_FREE(ptr) virFree(&(ptr));
+
+#endif /* __VIR_MEMORY_H_ */