chiark / gitweb /
[PATCH] gentoo rule update for raid devices.
[elogind.git] / klibc / klibc / sbrk.c
index 03ab3c14bba0824f927d0651dd4e32ff054eb5b3..cb0efb21b9d82e8aa171863a8aca189808b7b59b 100644 (file)
@@ -1,23 +1,41 @@
 /* sbrk.c - Change data segment size */
 
 /* Written 2000 by Werner Almesberger */
+/* Modified 2003-2004 for klibc by H. Peter Anvin */
 
 #include <stddef.h>
 #include <unistd.h>
-#include <sys/types.h>
+#include <inttypes.h>
+#include <errno.h>
+#include "malloc.h"
 
 char *__current_brk;           /* Common with brk.c */
 
+/* p is an address,  a is alignment; must be a power of 2 */
+static inline void *align_up(void *p, uintptr_t a)
+{
+  return (void *) (((uintptr_t)p + a-1) & ~(a-1));
+}
+
 void *sbrk(ptrdiff_t increment)
 {
-  char *old_brk, *new_brk;
+  char *start, *end, *new_brk;
   
   if (!__current_brk)
     __current_brk = __brk(NULL);
-  new_brk = __brk(__current_brk+increment);
-  if (new_brk != __current_brk+increment)
+
+  start = align_up(__current_brk, SBRK_ALIGNMENT);
+  end   = start + increment;
+
+  new_brk = __brk(end);
+
+  if (new_brk == (void *)-1)
+    return (void *)-1;
+  else if (new_brk < end) {
+    errno = ENOMEM;
     return (void *) -1;
-  old_brk = __current_brk;
+  }
+
   __current_brk = new_brk;
-  return old_brk;
+  return start;
 }