core: new API libusb_set_log_cb() to redirect global and per context log messages to the provided log handling function

Closes #486

Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
This commit is contained in:
dmitrykos
2018-10-23 21:05:25 +03:00
committed by Nathan Hjelm
parent 270bef4002
commit f74c7f5398
5 changed files with 87 additions and 2 deletions

View File

@@ -51,6 +51,9 @@ static const struct libusb_version libusb_version_internal =
static int default_context_refcnt = 0;
static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
static struct timespec timestamp_origin = { 0, 0 };
#ifndef USE_SYSTEM_LOGGING_FACILITY
static libusb_log_cb log_handler = NULL;
#endif
usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER;
struct list_head active_contexts_list;
@@ -424,6 +427,7 @@ if (cfg != desired)
* - libusb_set_auto_detach_kernel_driver()
* - libusb_set_configuration()
* - libusb_set_debug()
* - libusb_set_log_cb()
* - libusb_set_interface_alt_setting()
* - libusb_set_iso_packet_lengths()
* - libusb_set_option()
@@ -2025,6 +2029,49 @@ void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level)
#endif
}
/** \ingroup libusb_lib
* Set log handler.
*
* libusb will redirect its log messages to the provided callback function.
* libusb supports redirection of per context and global log messages.
* Log messages sent to the context will be sent to the global log handler too.
*
* If libusb is compiled without message logging or USE_SYSTEM_LOGGING_FACILITY
* is defined then global callback function will never be called.
* If ENABLE_DEBUG_LOGGING is defined then per context callback function will
* never be called.
*
* \param ctx context on which to assign log handler, or NULL for the default
* context. Parameter ignored if only LIBUSB_LOG_CB_GLOBAL mode is requested.
* \param cb pointer to the callback function, or NULL to stop log
* messages redirection
* \param mode mode of callback function operation. Several modes can be
* selected for a single callback function, see \ref libusb_log_cb_mode for
* a description.
* \see libusb_log_cb, libusb_log_cb_mode
*/
void API_EXPORTED libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb,
int mode)
{
#if !defined(USE_SYSTEM_LOGGING_FACILITY)
if (mode & LIBUSB_LOG_CB_GLOBAL) {
log_handler = cb;
}
#endif
#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
if (mode & LIBUSB_LOG_CB_CONTEXT) {
USBI_GET_CONTEXT(ctx);
ctx->log_handler = cb;
}
#else
UNUSED(ctx);
#if defined(USE_SYSTEM_LOGGING_FACILITY)
UNUSED(cb);
UNUSED(mode);
#endif
#endif
}
/** \ingroup libusb_lib
* Set an option in the library.
*
@@ -2393,7 +2440,11 @@ static void usbi_log_str(enum libusb_log_level level, const char *str)
fputs(str, stderr);
#endif
#else
fputs(str, stderr);
/* Global log handler */
if (log_handler != NULL)
log_handler(NULL, level, str);
else
fputs(str, stderr);
#endif /* USE_SYSTEM_LOGGING_FACILITY */
UNUSED(level);
}
@@ -2494,6 +2545,12 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
strcpy(buf + header_len + text_len, USBI_LOG_LINE_END);
usbi_log_str(level, buf);
/* Per context log handler */
#ifndef ENABLE_DEBUG_LOGGING
if (ctx && ctx->log_handler)
ctx->log_handler(ctx, level, buf);
#endif
}
void usbi_log(struct libusb_context *ctx, enum libusb_log_level level,

View File

@@ -148,6 +148,8 @@ EXPORTS
libusb_set_configuration@8 = libusb_set_configuration
libusb_set_debug
libusb_set_debug@8 = libusb_set_debug
libusb_set_log_cb
libusb_set_log_cb@12 = libusb_set_log_cb
libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
libusb_set_option

View File

@@ -1294,10 +1294,35 @@ enum libusb_log_level {
LIBUSB_LOG_LEVEL_DEBUG = 4,
};
/** \ingroup libusb_lib
* Log callback mode.
* \see libusb_set_log_cb()
*/
enum libusb_log_cb_mode {
/** Callback function handling all log mesages. */
LIBUSB_LOG_CB_GLOBAL = 1 << 0,
/** Callback function handling context related log mesages. */
LIBUSB_LOG_CB_CONTEXT = 1 << 1
};
/** \ingroup libusb_lib
* Callback function for handling log messages.
* \param ctx the context which is related to the log message, or NULL if it
* is a global log message
* \param level the log level, see \ref libusb_log_level for a description
* \param str the log message
* \see libusb_set_log_cb()
*/
typedef void (LIBUSB_CALL *libusb_log_cb)(libusb_context *ctx,
enum libusb_log_level level, const char *str);
int LIBUSB_CALL libusb_init(libusb_context **ctx);
void LIBUSB_CALL libusb_exit(libusb_context *ctx);
LIBUSB_DEPRECATED_FOR(libusb_set_option)
void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level);
void LIBUSB_CALL libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, int mode);
const struct libusb_version * LIBUSB_CALL libusb_get_version(void);
int LIBUSB_CALL libusb_has_capability(uint32_t capability);
const char * LIBUSB_CALL libusb_error_name(int errcode);

View File

@@ -293,6 +293,7 @@ struct libusb_context {
#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
enum libusb_log_level debug;
int debug_fixed;
libusb_log_cb log_handler;
#endif
/* internal event pipe, used for signalling occurrence of an internal event. */

View File

@@ -1 +1 @@
#define LIBUSB_NANO 11318
#define LIBUSB_NANO 11319