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