From 3311960795ca30bfac4e5a3226909b0a79602bee Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 19 Aug 2012 23:15:46 +0200 Subject: [PATCH] Add a convenience function for logging system errors. The new convenience function provides a centralized and threadsafe function for logging system errors. The previous functions are deprecated and will be removed after the transition to the new context based logging. --- configure.ac | 1 + src/context-private.h | 4 ++++ src/context.c | 44 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/configure.ac b/configure.ac index 78af57b..d08f2d7 100644 --- a/configure.ac +++ b/configure.ac @@ -78,6 +78,7 @@ AC_CHECK_HEADERS([linux/serial.h]) AC_CHECK_HEADERS([IOKit/serial/ioss.h]) # Checks for library functions. +AC_FUNC_STRERROR_R AC_CHECK_FUNCS([localtime_r gmtime_r]) # Versioning. diff --git a/src/context-private.h b/src/context-private.h index 677eb09..c32fa1b 100644 --- a/src/context-private.h +++ b/src/context-private.h @@ -28,6 +28,7 @@ extern "C" { #endif /* __cplusplus */ +#define SYSERROR(context, errcode) dc_context_syserror (context, DC_LOGLEVEL_ERROR, __FILE__, __LINE__, __FUNCTION__, errcode) #define ERROR(context, ...) dc_context_log (context, DC_LOGLEVEL_ERROR, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__) #define WARNING(context, ...) dc_context_log (context, DC_LOGLEVEL_WARNING, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__) #define INFO(context, ...) dc_context_log (context, DC_LOGLEVEL_INFO, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__) @@ -36,6 +37,9 @@ extern "C" { dc_status_t dc_context_log (dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, const char *format, ...); +dc_status_t +dc_context_syserror (dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, int errcode); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/context.c b/src/context.c index 2e0c62b..45f6800 100644 --- a/src/context.c +++ b/src/context.c @@ -24,6 +24,10 @@ #include #include +#ifdef _WIN32 +#include +#endif + #include "context-private.h" struct dc_context_t { @@ -117,3 +121,43 @@ dc_context_log (dc_context_t *context, dc_loglevel_t loglevel, const char *file, return DC_STATUS_SUCCESS; } + +dc_status_t +dc_context_syserror (dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, int errcode) +{ + const char *errmsg = NULL; + +#ifdef _WIN32 + char buffer[256]; + + DWORD rc = FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errcode, 0, buffer, sizeof (buffer), NULL); + + /* Remove the CRLF and period at the end of the error message. */ + while (rc > 0 && ( + buffer[rc - 1] == '\n' || + buffer[rc - 1] == '\r' || + buffer[rc - 1] == '.')) + { + buffer[rc - 1] = '\0'; + rc--; + } + + if (rc > 0) + errmsg = buffer; +#elif defined (HAVE_STRERROR_R) + char buffer[256]; + + int rc = strerror_r (errcode, buffer, sizeof (buffer)); + if (rc == 0) + errmsg = buffer; +#else + /* Fallback to the non-threadsafe function. */ + errmsg = strerror (errcode); +#endif + + if (errmsg == NULL) + errmsg = "Unknown system error"; + + return dc_context_log (context, loglevel, file, line, function, "%s (%d)", errmsg, errcode); +}