diff options
Diffstat (limited to 'db2/os/os_alloc.c')
-rw-r--r-- | db2/os/os_alloc.c | 202 |
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); } |