1*7c478bd9Sstevel@tonic-gate /*- 2*7c478bd9Sstevel@tonic-gate * See the file LICENSE for redistribution information. 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * Copyright (c) 1997, 1998 5*7c478bd9Sstevel@tonic-gate * Sleepycat Software. All rights reserved. 6*7c478bd9Sstevel@tonic-gate */ 7*7c478bd9Sstevel@tonic-gate 8*7c478bd9Sstevel@tonic-gate #include "config.h" 9*7c478bd9Sstevel@tonic-gate 10*7c478bd9Sstevel@tonic-gate #ifndef lint 11*7c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)os_alloc.c 10.10 (Sleepycat) 10/12/98"; 12*7c478bd9Sstevel@tonic-gate #endif /* not lint */ 13*7c478bd9Sstevel@tonic-gate 14*7c478bd9Sstevel@tonic-gate #ifndef NO_SYSTEM_INCLUDES 15*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 16*7c478bd9Sstevel@tonic-gate 17*7c478bd9Sstevel@tonic-gate #include <errno.h> 18*7c478bd9Sstevel@tonic-gate #include <string.h> 19*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 20*7c478bd9Sstevel@tonic-gate #endif 21*7c478bd9Sstevel@tonic-gate 22*7c478bd9Sstevel@tonic-gate #include "db_int.h" 23*7c478bd9Sstevel@tonic-gate #include "os_jump.h" 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate /* 26*7c478bd9Sstevel@tonic-gate * !!! 27*7c478bd9Sstevel@tonic-gate * Correct for systems that return NULL when you allocate 0 bytes of memory. 28*7c478bd9Sstevel@tonic-gate * There are several places in DB where we allocate the number of bytes held 29*7c478bd9Sstevel@tonic-gate * by the key/data item, and it can be 0. Correct here so that malloc never 30*7c478bd9Sstevel@tonic-gate * returns a NULL for that reason (which behavior is permitted by ANSI). We 31*7c478bd9Sstevel@tonic-gate * could make these calls macros on non-Alpha architectures (that's where we 32*7c478bd9Sstevel@tonic-gate * saw the problem), but it's probably not worth the autoconf complexity. 33*7c478bd9Sstevel@tonic-gate * 34*7c478bd9Sstevel@tonic-gate * !!! 35*7c478bd9Sstevel@tonic-gate * Correct for systems that don't set errno when malloc and friends fail. 36*7c478bd9Sstevel@tonic-gate * 37*7c478bd9Sstevel@tonic-gate * Out of memory. 38*7c478bd9Sstevel@tonic-gate * We wish to hold the whole sky, 39*7c478bd9Sstevel@tonic-gate * But we never will. 40*7c478bd9Sstevel@tonic-gate */ 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate /* 43*7c478bd9Sstevel@tonic-gate * __os_strdup -- 44*7c478bd9Sstevel@tonic-gate * The strdup(3) function for DB. 45*7c478bd9Sstevel@tonic-gate * 46*7c478bd9Sstevel@tonic-gate * PUBLIC: int __os_strdup __P((const char *, void *)); 47*7c478bd9Sstevel@tonic-gate */ 48*7c478bd9Sstevel@tonic-gate int 49*7c478bd9Sstevel@tonic-gate __os_strdup(str, storep) 50*7c478bd9Sstevel@tonic-gate const char *str; 51*7c478bd9Sstevel@tonic-gate void *storep; 52*7c478bd9Sstevel@tonic-gate { 53*7c478bd9Sstevel@tonic-gate size_t size; 54*7c478bd9Sstevel@tonic-gate int ret; 55*7c478bd9Sstevel@tonic-gate void *p; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate *(void **)storep = NULL; 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate size = strlen(str) + 1; 60*7c478bd9Sstevel@tonic-gate if ((ret = __os_malloc(size, NULL, &p)) != 0) 61*7c478bd9Sstevel@tonic-gate return (ret); 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate memcpy(p, str, size); 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate *(void **)storep = p; 66*7c478bd9Sstevel@tonic-gate return (0); 67*7c478bd9Sstevel@tonic-gate } 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate /* 70*7c478bd9Sstevel@tonic-gate * __os_calloc -- 71*7c478bd9Sstevel@tonic-gate * The calloc(3) function for DB. 72*7c478bd9Sstevel@tonic-gate * 73*7c478bd9Sstevel@tonic-gate * PUBLIC: int __os_calloc __P((size_t, size_t, void *)); 74*7c478bd9Sstevel@tonic-gate */ 75*7c478bd9Sstevel@tonic-gate int 76*7c478bd9Sstevel@tonic-gate __os_calloc(num, size, storep) 77*7c478bd9Sstevel@tonic-gate size_t num, size; 78*7c478bd9Sstevel@tonic-gate void *storep; 79*7c478bd9Sstevel@tonic-gate { 80*7c478bd9Sstevel@tonic-gate void *p; 81*7c478bd9Sstevel@tonic-gate int ret; 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate size *= num; 84*7c478bd9Sstevel@tonic-gate if ((ret = __os_malloc(size, NULL, &p)) != 0) 85*7c478bd9Sstevel@tonic-gate return (ret); 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate memset(p, 0, size); 88*7c478bd9Sstevel@tonic-gate *(void **)storep = p; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate return (0); 91*7c478bd9Sstevel@tonic-gate } 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /* 94*7c478bd9Sstevel@tonic-gate * __os_malloc -- 95*7c478bd9Sstevel@tonic-gate * The malloc(3) function for DB. 96*7c478bd9Sstevel@tonic-gate * 97*7c478bd9Sstevel@tonic-gate * PUBLIC: int __os_malloc __P((size_t, void *(*)(size_t), void *)); 98*7c478bd9Sstevel@tonic-gate */ 99*7c478bd9Sstevel@tonic-gate int 100*7c478bd9Sstevel@tonic-gate __os_malloc(size, db_malloc, storep) 101*7c478bd9Sstevel@tonic-gate size_t size; 102*7c478bd9Sstevel@tonic-gate void *(*db_malloc) __P((size_t)), *storep; 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate void *p; 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate *(void **)storep = NULL; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate /* Never allocate 0 bytes -- some C libraries don't like it. */ 109*7c478bd9Sstevel@tonic-gate if (size == 0) 110*7c478bd9Sstevel@tonic-gate ++size; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* Some C libraries don't correctly set errno when malloc(3) fails. */ 113*7c478bd9Sstevel@tonic-gate errno = 0; 114*7c478bd9Sstevel@tonic-gate if (db_malloc != NULL) 115*7c478bd9Sstevel@tonic-gate p = db_malloc(size); 116*7c478bd9Sstevel@tonic-gate else if (__db_jump.j_malloc != NULL) 117*7c478bd9Sstevel@tonic-gate p = __db_jump.j_malloc(size); 118*7c478bd9Sstevel@tonic-gate else 119*7c478bd9Sstevel@tonic-gate p = malloc(size); 120*7c478bd9Sstevel@tonic-gate if (p == NULL) { 121*7c478bd9Sstevel@tonic-gate if (errno == 0) 122*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 123*7c478bd9Sstevel@tonic-gate return (errno); 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate #ifdef DIAGNOSTIC 127*7c478bd9Sstevel@tonic-gate memset(p, 0xdb, size); 128*7c478bd9Sstevel@tonic-gate #endif 129*7c478bd9Sstevel@tonic-gate *(void **)storep = p; 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate return (0); 132*7c478bd9Sstevel@tonic-gate } 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate /* 135*7c478bd9Sstevel@tonic-gate * __os_realloc -- 136*7c478bd9Sstevel@tonic-gate * The realloc(3) function for DB. 137*7c478bd9Sstevel@tonic-gate * 138*7c478bd9Sstevel@tonic-gate * PUBLIC: int __os_realloc __P((void *, size_t)); 139*7c478bd9Sstevel@tonic-gate */ 140*7c478bd9Sstevel@tonic-gate int 141*7c478bd9Sstevel@tonic-gate __os_realloc(storep, size) 142*7c478bd9Sstevel@tonic-gate void *storep; 143*7c478bd9Sstevel@tonic-gate size_t size; 144*7c478bd9Sstevel@tonic-gate { 145*7c478bd9Sstevel@tonic-gate void *p, *ptr; 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate ptr = *(void **)storep; 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate /* If we haven't yet allocated anything yet, simply call malloc. */ 150*7c478bd9Sstevel@tonic-gate if (ptr == NULL) 151*7c478bd9Sstevel@tonic-gate return (__os_malloc(size, NULL, storep)); 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate /* Never allocate 0 bytes -- some C libraries don't like it. */ 154*7c478bd9Sstevel@tonic-gate if (size == 0) 155*7c478bd9Sstevel@tonic-gate ++size; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * Some C libraries don't correctly set errno when realloc(3) fails. 159*7c478bd9Sstevel@tonic-gate * 160*7c478bd9Sstevel@tonic-gate * Don't overwrite the original pointer, there are places in DB we 161*7c478bd9Sstevel@tonic-gate * try to continue after realloc fails. 162*7c478bd9Sstevel@tonic-gate */ 163*7c478bd9Sstevel@tonic-gate errno = 0; 164*7c478bd9Sstevel@tonic-gate if (__db_jump.j_realloc != NULL) 165*7c478bd9Sstevel@tonic-gate p = __db_jump.j_realloc(ptr, size); 166*7c478bd9Sstevel@tonic-gate else 167*7c478bd9Sstevel@tonic-gate p = realloc(ptr, size); 168*7c478bd9Sstevel@tonic-gate if (p == NULL) { 169*7c478bd9Sstevel@tonic-gate if (errno == 0) 170*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 171*7c478bd9Sstevel@tonic-gate return (errno); 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate *(void **)storep = p; 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate return (0); 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate /* 180*7c478bd9Sstevel@tonic-gate * __os_free -- 181*7c478bd9Sstevel@tonic-gate * The free(3) function for DB. 182*7c478bd9Sstevel@tonic-gate * 183*7c478bd9Sstevel@tonic-gate * PUBLIC: void __os_free __P((void *, size_t)); 184*7c478bd9Sstevel@tonic-gate */ 185*7c478bd9Sstevel@tonic-gate void 186*7c478bd9Sstevel@tonic-gate __os_free(ptr, size) 187*7c478bd9Sstevel@tonic-gate void *ptr; 188*7c478bd9Sstevel@tonic-gate size_t size; 189*7c478bd9Sstevel@tonic-gate { 190*7c478bd9Sstevel@tonic-gate #ifdef DIAGNOSTIC 191*7c478bd9Sstevel@tonic-gate if (size != 0) 192*7c478bd9Sstevel@tonic-gate memset(ptr, 0xdb, size); 193*7c478bd9Sstevel@tonic-gate #endif 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate if (__db_jump.j_free != NULL) 196*7c478bd9Sstevel@tonic-gate __db_jump.j_free(ptr); 197*7c478bd9Sstevel@tonic-gate else 198*7c478bd9Sstevel@tonic-gate free(ptr); 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate /* 202*7c478bd9Sstevel@tonic-gate * __os_freestr -- 203*7c478bd9Sstevel@tonic-gate * The free(3) function for DB, freeing a string. 204*7c478bd9Sstevel@tonic-gate * 205*7c478bd9Sstevel@tonic-gate * PUBLIC: void __os_freestr __P((void *)); 206*7c478bd9Sstevel@tonic-gate */ 207*7c478bd9Sstevel@tonic-gate void 208*7c478bd9Sstevel@tonic-gate __os_freestr(ptr) 209*7c478bd9Sstevel@tonic-gate void *ptr; 210*7c478bd9Sstevel@tonic-gate { 211*7c478bd9Sstevel@tonic-gate #ifdef DIAGNOSTIC 212*7c478bd9Sstevel@tonic-gate memset(ptr, 0xdb, strlen(ptr) + 1); 213*7c478bd9Sstevel@tonic-gate #endif 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate if (__db_jump.j_free != NULL) 216*7c478bd9Sstevel@tonic-gate __db_jump.j_free(ptr); 217*7c478bd9Sstevel@tonic-gate else 218*7c478bd9Sstevel@tonic-gate free(ptr); 219*7c478bd9Sstevel@tonic-gate } 220