chiark / gitweb /
volume_id: provide libvolume_id.a file
[elogind.git] / klibc / klibc / sbrk.c
1 /* sbrk.c - Change data segment size */
2
3 /* Written 2000 by Werner Almesberger */
4 /* Modified 2003-2004 for klibc by H. Peter Anvin */
5
6 #include <stddef.h>
7 #include <unistd.h>
8 #include <inttypes.h>
9 #include <errno.h>
10 #include "malloc.h"
11
12 char *__current_brk;            /* Common with brk.c */
13
14 /* p is an address,  a is alignment; must be a power of 2 */
15 static inline void *align_up(void *p, uintptr_t a)
16 {
17   return (void *) (((uintptr_t)p + a-1) & ~(a-1));
18 }
19
20 void *sbrk(ptrdiff_t increment)
21 {
22   char *start, *end, *new_brk;
23   
24   if (!__current_brk)
25     __current_brk = __brk(NULL);
26
27   start = align_up(__current_brk, SBRK_ALIGNMENT);
28   end   = start + increment;
29
30   new_brk = __brk(end);
31
32   if (new_brk == (void *)-1)
33     return (void *)-1;
34   else if (new_brk < end) {
35     errno = ENOMEM;
36     return (void *) -1;
37   }
38
39   __current_brk = new_brk;
40   return start;
41 }