summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorFlorian Pritz <bluewind@xinu.at>2014-01-27 23:38:49 +0100
committerAllan McRae <allan@archlinux.org>2014-03-03 02:25:54 +0100
commit42f4a5081e06793be6c807d50cd7ec0a83bbcdf1 (patch)
treea07e733cdf17121263ff838f7b38e018f4d4afdd /lib
parentf27fad9b890d2696201e1df2356dd4d66f813ddd (diff)
downloadpacman-42f4a5081e06793be6c807d50cd7ec0a83bbcdf1.tar.gz
pacman-42f4a5081e06793be6c807d50cd7ec0a83bbcdf1.tar.xz
util: Add _alpm_realloc() and _alpm_greedy_grow()
These will be used in the following patches. Signed-off-by: Florian Pritz <bluewind@xinu.at>
Diffstat (limited to 'lib')
-rw-r--r--lib/libalpm/util.c62
-rw-r--r--lib/libalpm/util.h2
2 files changed, 64 insertions, 0 deletions
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 150b85ea..1bc208c6 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -1287,6 +1287,68 @@ int _alpm_fnmatch(const void *pattern, const void *string)
return fnmatch(pattern, string, 0);
}
+/** Think of this as realloc with error handling. If realloc fails NULL will be
+ * returned and data will not be changed.
+ *
+ * Newly created memory will be zeroed.
+ *
+ * @param data source memory space
+ * @param current size of the space pointed to by data
+ * @param required size you want
+ * @return new memory; NULL on error
+ */
+void *_alpm_realloc(void **data, size_t *current, const size_t required)
+{
+ char *newdata;
+
+ newdata = realloc(*data, required);
+ if(!newdata) {
+ _alpm_alloc_fail(required);
+ return NULL;
+ }
+
+ if (*current < required) {
+ /* ensure all new memory is zeroed out, in both the initial
+ * allocation and later reallocs */
+ memset(newdata + *current, 0, required - *current);
+ }
+ *current = required;
+ *data = newdata;
+ return newdata;
+}
+
+/** This automatically grows data based on current/required.
+ *
+ * The memory space will be initialised to required bytes and doubled in size when required.
+ *
+ * Newly created memory will be zeroed.
+ * @param data source memory space
+ * @param current size of the space pointed to by data
+ * @param required size you want
+ * @return new memory if grown; old memory otherwise; NULL on error
+ */
+void *_alpm_greedy_grow(void **data, size_t *current, const size_t required)
+{
+ size_t newsize = 0;
+
+ if(*current >= required) {
+ return data;
+ }
+
+ if(*current == 0) {
+ newsize = required;
+ } else {
+ newsize = *current * 2;
+ }
+
+ /* check for overflows */
+ if (newsize < required) {
+ return NULL;
+ }
+
+ return _alpm_realloc(data, current, required);
+}
+
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 250c5300..20f63f64 100644
--- a/lib/libalpm/util.h
+++ b/lib/libalpm/util.h
@@ -141,6 +141,8 @@ 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);
+void *_alpm_greedy_grow(void **data, size_t *current, const size_t required);
#ifndef HAVE_STRSEP
char *strsep(char **, const char *);