UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 5 * 6 * THE BSD LICENSE 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * Redistributions of source code must retain the above copyright notice, this 12 * list of conditions and the following disclaimer. 13 * Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * Neither the name of the nor the names of its contributors may be 18 * used to endorse or promote products derived from this software without 19 * specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 25 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * system.c: A grab bag of system-level abstractions 36 * 37 * Many authors 38 */ 39 40 #if (defined(__GNUC__) && (__GNUC__ > 2)) 41 //include <new> 42 //using namespace std; 43 #else 44 //include <new.h> 45 #endif 46 #include "../daemon/netsite.h" 47 //include "ereport.h" 48 49 #ifdef XP_WIN32 50 #include <windows.h> 51 #include <process.h> 52 #endif 53 54 static int thread_malloc_key = -1; 55 56 static char* temp_dir = NULL; 57 58 #ifdef XP_WIN32 59 // TODO: 60 //_PNH original_newhandler = 0; 61 #else 62 typedef void (newhandler)(void); 63 static newhandler *original_newhandler = 0; 64 #endif 65 66 #include "pool.h" 67 #include "systhr.h" 68 69 #define MALLOC_KEY \ 70 ((pool_handle_t *)(thread_malloc_key != -1 ? systhread_getdata(thread_malloc_key) : NULL)) 71 72 73 #ifdef MCC_DEBUG 74 #define DEBUG_MALLOC 75 #endif 76 77 #ifdef DEBUG_MALLOC 78 79 /* The debug malloc routines provide several functions: 80 * 81 * - detect allocated memory overflow/underflow 82 * - detect multiple frees 83 * - intentionally clobbers malloc'd buffers 84 * - intentionally clobbers freed buffers 85 */ 86 #define DEBUG_MAGIC 0x12345678 87 #define DEBUG_MARGIN 32 88 #define DEBUG_MARGIN_CHAR '*' 89 #define DEBUG_MALLOC_CHAR '.' 90 #define DEBUG_FREE_CHAR 'X' 91 #endif /* DEBUG_MALLOC */ 92 93 NSAPI_PUBLIC char *system_version() 94 { 95 //return PRODUCT_ID"/"PRODUCT_VERSION_ID; 96 return "webserver/alpha"; 97 } 98 99 NSAPI_PUBLIC pool_handle_t *system_pool(void) 100 { 101 return MALLOC_KEY; 102 } 103 104 NSAPI_PUBLIC void *system_malloc(int size) 105 { 106 void *ret; 107 ret = pool_malloc(MALLOC_KEY, size); 108 if (!ret) { 109 //ereport_outofmemory(); 110 //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); // TODO 111 } 112 return ret; 113 } 114 115 116 NSAPI_PUBLIC void *system_calloc(int size) 117 { 118 void *ret; 119 ret = pool_malloc(MALLOC_KEY, size); 120 if(ret) { 121 ZERO(ret, size); 122 } else { 123 //ereport_outofmemory(); 124 //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); // TODO 125 } 126 return ret; 127 } 128 129 130 NSAPI_PUBLIC void *system_realloc(void *ptr, int size) 131 { 132 void *ret; 133 ret = pool_realloc(MALLOC_KEY, ptr, size); 134 if (!ret) { 135 //ereport_outofmemory(); 136 //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); 137 } 138 return ret; 139 } 140 141 142 NSAPI_PUBLIC void system_free(void *ptr) 143 { 144 pool_free(MALLOC_KEY, ptr); 145 } 146 147 NSAPI_PUBLIC char *system_strdup(const char *ptr) 148 { 149 //NS_ASSERT(ptr); 150 char *ret; 151 ret = pool_strdup(MALLOC_KEY, ptr); 152 if (!ret) { 153 //ereport_outofmemory(); 154 //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); 155 } 156 return ret; 157 } 158 159 160 NSAPI_PUBLIC void *system_malloc_perm(int size) 161 { 162 void *ret; 163 #ifndef DEBUG_MALLOC 164 ret = malloc(size); 165 #else 166 char *ptr = (char *)malloc(size + 2*DEBUG_MARGIN+2*sizeof(int)); 167 char *real_ptr; 168 int *magic; 169 int *length; 170 171 magic = (int *)ptr; 172 *magic = DEBUG_MAGIC; 173 ptr += sizeof(int); 174 length = (int *)ptr; 175 *length = size; 176 ptr += sizeof(int); 177 memset(ptr, DEBUG_MARGIN_CHAR, DEBUG_MARGIN); 178 ptr += DEBUG_MARGIN; 179 memset(ptr, DEBUG_MALLOC_CHAR, size); 180 real_ptr = ptr; 181 ptr += size; 182 memset(ptr, DEBUG_MARGIN_CHAR, DEBUG_MARGIN); 183 184 ret = real_ptr; 185 #endif 186 if (!ret) { 187 //ereport_outofmemory(); 188 //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); 189 } 190 return ret; 191 } 192 193 NSAPI_PUBLIC void *system_calloc_perm(int size) 194 { 195 void *ret = system_malloc_perm(size); 196 if(ret) 197 ZERO(ret, size); 198 return ret; 199 } 200 201 NSAPI_PUBLIC void *system_realloc_perm(void *ptr, int size) 202 { 203 void *ret; 204 205 #ifndef DEBUG_MALLOC 206 ret = realloc(ptr, size); 207 #else 208 int *magic, *length; 209 char *baseptr; 210 char *cptr; 211 212 /* realloc semantics allow realloc(NULL, size) */ 213 if (ptr == NULL) 214 return system_malloc_perm(size); 215 216 cptr = (char *)ptr - DEBUG_MARGIN - 2 * sizeof(int); 217 magic = (int *)cptr; 218 if (*magic == DEBUG_MAGIC) { 219 cptr += sizeof(int); 220 length = (int *)cptr; 221 if (*length < size) { 222 char *newptr = (char *)system_malloc_perm(size); 223 memcpy(newptr, ptr, *length); 224 system_free_perm(ptr); 225 226 ret = newptr; 227 }else { 228 ret = ptr; 229 } 230 } else { 231 ereport(LOG_WARN, XP_GetAdminString(DBT_systemReallocSmallerSize)); 232 ret = realloc(ptr, size); 233 } 234 #endif 235 236 if (!ret) { 237 //ereport_outofmemory(); 238 //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); 239 } 240 241 return ret; 242 } 243 244 NSAPI_PUBLIC void system_free_perm(void *ptr) 245 { 246 #ifdef DEBUG_MALLOC 247 int *length, *magic; 248 char *baseptr, *cptr; 249 int index; 250 251 NS_ASSERT(ptr); 252 253 cptr = baseptr = ((char *)ptr) - DEBUG_MARGIN - 2*sizeof(int); 254 255 magic = (int *)cptr; 256 if (*magic == DEBUG_MAGIC) { 257 cptr += sizeof(int); 258 259 length = (int *)cptr; 260 261 cptr += sizeof(int); 262 for (index=0; index<DEBUG_MARGIN; index++) 263 if (cptr[index] != DEBUG_MARGIN_CHAR) { 264 ereport(LOG_CATASTROPHE, XP_GetAdminString(DBT_systemRFreeCorruptMemoryPre)); 265 break; 266 } 267 268 cptr += DEBUG_MARGIN + *length; 269 for (index=0; index<DEBUG_MARGIN; index++) 270 if (cptr[index] != DEBUG_MARGIN_CHAR) { 271 ereport(LOG_CATASTROPHE, XP_GetAdminString(DBT_systemRFreeCorruptMemoryPost)); 272 break; 273 } 274 275 memset(baseptr, DEBUG_FREE_CHAR, *length + 2*DEBUG_MARGIN+sizeof(int)); 276 } else { 277 ereport(LOG_CATASTROPHE, XP_GetAdminString(DBT_systemRFreeUnallocatedMem)); 278 } 279 free(baseptr); 280 #else 281 free(ptr); 282 #endif 283 } 284 285 NSAPI_PUBLIC char *system_strdup_perm(const char *ptr) 286 { 287 char *ret; 288 289 #ifndef DEBUG_MALLOC 290 //NS_ASSERT(ptr); 291 ret = strdup(ptr); 292 #else 293 int len = strlen(ptr); 294 char *nptr = (char *)system_malloc_perm(len+1); 295 memcpy(nptr, ptr, len); 296 nptr[len] = '\0'; 297 ret = nptr; 298 #endif 299 300 if (!ret) { 301 //ereport_outofmemory(); 302 //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); 303 } 304 305 return ret; 306 } 307 308 NSAPI_PUBLIC void system_set_temp_dir(const char *dir) 309 { 310 // Leak any previously-allocated dir in case someone still has a reference 311 temp_dir = STRDUP(dir); 312 } 313 314 NSAPI_PUBLIC const char *system_get_temp_dir(void) 315 { 316 char* dir = temp_dir; 317 318 if (!dir) { 319 #ifdef XP_WIN32 320 dir = getenv("TEMP"); 321 if (!dir) dir = getenv("TMP"); 322 if (!dir) dir = "C:\\TEMP"; 323 #else 324 dir = "/tmp"; 325 #endif 326 } 327 328 return dir; 329 } 330 331 int system_close(int fd) { 332 while(close(fd)) { 333 if(errno != EINTR) { 334 return -1; 335 } else { 336 log_ereport(LOG_VERBOSE, "close interrupted by signal"); // TODO: use debug log level 337 } 338 } 339 return 0; 340 } 341 342 NSAPI_PUBLIC int 343 getThreadMallocKey(void) 344 { 345 return thread_malloc_key; 346 } 347 348 NSAPI_PUBLIC void 349 InitThreadMallocKey(void) 350 { 351 // TODO 352 //PR_NewThreadPrivateIndex((unsigned int *)&thread_malloc_key, NULL); 353 //PR_ASSERT(thread_malloc_key); 354 } 355 356 // TODO: don't know what this is 357 /* 358 #ifdef XP_WIN32 359 static int _cdecl system_newhandler(unsigned int size) 360 { 361 //ereport_outofmemory(); 362 363 if (original_newhandler) { 364 // Let original handler deal with things 365 return (*original_newhandler)(size); 366 } 367 368 // Tell new not to retry the allocation 369 return 0; 370 } 371 #else 372 static void system_newhandler() 373 { 374 // We want to preserve the original new semantics, but we don't know what 375 // those semantics are. Some platforms throw xalloc while others throw 376 // bad_alloc. 377 378 //ereport_outofmemory(); 379 380 if (original_newhandler) { 381 // Let original handler deal with things 382 (*original_newhandler)(); 383 } else { 384 // No original handler to call; try to remove all handlers 385 static PRBool flagRemovedHandler = PR_FALSE; 386 if (flagRemovedHandler) { 387 abort(); 388 } 389 //set_new_handler(0); // TODO: set_new_handler 390 flagRemovedHandler = PR_TRUE; 391 } 392 } 393 #endif 394 395 NSAPI_PUBLIC void system_setnewhandler(void) 396 { 397 #ifdef XP_WIN32 398 original_newhandler = _set_new_handler(system_newhandler); 399 #else 400 //original_newhandler = set_new_handler(system_newhandler); // TODO: ... 401 #endif 402 } 403 404 */ 405