[pacman-dev] [PATCH v3 2/5] util: Add _alpm_realloc()

Florian Pritz bluewind at xinu.at
Thu Jan 30 11:24:22 EST 2014


Signed-off-by: Florian Pritz <bluewind at xinu.at>
---

v3: Implement suggestions from Andrew

RFC from v2 still holds: is using char for *newdata fine
or is there any good reason to use uint8_t like systemd does?

 lib/libalpm/util.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 lib/libalpm/util.h |  1 +
 2 files changed, 50 insertions(+)

diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 150b85e..28b8646 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -1287,6 +1287,55 @@ int _alpm_fnmatch(const void *pattern, const void *string)
 	return fnmatch(pattern, string, 0);
 }
 
+/**
+ * Think of this as realloc with error handling and
+ * automatic growing based on current/required.
+ *
+ * data will point to a memory space with at least required
+ * bytes, likely more. You may want to free unused memory.
+ * If required < current data is returned and nothing happens.
+ *
+ * @param data source memory space
+ * @param current size of the space pointed to be data
+ * @param required size you want
+ * @return new memory if grown; old memory otherwise; NULL on error
+ */
+void *_alpm_realloc(void **data, size_t *current, const size_t required)
+{
+	char *newdata;
+	size_t newsize = 0;
+
+	if(*current >= required) {
+		return data;
+	}
+
+	if(*current == 0) {
+		newsize = ALPM_BUFFER_SIZE;
+	} else if (required > (*current) * 2) {
+		newsize = required * 2;
+	} else {
+		newsize = *current * 2;
+	}
+
+	/* check for overflows */
+	if (newsize < required) {
+		return NULL;
+	}
+
+	newdata = realloc(*data, newsize);
+	if(!newdata) {
+		_alpm_alloc_fail(newsize);
+		return NULL;
+	}
+
+	/* ensure all new memory is zeroed out, in both the initial
+	 * allocation and later reallocs */
+	memset(newdata + *current, 0, newsize - *current);
+	*current = newsize;
+	*data = newdata;
+	return newdata;
+}
+
 void _alpm_alloc_fail(size_t size)
 {
 	fprintf(stderr, "alloc failure: could not allocate %zd bytes\n", size);
diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h
index 250c530..f348540 100644
--- a/lib/libalpm/util.h
+++ b/lib/libalpm/util.h
@@ -141,6 +141,7 @@ int _alpm_raw_ncmp(const char *first, const char *second, size_t max);
 int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode);
 int _alpm_fnmatch_patterns(alpm_list_t *patterns, const char *string);
 int _alpm_fnmatch(const void *pattern, const void *string);
+void *_alpm_realloc(void **data, size_t *current, const size_t required);
 
 #ifndef HAVE_STRSEP
 char *strsep(char **, const char *);
-- 
1.8.5.3


More information about the pacman-dev mailing list