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.
This commit is contained in:
Jef Driesen 2012-08-19 23:15:46 +02:00
parent 43cd111198
commit 3311960795
3 changed files with 49 additions and 0 deletions

View File

@ -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.

View File

@ -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 */

View File

@ -24,6 +24,10 @@
#include <stdarg.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#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);
}