1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1999,2008 Oracle. All rights reserved. 5 * 6 * $Id: log_debug.c,v 1.15 2008/01/08 20:58:41 bostic Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12#include "dbinc/db_page.h" 13#include "dbinc/db_am.h" 14#include "dbinc/log.h" 15 16static int __log_printf_int __P((ENV *, DB_TXN *, const char *, va_list)); 17 18/* 19 * __log_printf_capi -- 20 * Write a printf-style format string into the DB log. 21 * 22 * PUBLIC: int __log_printf_capi __P((DB_ENV *, DB_TXN *, const char *, ...)) 23 * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); 24 */ 25int 26#ifdef STDC_HEADERS 27__log_printf_capi(DB_ENV *dbenv, DB_TXN *txnid, const char *fmt, ...) 28#else 29__log_printf_capi(dbenv, txnid, fmt, va_alist) 30 DB_ENV *dbenv; 31 DB_TXN *txnid; 32 const char *fmt; 33 va_dcl 34#endif 35{ 36 va_list ap; 37 int ret; 38 39#ifdef STDC_HEADERS 40 va_start(ap, fmt); 41#else 42 va_start(ap); 43#endif 44 ret = __log_printf_pp(dbenv, txnid, fmt, ap); 45 va_end(ap); 46 47 return (ret); 48} 49 50/* 51 * __log_printf_pp -- 52 * Handle the arguments and call an internal routine to do the work. 53 * 54 * The reason this routine isn't just folded into __log_printf_capi 55 * is because the C++ API has to call a C API routine, and you can 56 * only pass variadic arguments to a single routine. 57 * 58 * PUBLIC: int __log_printf_pp 59 * PUBLIC: __P((DB_ENV *, DB_TXN *, const char *, va_list)); 60 */ 61int 62__log_printf_pp(dbenv, txnid, fmt, ap) 63 DB_ENV *dbenv; 64 DB_TXN *txnid; 65 const char *fmt; 66 va_list ap; 67{ 68 DB_THREAD_INFO *ip; 69 ENV *env; 70 int ret; 71 72 env = dbenv->env; 73 74 ENV_REQUIRES_CONFIG(env, 75 env->lg_handle, "DB_ENV->log_printf", DB_INIT_LOG); 76 77 ENV_ENTER(env, ip); 78 REPLICATION_WRAP(env, (__log_printf_int(env, txnid, fmt, ap)), 0, ret); 79 va_end(ap); 80 ENV_LEAVE(env, ip); 81 return (ret); 82} 83 84/* 85 * __log_printf -- 86 * Write a printf-style format string into the DB log. 87 * 88 * PUBLIC: int __log_printf __P((ENV *, DB_TXN *, const char *, ...)) 89 * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); 90 */ 91int 92#ifdef STDC_HEADERS 93__log_printf(ENV *env, DB_TXN *txnid, const char *fmt, ...) 94#else 95__log_printf(env, txnid, fmt, va_alist) 96 ENV *env; 97 DB_TXN *txnid; 98 const char *fmt; 99 va_dcl 100#endif 101{ 102 va_list ap; 103 int ret; 104 105#ifdef STDC_HEADERS 106 va_start(ap, fmt); 107#else 108 va_start(ap); 109#endif 110 ret = __log_printf_int(env, txnid, fmt, ap); 111 va_end(ap); 112 113 return (ret); 114} 115 116/* 117 * __log_printf_int -- 118 * Write a printf-style format string into the DB log (internal). 119 */ 120static int 121__log_printf_int(env, txnid, fmt, ap) 122 ENV *env; 123 DB_TXN *txnid; 124 const char *fmt; 125 va_list ap; 126{ 127 DBT opdbt, msgdbt; 128 DB_LSN lsn; 129 char __logbuf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ 130 131 if (!DBENV_LOGGING(env)) { 132 __db_errx(env, "Logging not currently permitted"); 133 return (EAGAIN); 134 } 135 136 memset(&opdbt, 0, sizeof(opdbt)); 137 opdbt.data = "DIAGNOSTIC"; 138 opdbt.size = sizeof("DIAGNOSTIC") - 1; 139 140 memset(&msgdbt, 0, sizeof(msgdbt)); 141 msgdbt.data = __logbuf; 142 msgdbt.size = (u_int32_t)vsnprintf(__logbuf, sizeof(__logbuf), fmt, ap); 143 144 return (__db_debug_log( 145 env, txnid, &lsn, 0, &opdbt, -1, &msgdbt, NULL, 0)); 146} 147