From 3b381609dddb8f4f9c3668681e4e475501b3f38f Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 23 May 2010 11:45:32 +0200 Subject: removed FormatMessage/Win32 macro from log.h and added a more portable wolf_system_error_msg in errors module --- include/wolf/errors.h | 13 +++++++++++++ include/wolf/library/loader.h | 2 +- include/wolf/log/log.h | 28 ---------------------------- src/errors.c | 42 ++++++++++++++++++++++++++++++++++++++++-- src/library/loader.c | 2 +- src/service/service.c | 30 +++++++++++++++--------------- tests/library/test_loader.c | 2 +- tests/log/test_log.c | 6 +++--- 8 files changed, 74 insertions(+), 51 deletions(-) diff --git a/include/wolf/errors.h b/include/wolf/errors.h index 96b6e2f..c33d619 100644 --- a/include/wolf/errors.h +++ b/include/wolf/errors.h @@ -60,6 +60,19 @@ typedef enum { */ char *wolf_error_msg( const wolf_error_t error, char *buf, size_t buflen ); +/** + * Converts the last system error into a human readable message. + * On Windows this is done with FormatMessage and GetLastError, on + * Unix with strerror_r and errno. + * + * @param error the error to retrieve the textual representation for + * @param buf the buffer which will hold the error message + * @param buflen the size of the buffer + * + * @returns a pointer to buf for convenience + */ +char *wolf_system_error_msg( char *buf, size_t buflen ); + #ifdef __cplusplus } #endif diff --git a/include/wolf/library/loader.h b/include/wolf/library/loader.h index 437fa1b..b62b350 100644 --- a/include/wolf/library/loader.h +++ b/include/wolf/library/loader.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2010 Andreas Baumann + Copyright (C) 2008 Andreas Baumann This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/include/wolf/log/log.h b/include/wolf/log/log.h index 78e2b63..e8f1878 100644 --- a/include/wolf/log/log.h +++ b/include/wolf/log/log.h @@ -288,34 +288,6 @@ void wolf_log_reopenlogtoeventlog( void ); */ void wolf_log( wolf_log_level_t level, int category_id, int message_id, const char *format, ... ); -#ifdef _WIN32 - -#define WOLF_LOG_GET_LAST_ERROR( last_error, errbuf, errbuf_size ) \ -{ \ - LPVOID wolf_log_errbuf; \ - DWORD wolf_log_buf_size; \ - DWORD wolf_log_res; \ - \ - wolf_log_res = FormatMessage( \ - FORMAT_MESSAGE_ALLOCATE_BUFFER | \ - FORMAT_MESSAGE_FROM_SYSTEM | \ - FORMAT_MESSAGE_IGNORE_INSERTS | \ - FORMAT_MESSAGE_MAX_WIDTH_MASK, \ - NULL, /* message is from system */ \ - last_error, /* there is a message with that id */ \ - 0, /* default language preference */ \ - (LPTSTR)&wolf_log_errbuf,/* buffer allocated internally with LocalAlloc */ \ - 0, /* minimum allocation size */ \ - NULL ); /* no arguments */ \ - \ - if( wolf_log_res == 0 ) { \ - strlcpy( errbuf, _( "No message available" ), errbuf_size ); \ - } \ - \ - strlcpy( errbuf, wolf_log_errbuf, errbuf_size ); \ -} -#endif - #ifdef __cplusplus } #endif diff --git a/src/errors.c b/src/errors.c index 5de1c6b..efd3f15 100644 --- a/src/errors.c +++ b/src/errors.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2010 Andreas Baumann + Copyright (C) 2008 Andreas Baumann This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,7 +18,12 @@ #include "errors.h" #include "port/gettext.h" /* for localization */ -#include "port/string.h" /* for strncpy */ +#include "port/string.h" /* for strncpy, strerror_r */ + +#if defined _WIN32 +#define WIN32_MEAN_AND_LEAN +#include +#endif /* defined _WIN32 */ char *wolf_error_msg( const wolf_error_t error, char *buf, size_t buflen ) { switch( error ) { @@ -61,3 +66,36 @@ char *wolf_error_msg( const wolf_error_t error, char *buf, size_t buflen ) { return buf; } +char *wolf_system_error_msg( char *buf, size_t buflen ) { +#ifdef _WIN32 + LPTSTR errbuf; + DWORD errbuf_len; + DWORD res; + DWORD last_error; + + last_error = GetLastError( ); + + res = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, /* message is from system */ + last_error, /* there is a message with that id */ + 0, /* default language preference */ + (LPTSTR)&errbuf, /* buffer allocated internally with LocalAlloc */ + 0, /* minimum allocation size */ + NULL ); /* no arguments */ + + if( res == 0 ) { + strlcpy( buf, _( "No message available" ), buflen ); + } else { + strlcpy( buf, errbuf, buflen ); + LocalFree( errbuf ); + } + + return buf; +#else + (void)strerror_r( errno, buf, buflen ); +#endif +} diff --git a/src/library/loader.c b/src/library/loader.c index 2f91278..106df7f 100644 --- a/src/library/loader.c +++ b/src/library/loader.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2010 Andreas Baumann + Copyright (C) 2008 Andreas Baumann This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/service/service.c b/src/service/service.c index 3b30c55..e63ce11 100644 --- a/src/service/service.c +++ b/src/service/service.c @@ -54,7 +54,7 @@ wolf_error_t wolf_service_install( wolf_service_params_t params ) { SC_MANAGER_ALL_ACCESS ); if( scm == NULL ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_OPEN_SCM_FOR_INSTALL, _( "Unable to open the service control manager to register service '%s': %s (%d)" ), params.service_name, errbuf, GetLastError( ) ); @@ -68,7 +68,7 @@ wolf_error_t wolf_service_install( wolf_service_params_t params ) { MAX_PATH ); if( res == MAX_PATH ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_GET_PATH_OF_BINARY, _( "Unable to get full path of the binary of service '%s': %s (%d)" ), params.service_name, errbuf, GetLastError( ) ); @@ -93,7 +93,7 @@ wolf_error_t wolf_service_install( wolf_service_params_t params ) { NULL ); if( service == NULL ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_CREATE_SERVICE, _( "Unable to create service '%s': %s (%d)" ), params.service_name, errbuf, GetLastError( ) ); @@ -105,7 +105,7 @@ wolf_error_t wolf_service_install( wolf_service_params_t params ) { descr.lpDescription = (LPTSTR)params.service_description; rt = ChangeServiceConfig2( service, SERVICE_CONFIG_DESCRIPTION, &descr ); if( !rt ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_SET_SERVICE_DESCRIPTION, _( "Unable to set description of service '%s': %s (%d)" ), params.service_name, errbuf, GetLastError( ) ); @@ -141,7 +141,7 @@ wolf_error_t wolf_service_remove( LPCTSTR service_name ) { SC_MANAGER_ALL_ACCESS ); if( scm == NULL ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_OPEN_SCM_FOR_UNINSTALL, _( "Unable to open the service control manager to uninstall '%s': %s (%d)" ), service_name, errbuf, GetLastError( ) ); @@ -152,7 +152,7 @@ wolf_error_t wolf_service_remove( LPCTSTR service_name ) { service = OpenService( scm, service_name, SERVICE_ALL_ACCESS ); if( service == NULL ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_OPEN_SERVICE, _( "Unable to open service '%s': %s (%d)" ), service_name, errbuf, GetLastError( ) ); @@ -162,7 +162,7 @@ wolf_error_t wolf_service_remove( LPCTSTR service_name ) { res = DeleteService( service ); if( res == 0 ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_DELETE_SERVICE, _( "Unable to uninstall service '%s': %s (%d)" ), service_name, errbuf, GetLastError( ) ); @@ -256,7 +256,7 @@ static void wolf_service_report_status( DWORD current_state, res = SetServiceStatus( service_status_handle, &service_status ); if( !res ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_REPORT_STATUS, _( "Unable to report state '%s' (%d) of service '%s' to SCM '%s (%d)" ), wolf_service_state_to_str( current_state ), current_state, @@ -312,7 +312,7 @@ void WINAPI wolf_service_main( DWORD argc, LPTSTR *argv ) { SERVICE_NAME, wolf_service_ctrl_handler ); if( service_status_handle == 0 ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_REGISTER_SERVICE_CTRL_HANDLER, _( "Unable to register service control handler function for service '%s': %s (%d)" ), SERVICE_NAME, errbuf, GetLastError( ) ); @@ -333,7 +333,7 @@ void WINAPI wolf_service_main( DWORD argc, LPTSTR *argv ) { FALSE, /* not signalled */ NULL ); /* no name */ if( service_stop_event == NULL ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_CREATE_STOP_EVENT, _( "Unable to create the stop event for service '%s': %s (%d)" ), SERVICE_NAME, errbuf, GetLastError( ) ); @@ -369,7 +369,7 @@ wolf_service_event_t wolf_service_events_suspend_console( int timeout, wolf_erro return WOLF_SERVICE_NO_EVENT; default: - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_WAIT_FOR_OBJECT_FAILED, _( "Waiting for events in the service '%s' failed: %s (%d)" ), SERVICE_NAME, errbuf, GetLastError( ) ); @@ -395,7 +395,7 @@ wolf_service_event_t wolf_service_events_suspend_service( int timeout, wolf_erro return WOLF_SERVICE_NO_EVENT; default: - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_WAIT_FOR_OBJECT_FAILED, _( "Waiting for events in the service '%s' failed: %s (%d)" ), SERVICE_NAME, errbuf, GetLastError( ) ); @@ -457,7 +457,7 @@ wolf_error_t wolf_service_start_console( LPTSTR service_name, FALSE, /* not signalled */ NULL ); /* no name */ if( service_stop_event == NULL ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_CREATE_STOP_EVENT, _( "Unable to create the stop event for service '%s': %s (%d)" ), SERVICE_NAME, errbuf, GetLastError( ) ); @@ -467,7 +467,7 @@ wolf_error_t wolf_service_start_console( LPTSTR service_name, /* catch console events for proper termination of the service in console mode */ res = SetConsoleCtrlHandler( wolf_service_console_ctrl_handler, TRUE ); if( !res ) { - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_REGISTER_CONSOLE_CTRL_HANDLER, _( "Unable to register the console control handler for foreground service '%s': %s (%d)" ), service_name, errbuf, GetLastError( ) ); @@ -508,7 +508,7 @@ wolf_error_t wolf_service_start( LPTSTR service_name, return WOLF_ERR_INVALID_STATE; } - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_SERVICE, WOLF_MSG_SERVICE_CANT_DISPATCH_SERVICE, _( "Unable to dispatch service '%s': %s (%d)" ), service_name, errbuf, GetLastError( ) ); diff --git a/tests/library/test_loader.c b/tests/library/test_loader.c index 50ed8db..bda32b3 100644 --- a/tests/library/test_loader.c +++ b/tests/library/test_loader.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2010 Andreas Baumann + Copyright (C) 2008 Andreas Baumann This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/tests/log/test_log.c b/tests/log/test_log.c index 3d6ab97..50a3904 100644 --- a/tests/log/test_log.c +++ b/tests/log/test_log.c @@ -76,14 +76,14 @@ int main( void ) { /* different ways of handling system errors (errno, GetLastError) */ errno = 5; - (void)strerror_r( errno, errbuf, 512 ); + (void)wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_TEST_LOG, WOLF_MSG_TEST_LOG_MSG7, - "A system error occured during %s phase: %s (%d)", "fla", + "A Unix system error occured during %s phase: %s (%d)", "fla", errbuf, errno ); #ifdef _WIN32 SetLastError( 18 ); - WOLF_LOG_GET_LAST_ERROR( GetLastError( ), errbuf, 512 ); + (void)wolf_system_error_msg( errbuf, 512 ); wolf_log( WOLF_LOG_ERR, WOLF_CATEGORY_TEST_LOG, WOLF_MSG_TEST_LOG_MSG8, "A Windows error occured during %s phase: %s (%d)", "fla", errbuf, GetLastError( ) ); -- cgit v1.2.3-54-g00ecf