00001 /*- 00002 * See the file LICENSE for redistribution information. 00003 * 00004 * Copyright (c) 1997, 1998, 1999, 2000 00005 * Sleepycat Software. All rights reserved. 00006 */ 00007 00008 #include "config.h" 00009 00010 #ifndef lint 00011 static const char revid[] = "$Id: os__alloc_8c-source.html,v 1.1 2008年06月08日 10:21:05 sebdiaz Exp $"; 00012 #endif /* not lint */ 00013 00014 #ifndef NO_SYSTEM_INCLUDES 00015 #include <sys/types.h> 00016 00017 #include <errno.h> 00018 #include <string.h> 00019 #include <stdlib.h> 00020 #endif 00021 00022 #include "db_int.h" 00023 #include "os_jump.h" 00024 00025 #ifdef DIAGNOSTIC 00026 static void __os_guard __P((void)); 00027 #endif 00028 00029 /* 00030 * !!! 00031 * Correct for systems that return NULL when you allocate 0 bytes of memory. 00032 * There are several places in DB where we allocate the number of bytes held 00033 * by the key/data item, and it can be 0. Correct here so that malloc never 00034 * returns a NULL for that reason (which behavior is permitted by ANSI). We 00035 * could make these calls macros on non-Alpha architectures (that's where we 00036 * saw the problem), but it's probably not worth the autoconf complexity. 00037 * 00038 * !!! 00039 * Correct for systems that don't set errno when malloc and friends fail. 00040 * 00041 * Out of memory. 00042 * We wish to hold the whole sky, 00043 * But we never will. 00044 */ 00045 00046 /* 00047 * CDB___os_strdup -- 00048 * The strdup(3) function for DB. 00049 * 00050 * PUBLIC: int CDB___os_strdup __P((DB_ENV *, const char *, void *)); 00051 */ 00052 int 00053 CDB___os_strdup(dbenv, str, storep) 00054 DB_ENV *dbenv; 00055 const char *str; 00056 void *storep; 00057 { 00058 size_t size; 00059 int ret; 00060 void *p; 00061 00062 *(void **)storep = NULL; 00063 00064 size = strlen(str) + 1; 00065 if ((ret = CDB___os_malloc(dbenv, size, NULL, &p)) != 0) 00066 return (ret); 00067 00068 memcpy(p, str, size); 00069 00070 *(void **)storep = p; 00071 return (0); 00072 } 00073 00074 /* 00075 * CDB___os_calloc -- 00076 * The calloc(3) function for DB. 00077 * 00078 * PUBLIC: int CDB___os_calloc __P((DB_ENV *, size_t, size_t, void *)); 00079 */ 00080 int 00081 CDB___os_calloc(dbenv, num, size, storep) 00082 DB_ENV *dbenv; 00083 size_t num, size; 00084 void *storep; 00085 { 00086 void *p; 00087 int ret; 00088 00089 size *= num; 00090 if ((ret = CDB___os_malloc(dbenv, size, NULL, &p)) != 0) 00091 return (ret); 00092 00093 memset(p, 0, size); 00094 00095 *(void **)storep = p; 00096 return (0); 00097 } 00098 00099 /* 00100 * CDB___os_malloc -- 00101 * The malloc(3) function for DB. 00102 * 00103 * PUBLIC: int CDB___os_malloc __P((DB_ENV *, size_t, void *(*)(size_t), void *)); 00104 */ 00105 int 00106 CDB___os_malloc(dbenv, size, db_malloc, storep) 00107 DB_ENV *dbenv; 00108 size_t size; 00109 void *(*db_malloc) __P((size_t)), *storep; 00110 { 00111 int ret; 00112 void *p; 00113 00114 *(void **)storep = NULL; 00115 00116 /* Never allocate 0 bytes -- some C libraries don't like it. */ 00117 if (size == 0) 00118 ++size; 00119 #ifdef DIAGNOSTIC 00120 else 00121 ++size; /* Add room for a guard byte. */ 00122 #endif 00123 00124 /* Some C libraries don't correctly set errno when malloc(3) fails. */ 00125 CDB___os_set_errno(0); 00126 if (db_malloc != NULL) 00127 p = db_malloc(size); 00128 else if (CDB___db_jump.j_malloc != NULL) 00129 p = CDB___db_jump.j_malloc(size); 00130 else 00131 p = malloc(size); 00132 if (p == NULL) { 00133 ret = CDB___os_get_errno(); 00134 if (ret == 0) { 00135 CDB___os_set_errno(ENOMEM); 00136 ret = ENOMEM; 00137 } 00138 CDB___db_err(dbenv, 00139 "malloc: %s: %lu", strerror(ret), (u_long)size); 00140 return (ret); 00141 } 00142 00143 #ifdef DIAGNOSTIC 00144 /* 00145 * Guard bytes: if #DIAGNOSTIC is defined, we allocate an additional 00146 * byte after the memory and set it to a special value that we check 00147 * for when the memory is free'd. This is fine for structures, but 00148 * not quite so fine for strings. There are places in DB where memory 00149 * is allocated sufficient to hold the largest possible string that 00150 * we'll see, and then only some subset of the memory is used. To 00151 * support this CDB_usage, the CDB___os_freestr() function checks the byte 00152 * after the string's nul, which may or may not be the last byte in 00153 * the originally allocated memory. 00154 */ 00155 memset(p, CLEAR_BYTE, size); /* Initialize guard byte. */ 00156 #endif 00157 *(void **)storep = p; 00158 00159 return (0); 00160 } 00161 00162 /* 00163 * CDB___os_realloc -- 00164 * The realloc(3) function for DB. 00165 * 00166 * PUBLIC: int CDB___os_realloc __P((DB_ENV *, 00167 * PUBLIC: size_t, void *(*)(void *, size_t), void *)); 00168 */ 00169 int 00170 CDB___os_realloc(dbenv, size, db_realloc, storep) 00171 DB_ENV *dbenv; 00172 size_t size; 00173 void *(*db_realloc) __P((void *, size_t)), *storep; 00174 { 00175 int ret; 00176 void *p, *ptr; 00177 00178 ptr = *(void **)storep; 00179 00180 /* If we haven't yet allocated anything yet, simply call malloc. */ 00181 if (ptr == NULL && db_realloc == NULL) 00182 return (CDB___os_malloc(dbenv, size, NULL, storep)); 00183 00184 /* Never allocate 0 bytes -- some C libraries don't like it. */ 00185 if (size == 0) 00186 ++size; 00187 #ifdef DIAGNOSTIC 00188 else 00189 ++size; /* Add room for a guard byte. */ 00190 #endif 00191 00192 /* 00193 * Some C libraries don't correctly set errno when realloc(3) fails. 00194 * 00195 * Don't overwrite the original pointer, there are places in DB we 00196 * try to continue after realloc fails. 00197 */ 00198 CDB___os_set_errno(0); 00199 if (db_realloc != NULL) 00200 p = db_realloc(ptr, size); 00201 else if (CDB___db_jump.j_realloc != NULL) 00202 p = CDB___db_jump.j_realloc(ptr, size); 00203 else 00204 p = realloc(ptr, size); 00205 if (p == NULL) { 00206 if ((ret = CDB___os_get_errno()) == 0) { 00207 ret = ENOMEM; 00208 CDB___os_set_errno(ENOMEM); 00209 } 00210 CDB___db_err(dbenv, 00211 "realloc: %s: %lu", strerror(ret), (u_long)size); 00212 return (ret); 00213 } 00214 #ifdef DIAGNOSTIC 00215 ((u_int8_t *)p)[size - 1] = CLEAR_BYTE; /* Initialize guard byte. */ 00216 #endif 00217 00218 *(void **)storep = p; 00219 00220 return (0); 00221 } 00222 00223 /* 00224 * CDB___os_free -- 00225 * The free(3) function for DB. 00226 * 00227 * PUBLIC: void CDB___os_free __P((void *, size_t)); 00228 */ 00229 void 00230 CDB___os_free(ptr, size) 00231 void *ptr; 00232 size_t size; 00233 { 00234 #ifdef DIAGNOSTIC 00235 if (size != 0) { 00236 /* 00237 * Check that the guard byte (one past the end of the memory) is 00238 * still CLEAR_BYTE. 00239 */ 00240 if (((u_int8_t *)ptr)[size] != CLEAR_BYTE) 00241 __os_guard(); 00242 00243 /* Clear memory. */ 00244 if (size != 0) 00245 memset(ptr, CLEAR_BYTE, size); 00246 } 00247 #else 00248 COMPQUIET(size, 0); 00249 #endif 00250 00251 if (CDB___db_jump.j_free != NULL) 00252 CDB___db_jump.j_free(ptr); 00253 else 00254 free(ptr); 00255 } 00256 00257 /* 00258 * CDB___os_freestr -- 00259 * The free(3) function for DB, freeing a string. 00260 * 00261 * PUBLIC: void CDB___os_freestr __P((void *)); 00262 */ 00263 void 00264 CDB___os_freestr(ptr) 00265 void *ptr; 00266 { 00267 #ifdef DIAGNOSTIC 00268 size_t size; 00269 00270 size = strlen(ptr) + 1; 00271 00272 /* 00273 * Check that the guard byte (one past the end of the memory) is 00274 * still CLEAR_BYTE. 00275 */ 00276 if (((u_int8_t *)ptr)[size] != CLEAR_BYTE) 00277 __os_guard(); 00278 00279 /* Clear memory. */ 00280 memset(ptr, CLEAR_BYTE, size); 00281 #endif 00282 00283 if (CDB___db_jump.j_free != NULL) 00284 CDB___db_jump.j_free(ptr); 00285 else 00286 free(ptr); 00287 } 00288 00289 #ifdef DIAGNOSTIC 00290 /* 00291 * __os_guard -- 00292 * Complain and abort. 00293 */ 00294 static void 00295 __os_guard() 00296 { 00297 /* 00298 * Eventually, once we push a DB_ENV handle down to these 00299 * routines, we should use the standard output channels. 00300 */ 00301 fprintf(stderr, "Guard byte incorrect during free.\n"); 00302 abort(); 00303 /* NOTREACHED */ 00304 } 00305 #endif 00306 00307 /* 00308 * CDB___ua_memcpy -- 00309 * Copy memory to memory without relying on any kind of alignment. 00310 * 00311 * There are places in DB that we have unaligned data, for example, 00312 * when we've stored a structure in a log record as a DBT, and now 00313 * we want to look at it. Unfortunately, if you have code like: 00314 * 00315 * struct a { 00316 * int x; 00317 * } *p; 00318 * 00319 * void *func_argument; 00320 * int local; 00321 * 00322 * p = (struct a *)func_argument; 00323 * memcpy(&local, p->x, sizeof(local)); 00324 * 00325 * compilers optimize to use inline instructions requiring alignment, 00326 * and records in the log don't have any particular alignment. (This 00327 * isn't a compiler bug, because it's a structure they're allowed to 00328 * assume alignment.) 00329 * 00330 * Casting the memcpy arguments to (u_int8_t *) appears to work most 00331 * of the time, but we've seen examples where it wasn't sufficient 00332 * and there's nothing in ANSI C that requires that work. 00333 * 00334 * PUBLIC: void *CDB___ua_memcpy __P((void *, const void *, size_t)); 00335 */ 00336 void * 00337 CDB___ua_memcpy(dst, src, len) 00338 void *dst; 00339 const void *src; 00340 size_t len; 00341 { 00342 return (memcpy(dst, src, len)); 00343 }