b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering/***
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering This file is part of systemd.
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering Copyright 2010 Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering systemd is free software; you can redistribute it and/or modify it
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering under the terms of the GNU Lesser General Public License as published by
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering (at your option) any later version.
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering systemd is distributed in the hope that it will be useful, but
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering Lesser General Public License for more details.
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering You should have received a copy of the GNU Lesser General Public License
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering***/
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <stdint.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <string.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include "macro.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "util.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poetteringvoid* memdup(const void *p, size_t l) {
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering void *r;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering assert(p);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering r = malloc(l);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering if (!r)
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering return NULL;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering memcpy(r, p, l);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering return r;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering}
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poetteringvoid* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering size_t a, newalloc;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering void *q;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering assert(p);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering assert(allocated);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering if (*allocated >= need)
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering return *p;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering newalloc = MAX(need * 2, 64u / size);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering a = newalloc * size;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering /* check for overflows */
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering if (a < size * need)
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering return NULL;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering q = realloc(*p, a);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering if (!q)
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering return NULL;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering *p = q;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering *allocated = newalloc;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering return q;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering}
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poetteringvoid* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering size_t prev;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering uint8_t *q;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering assert(p);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering assert(allocated);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering prev = *allocated;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering q = greedy_realloc(p, allocated, need, size);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering if (!q)
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering return NULL;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering if (*allocated > prev)
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering memzero(q + prev * size, (*allocated - prev) * size);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering return q;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering}