diff --git a/include/tss2/tss2_common.h b/include/tss2/tss2_common.h index 082883f52a..ef95578278 100644 --- a/include/tss2/tss2_common.h +++ b/include/tss2/tss2_common.h @@ -39,6 +39,10 @@ struct TSS2_ABI_VERSION { #define TSS2_ABI_VERSION_CURRENT {1, 2, 1, 108} +/* TODO: Maybe this is better in tss2_log.h? */ +#include +typedef void (*TSS2_LOG_HANDLER)(const char *msg, size_t size); + /* * Return Codes */ diff --git a/src/util/log.c b/src/util/log.c index 76899eb19d..e28f451416 100644 --- a/src/util/log.c +++ b/src/util/log.c @@ -2,6 +2,7 @@ #include #endif +#include #include #include #include @@ -182,32 +183,55 @@ doLogBlob(log_level loglevel, const char *module, log_level logdefault, } } +static void do_default_log(const char *msg, size_t size) +{ + FILE *logfile = getLogFile(); + fwrite(msg, size, 1, logfile); + fflush(logfile); +} + +static TSS2_LOG_HANDLER log_cb = do_default_log; + +TSS2_LOG_HANDLER set_log_handler(TSS2_LOG_HANDLER new_handler) +{ + TSS2_LOG_HANDLER old = log_cb; + log_cb = new_handler; + return old; +} + void doLog(log_level loglevel, const char *module, log_level logdefault, log_level *status, const char *file, const char *func, int line, const char *msg, ...) { - FILE *logfile; - if (unlikely(*status == LOGLEVEL_UNDEFINED)) - *status = getLogLevel(module, logdefault); - - if (loglevel > *status) + /* No logger set, skip */ + if (!log_cb) { return; + /* Logger is default, so check the level */ + } else if (log_cb == do_default_log) { + + if (unlikely(*status == LOGLEVEL_UNDEFINED)) + *status = getLogLevel(module, logdefault); + + if (loglevel > *status) + return; + } + + /* Any set logger gets called */ + char fmt[1024]; + char buf[4096]; - int size = snprintf(NULL, 0, "%s:%s:%s:%d:%s() %s \n", - log_strings[loglevel], module, file, line, func, msg); - char fmt[size+1]; snprintf(fmt, sizeof(fmt), "%s:%s:%s:%d:%s() %s \n", log_strings[loglevel], module, file, line, func, msg); va_list vaargs; va_start(vaargs, msg); - logfile = getLogFile(); - vfprintf (logfile, fmt, + int rc = vsnprintf (buf, sizeof(buf), fmt, /* log_strings[loglevel], module, file, func, line, */ vaargs); - fflush(logfile); + assert(rc > 0); + log_cb(buf, (size_t)rc); va_end(vaargs); } diff --git a/src/util/log.h b/src/util/log.h index 75ed7191ad..0acd2cbe70 100644 --- a/src/util/log.h +++ b/src/util/log.h @@ -146,6 +146,8 @@ static log_level LOGMODULE_status COMPILER_ATTR(unused) = LOGLEVEL_UNDEFINED; #define LOGBLOB_TRACE(FORMAT, ...) {} #endif +TSS2_LOG_HANDLER set_log_handler(TSS2_LOG_HANDLER new_handler); + void doLog(log_level loglevel, const char *module, log_level logdefault, log_level *status,