diff options
author | Florian Pritz <bluewind@xinu.at> | 2014-01-27 23:38:49 +0100 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2014-03-03 02:25:54 +0100 |
commit | 42f4a5081e06793be6c807d50cd7ec0a83bbcdf1 (patch) | |
tree | a07e733cdf17121263ff838f7b38e018f4d4afdd | |
parent | f27fad9b890d2696201e1df2356dd4d66f813ddd (diff) | |
download | pacman-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>
-rw-r--r-- | lib/libalpm/util.c | 62 | ||||
-rw-r--r-- | lib/libalpm/util.h | 2 |
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 *); |