OSDN Git Service

Fix errno values. Fix MALLOC_GLIBC_COMPAT handling in malloc/malloc.c,
authorEric Andersen <andersen@codepoet.org>
Sat, 6 Sep 2003 11:49:28 +0000 (11:49 -0000)
committerEric Andersen <andersen@codepoet.org>
Sat, 6 Sep 2003 11:49:28 +0000 (11:49 -0000)
which was reversed.  Provide more consistancy between implementations.
Handle it when people do stupid things like malloc(-1);

libc/stdlib/malloc-930716/malloc.c
libc/stdlib/malloc-930716/realloc.c
libc/stdlib/malloc/malloc.c
libc/stdlib/malloc/realloc.c

index dce32b9..3e69f11 100644 (file)
@@ -15,6 +15,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 #include "malloc.h"
 
 #ifdef __UCLIBC_HAS_THREADS__
@@ -161,19 +162,22 @@ void * __malloc_unlocked (size_t size)
     struct list *next;
 
 #if defined(__MALLOC_GLIBC_COMPAT__)
-    if (size == 0)
+    if (unlikely(size == 0))
        size++;
 #else
     /* Some programs will call malloc (0).  Lets be strict and return NULL */
-    if (size == 0)
-       return NULL;
+    if (unlikely(size == 0))
+       goto oom;
 #endif
+    /* Check if they are doing something dumb like malloc(-1) */
+    if (unlikely(((unsigned long)size > (unsigned long)(sizeof (struct list)*-2))))
+       goto oom;
 
-    if (size < sizeof (struct list))
+    if (unlikely(size < sizeof (struct list)))
        size = sizeof (struct list);
 
     if (!initialized && !initialize()) {
-       return NULL;
+       goto oom;
     }
 
     /* Determine the allocation policy based on the request size. */
@@ -204,7 +208,7 @@ void * __malloc_unlocked (size_t size)
               and break it into fragments, returning the first. */
            result = __malloc_unlocked(BLOCKSIZE);
            if (!result) {
-               return NULL;
+               goto oom;
            }
            ++_fragblocks[log];
 
@@ -255,7 +259,7 @@ void * __malloc_unlocked (size_t size)
                }
                result = morecore(blocks * BLOCKSIZE);
                if (!result) {
-                   return NULL;
+                   goto oom;
                }
                block = BLOCK(result);
                _heapinfo[block].busy.type = 0;
@@ -293,6 +297,10 @@ void * __malloc_unlocked (size_t size)
     }
 
     return result;
+
+oom:
+    __set_errno(ENOMEM);
+    return NULL;
 }
 
 /* Return memory to the heap. */
index 2b486ce..8215afa 100644 (file)
@@ -15,6 +15,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 #include "malloc.h"
 
 #ifdef __UCLIBC_HAS_THREADS__
@@ -44,8 +45,7 @@ void * realloc (void *ptr, size_t size)
        LOCK;
        __free_unlocked(ptr);
        result = __malloc_unlocked(0);
-       UNLOCK;
-       return(result);
+       goto alldone;
     }
 
     LOCK;
@@ -59,8 +59,7 @@ void * realloc (void *ptr, size_t size)
                    memcpy(result, ptr, size);
                    __free_unlocked(ptr);
                }
-               UNLOCK;
-               return result;
+               goto alldone;
            }
 
            /* The new size is a large allocation as well; see if
@@ -74,12 +73,12 @@ void * realloc (void *ptr, size_t size)
                    = _heapinfo[block].busy.info.size - blocks;
                _heapinfo[block].busy.info.size = blocks;
                __free_unlocked(ADDRESS(block + blocks));
-               UNLOCK;
-               return ptr;
+               result = ptr;
+               goto alldone;
            } else if (blocks == _heapinfo[block].busy.info.size) {
                /* No size change necessary. */
-               UNLOCK;
-               return ptr;
+               result = ptr;
+               goto alldone;
            } else {
                /* Won't fit, so allocate a new region that will.  Free
                   the old region first in case there is sufficient adjacent
@@ -102,13 +101,11 @@ void * realloc (void *ptr, size_t size)
                        __malloc_unlocked(blocks * BLOCKSIZE);
                        __free_unlocked(previous);
                    }       
-                   UNLOCK;
-                   return NULL;
+                   goto oom;
                }
                if (ptr != result)
                    memmove(result, ptr, blocks * BLOCKSIZE);
-               UNLOCK;
-               return result;
+               goto alldone;
            }
            break;
 
@@ -117,24 +114,29 @@ void * realloc (void *ptr, size_t size)
               the fragment size. */
            if ((size > 1 << (type - 1)) && (size <= 1 << type)) {
                /* New size is the same kind of fragment. */
-               UNLOCK;
-               return ptr;
+               result = ptr;
+               goto alldone;
            }
            else {
                /* New size is different; allocate a new space, and copy
                   the lesser of the new size and the old. */
                result = __malloc_unlocked(size);
                if (!result) {
-                   UNLOCK;
-                   return NULL;
+                   goto oom;
                }
                memcpy(result, ptr, MIN(size, (size_t)(1 << type)));
                __free_unlocked(ptr);
-               UNLOCK;
-               return result;
+               goto alldone;
            }
            break;
     }
+alldone:
     UNLOCK;
+    return result;
+
+oom:
+    UNLOCK;
+    __set_errno(ENOMEM);
+    return NULL;
 }
 
index 5f88cf4..98ac41c 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <stdlib.h>
 #include <unistd.h>
+#include <errno.h>
 #include <sys/mman.h>
 
 #include "malloc.h"
@@ -173,6 +174,7 @@ malloc_from_heap (size_t size, struct heap *heap)
 void *
 malloc (size_t size)
 {
+  void *mem;
 #ifdef MALLOC_DEBUGGING
   static int debugging_initialized = 0;
   if (! debugging_initialized)
@@ -185,12 +187,22 @@ malloc (size_t size)
 #endif
 
 #if defined(__MALLOC_GLIBC_COMPAT__)
-  if (size == 0)
-    return 0;
-#else
-  if (size == 0)
+  if (unlikely(size == 0))
       size++;
+#else
+  /* Some programs will call malloc (0).  Lets be strict and return NULL */
+  if (unlikely(size == 0))
+      goto oom;
 #endif
-
-  return malloc_from_heap (size, &__malloc_heap);
+  /* Check if they are doing something dumb like malloc(-1) */
+  if (unlikely(((unsigned long)size > (unsigned long)(MALLOC_HEADER_SIZE*-2))))
+      goto oom;
+
+  mem = malloc_from_heap (size, &__malloc_heap);
+  if (unlikely(!mem)) {
+oom:
+      __set_errno(ENOMEM);
+      return NULL;
+  }
+  return mem;
 }
index d4e0d9c..9e6f880 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 
 #include "malloc.h"
 #include "heap.h"
@@ -25,13 +26,12 @@ realloc (void *mem, size_t new_size)
   char *base_mem;
 
   /* Check for special cases.  */
-  if (! new_size)
-    {
+  if (!mem)
+      return malloc(new_size);
+  if (!new_size) {
       free (mem);
-      return 0;
-    }
-  else if (! mem)
-    return malloc (new_size);
+      return (malloc(new_size));
+  }
 
   /* Normal realloc.  */