chiark / gitweb /
[PATCH] fix klibc's broken strlcpy/strlcat
[elogind.git] / klibc / klibc / realloc.c
1 /*
2  * realloc.c
3  */
4
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "malloc.h"
9
10 /* FIXME: This is cheesy, it should be fixed later */
11
12 void *realloc(void *ptr, size_t size)
13 {
14   struct free_arena_header *ah;
15   void *newptr;
16   size_t oldsize;
17
18   if ( !ptr )
19     return malloc(size);
20
21   if ( size == 0 ) {
22     free(ptr);
23     return NULL;
24   }
25
26   /* Add the obligatory arena header, and round up */
27   size = (size+2*sizeof(struct arena_header)-1) & ARENA_SIZE_MASK;
28
29   ah = (struct free_arena_header *)
30     ((struct arena_header *)ptr - 1);
31
32   if ( ah->a.size >= size && size >= (ah->a.size >> 2) ) {
33     /* This field is a good size already. */
34     return ptr;
35   } else {
36     /* Make me a new block.  This is kind of bogus; we should
37        be checking the adjacent blocks to see if we can do an
38        in-place adjustment... fix that later. */
39     
40     oldsize = ah->a.size - sizeof(struct arena_header);
41
42     newptr = malloc(size);
43     memcpy(newptr, ptr, (size < oldsize) ? size : oldsize);
44     free(ptr);
45
46     return newptr;
47   }
48 }
49