1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77#include <config.h> 78#include "dcethread-debug.h" 79#include <stdarg.h> 80#include <stdlib.h> 81#include <stdio.h> 82#include <pthread.h> 83 84pthread_mutex_t log_lock = PTHREAD_MUTEX_INITIALIZER; 85 86void 87dcethread__default_log_callback (const char* file, unsigned int line, 88 int level, const char* str, void* data ATTRIBUTE_UNUSED) 89{ 90 const char* level_name = NULL; 91 92 switch (level) 93 { 94 case DCETHREAD_DEBUG_ERROR: 95 level_name = "ERROR"; 96 break; 97 case DCETHREAD_DEBUG_WARNING: 98 level_name = "WARNING"; 99 break; 100 case DCETHREAD_DEBUG_INFO: 101 level_name = "INFO"; 102 break; 103 case DCETHREAD_DEBUG_VERBOSE: 104 level_name = "VERBOSE"; 105 break; 106 case DCETHREAD_DEBUG_TRACE: 107 level_name = "TRACE"; 108 break; 109 default: 110 level_name = "UNKNOWN"; 111 break; 112 } 113 114 pthread_mutex_lock(&log_lock); 115 fprintf(stderr, "dcethread-%s %s:%i: %s\n", level_name, file, line, str); 116 if (level == DCETHREAD_DEBUG_ERROR) 117 abort(); 118 pthread_mutex_unlock(&log_lock); 119} 120 121static void (*log_callback) (const char* file, unsigned int line, int level, const char* str, void* data) = NULL; 122static void *log_callback_data = NULL; 123 124void 125dcethread__debug_set_callback(void (*cb) (const char*, unsigned int, int, const char*, void* data), void* data) 126{ 127 log_callback = cb; 128 log_callback_data = data; 129} 130 131#ifndef HAVE_VASPRINTF 132static char * 133my_vasprintf(const char* format, va_list args) 134{ 135 char *smallBuffer; 136 unsigned int bufsize; 137 int requiredLength; 138 int newRequiredLength; 139 char* outputString = NULL; 140 va_list args2; 141 142 va_copy(args2, args); 143 144 bufsize = 4; 145 /* Use a small buffer in case libc does not like NULL */ 146 do 147 { 148 smallBuffer = malloc(bufsize); 149 150 if (!smallBuffer) 151 { 152 return NULL; 153 } 154 155 requiredLength = vsnprintf(smallBuffer, bufsize, format, args); 156 if (requiredLength < 0) 157 { 158 bufsize *= 2; 159 } 160 free(smallBuffer); 161 } while (requiredLength < 0); 162 163 if (requiredLength >= (int)(0xFFFFFFFF - 1)) 164 { 165 return NULL; 166 } 167 168 outputString = malloc(requiredLength + 2); 169 170 if (!outputString) 171 { 172 return NULL; 173 } 174 175 newRequiredLength = vsnprintf(outputString, requiredLength + 1, format, args2); 176 if (newRequiredLength < 0) 177 { 178 free(outputString); 179 return NULL; 180 } 181 182 va_end(args2); 183 184 return outputString; 185} 186#endif /* HAVE_VASPRINTF */ 187 188void 189dcethread__debug_printf(const char* file, unsigned int line, int level, const char* fmt, ...) 190{ 191 va_list ap; 192 char* str = NULL; 193 194 if (!log_callback) 195 return; 196 197 va_start(ap, fmt); 198 199#if HAVE_VASPRINTF 200 vasprintf(&str, fmt, ap); 201#else 202 str = my_vasprintf(fmt, ap); 203#endif 204 205 if (str) 206 { 207 log_callback(file, line, level, str, log_callback_data); 208 free(str); 209 } 210 211 va_end(ap); 212} 213