about summary refs log tree commit diff
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);
 }