aboutsummaryrefslogtreecommitdiff
path: root/db2/os/os_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'db2/os/os_alloc.c')
-rw-r--r--db2/os/os_alloc.c202
1 files changed, 157 insertions, 45 deletions
diff --git a/db2/os/os_alloc.c b/db2/os/os_alloc.c
index 35784476c0..0090eb14a7 100644
--- a/db2/os/os_alloc.c
+++ b/db2/os/os_alloc.c
@@ -8,40 +8,22 @@
#include "config.h"
#ifndef lint
-static const char sccsid[] = "@(#)os_alloc.c 10.6 (Sleepycat) 5/2/98";
+static const char sccsid[] = "@(#)os_alloc.c 10.10 (Sleepycat) 10/12/98";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
+#include <errno.h>
#include <string.h>
+#include <stdlib.h>
#endif
#include "db_int.h"
+#include "os_jump.h"
/*
- * __db_strdup --
- * The strdup(3) function for DB.
- *
- * PUBLIC: char *__db_strdup __P((const char *));
- */
-char *
-__db_strdup(str)
- const char *str;
-{
- size_t len;
- char *copy;
-
- len = strlen(str) + 1;
- if ((copy = __db_malloc(len)) == NULL)
- return (NULL);
-
- memcpy(copy, str, len);
- return (copy);
-}
-
-/*
- * XXX
+ * !!!
* Correct for systems that return NULL when you allocate 0 bytes of memory.
* There are several places in DB where we allocate the number of bytes held
* by the key/data item, and it can be 0. Correct here so that malloc never
@@ -49,59 +31,189 @@ __db_strdup(str)
* could make these calls macros on non-Alpha architectures (that's where we
* saw the problem), but it's probably not worth the autoconf complexity.
*
+ * !!!
+ * Correct for systems that don't set errno when malloc and friends fail.
+ *
* Out of memory.
* We wish to hold the whole sky,
* But we never will.
*/
+
+/*
+ * __os_strdup --
+ * The strdup(3) function for DB.
+ *
+ * PUBLIC: int __os_strdup __P((const char *, void *));
+ */
+int
+__os_strdup(str, storep)
+ const char *str;
+ void *storep;
+{
+ size_t size;
+ int ret;
+ void *p;
+
+ *(void **)storep = NULL;
+
+ size = strlen(str) + 1;
+ if ((ret = __os_malloc(size, NULL, &p)) != 0)
+ return (ret);
+
+ memcpy(p, str, size);
+
+ *(void **)storep = p;
+ return (0);
+}
+
/*
- * __db_calloc --
+ * __os_calloc --
* The calloc(3) function for DB.
*
- * PUBLIC: void *__db_calloc __P((size_t, size_t));
+ * PUBLIC: int __os_calloc __P((size_t, size_t, void *));
*/
-void *
-__db_calloc(num, size)
+int
+__os_calloc(num, size, storep)
size_t num, size;
+ void *storep;
{
void *p;
+ int ret;
size *= num;
- if ((p = __db_jump.j_malloc(size == 0 ? 1 : size)) != NULL)
- memset(p, 0, size);
- return (p);
+ if ((ret = __os_malloc(size, NULL, &p)) != 0)
+ return (ret);
+
+ memset(p, 0, size);
+ *(void **)storep = p;
+
+ return (0);
}
/*
- * __db_malloc --
+ * __os_malloc --
* The malloc(3) function for DB.
*
- * PUBLIC: void *__db_malloc __P((size_t));
+ * PUBLIC: int __os_malloc __P((size_t, void *(*)(size_t), void *));
*/
-void *
-__db_malloc(size)
+int
+__os_malloc(size, db_malloc, storep)
size_t size;
+ void *(*db_malloc) __P((size_t)), *storep;
{
-#ifdef DIAGNOSTIC
void *p;
- p = __db_jump.j_malloc(size == 0 ? 1 : size);
- memset(p, 0xff, size == 0 ? 1 : size);
- return (p);
-#else
- return (__db_jump.j_malloc(size == 0 ? 1 : size));
+ *(void **)storep = NULL;
+
+ /* Never allocate 0 bytes -- some C libraries don't like it. */
+ if (size == 0)
+ ++size;
+
+ /* Some C libraries don't correctly set errno when malloc(3) fails. */
+ errno = 0;
+ if (db_malloc != NULL)
+ p = db_malloc(size);
+ else if (__db_jump.j_malloc != NULL)
+ p = __db_jump.j_malloc(size);
+ else
+ p = malloc(size);
+ if (p == NULL) {
+ if (errno == 0)
+ errno = ENOMEM;
+ return (errno);
+ }
+
+#ifdef DIAGNOSTIC
+ memset(p, 0xdb, size);
#endif
+ *(void **)storep = p;
+
+ return (0);
}
/*
- * __db_realloc --
+ * __os_realloc --
* The realloc(3) function for DB.
*
- * PUBLIC: void *__db_realloc __P((void *, size_t));
+ * PUBLIC: int __os_realloc __P((void *, size_t));
+ */
+int
+__os_realloc(storep, size)
+ void *storep;
+ size_t size;
+{
+ void *p, *ptr;
+
+ ptr = *(void **)storep;
+
+ /* If we haven't yet allocated anything yet, simply call malloc. */
+ if (ptr == NULL)
+ return (__os_malloc(size, NULL, storep));
+
+ /* Never allocate 0 bytes -- some C libraries don't like it. */
+ if (size == 0)
+ ++size;
+
+ /*
+ * Some C libraries don't correctly set errno when realloc(3) fails.
+ *
+ * Don't overwrite the original pointer, there are places in DB we
+ * try to continue after realloc fails.
+ */
+ errno = 0;
+ if (__db_jump.j_realloc != NULL)
+ p = __db_jump.j_realloc(ptr, size);
+ else
+ p = realloc(ptr, size);
+ if (p == NULL) {
+ if (errno == 0)
+ errno = ENOMEM;
+ return (errno);
+ }
+
+ *(void **)storep = p;
+
+ return (0);
+}
+
+/*
+ * __os_free --
+ * The free(3) function for DB.
+ *
+ * PUBLIC: void __os_free __P((void *, size_t));
*/
-void *
-__db_realloc(ptr, size)
+void
+__os_free(ptr, size)
void *ptr;
size_t size;
{
- return (__db_jump.j_realloc(ptr, size == 0 ? 1 : size));
+#ifdef DIAGNOSTIC
+ if (size != 0)
+ memset(ptr, 0xdb, size);
+#endif
+
+ if (__db_jump.j_free != NULL)
+ __db_jump.j_free(ptr);
+ else
+ free(ptr);
+}
+
+/*
+ * __os_freestr --
+ * The free(3) function for DB, freeing a string.
+ *
+ * PUBLIC: void __os_freestr __P((void *));
+ */
+void
+__os_freestr(ptr)
+ void *ptr;
+{
+#ifdef DIAGNOSTIC
+ memset(ptr, 0xdb, strlen(ptr) + 1);
+#endif
+
+ if (__db_jump.j_free != NULL)
+ __db_jump.j_free(ptr);
+ else
+ free(ptr);
}