Fix #4524: Initialize with cleanup handler

Use singleton initializer and register cleanup handler for logger.
This commit is contained in:
Armin Novak 2018-04-03 09:59:42 +02:00
parent e03333477a
commit e1b53a282f

View File

@ -28,6 +28,7 @@
#include <winpr/print.h>
#include <winpr/debug.h>
#include <winpr/environment.h>
#include <winpr/wlog.h>
#if defined(ANDROID)
#include <android/log.h>
@ -36,7 +37,6 @@
#include "wlog.h"
struct _wLogFilter
{
DWORD Level;
@ -66,12 +66,99 @@ LPCSTR WLOG_LEVELS[7] =
"OFF"
};
static INIT_ONCE _WLogInitialized = INIT_ONCE_STATIC_INIT;
static DWORD g_FilterCount = 0;
static wLogFilter* g_Filters = NULL;
static wLog* g_RootLog = NULL;
static wLog* WLog_New(LPCSTR name, wLog* rootLogger);
static void WLog_Free(wLog* log);
static LONG WLog_GetFilterLogLevel(wLog* log);
static int WLog_ParseLogLevel(LPCSTR level);
static BOOL WLog_ParseFilter(wLogFilter* filter, LPCSTR name);
static BOOL WLog_ParseFilters(void);
static void WLog_Uninit_(void)
{
DWORD index;
wLog* child = NULL;
wLog* root = g_RootLog;
if (!root)
return;
for (index = 0; index < root->ChildrenCount; index++)
{
child = root->Children[index];
WLog_Free(child);
}
WLog_Free(root);
g_RootLog = NULL;
}
static BOOL CALLBACK WLog_InitializeRoot(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
{
char* env;
DWORD nSize;
DWORD logAppenderType;
LPCSTR appender = "WLOG_APPENDER";
if (!(g_RootLog = WLog_New("", NULL)))
return FALSE;
g_RootLog->IsRoot = TRUE;
WLog_ParseFilters();
logAppenderType = WLOG_APPENDER_CONSOLE;
nSize = GetEnvironmentVariableA(appender, NULL, 0);
if (nSize)
{
env = (LPSTR) malloc(nSize);
if (!env)
goto fail;
if (GetEnvironmentVariableA(appender, env, nSize) != nSize - 1)
{
fprintf(stderr, "%s environment variable modified in my back", appender);
free(env);
goto fail;
}
if (_stricmp(env, "CONSOLE") == 0)
logAppenderType = WLOG_APPENDER_CONSOLE;
else if (_stricmp(env, "FILE") == 0)
logAppenderType = WLOG_APPENDER_FILE;
else if (_stricmp(env, "BINARY") == 0)
logAppenderType = WLOG_APPENDER_BINARY;
#ifdef HAVE_SYSLOG_H
else if (_stricmp(env, "SYSLOG") == 0)
logAppenderType = WLOG_APPENDER_SYSLOG;
#endif /* HAVE_SYSLOG_H */
#ifdef HAVE_JOURNALD_H
else if (_stricmp(env, "JOURNALD") == 0)
logAppenderType = WLOG_APPENDER_JOURNALD;
#endif
else if (_stricmp(env, "UDP") == 0)
logAppenderType = WLOG_APPENDER_UDP;
free(env);
}
if (!WLog_SetLogAppenderType(g_RootLog, logAppenderType))
goto fail;
atexit(WLog_Uninit_);
return TRUE;
fail:
free(g_RootLog);
g_RootLog = NULL;
return FALSE;
}
static BOOL log_recursion(LPCSTR file, LPCSTR fkt, int line)
{
@ -121,7 +208,7 @@ static BOOL log_recursion(LPCSTR file, LPCSTR fkt, int line)
return TRUE;
}
BOOL WLog_Write(wLog* log, wLogMessage* message)
static BOOL WLog_Write(wLog* log, wLogMessage* message)
{
BOOL status;
wLogAppender* appender;
@ -153,7 +240,7 @@ BOOL WLog_Write(wLog* log, wLogMessage* message)
return status;
}
BOOL WLog_WriteData(wLog* log, wLogMessage* message)
static BOOL WLog_WriteData(wLog* log, wLogMessage* message)
{
BOOL status;
wLogAppender* appender;
@ -185,7 +272,7 @@ BOOL WLog_WriteData(wLog* log, wLogMessage* message)
return status;
}
BOOL WLog_WriteImage(wLog* log, wLogMessage* message)
static BOOL WLog_WriteImage(wLog* log, wLogMessage* message)
{
BOOL status;
wLogAppender* appender;
@ -217,7 +304,7 @@ BOOL WLog_WriteImage(wLog* log, wLogMessage* message)
return status;
}
BOOL WLog_WritePacket(wLog* log, wLogMessage* message)
static BOOL WLog_WritePacket(wLog* log, wLogMessage* message)
{
BOOL status;
wLogAppender* appender;
@ -556,6 +643,7 @@ BOOL WLog_ParseFilters(void)
if (GetEnvironmentVariableA(filter, env, nSize) == nSize - 1)
res = WLog_AddStringLogFilters(env);
free(env);
return res;
}
@ -603,7 +691,7 @@ LONG WLog_GetFilterLogLevel(wLog* log)
return log->FilterLevel;
}
BOOL WLog_ParseName(wLog* log, LPCSTR name)
static BOOL WLog_ParseName(wLog* log, LPCSTR name)
{
char* p;
int count;
@ -684,7 +772,6 @@ wLog* WLog_New(LPCSTR name, wLog* rootLogger)
else
{
LPCSTR level = "WLOG_LEVEL";
log->Level = WLOG_INFO;
nSize = GetEnvironmentVariableA(level, NULL, 0);
@ -741,75 +828,15 @@ void WLog_Free(wLog* log)
}
}
static wLog* g_RootLog = NULL;
wLog* WLog_GetRoot(void)
{
char* env;
DWORD nSize;
DWORD logAppenderType;
if (!g_RootLog)
{
LPCSTR appender = "WLOG_APPENDER";
if (!(g_RootLog = WLog_New("", NULL)))
return NULL;
g_RootLog->IsRoot = TRUE;
WLog_ParseFilters();
logAppenderType = WLOG_APPENDER_CONSOLE;
nSize = GetEnvironmentVariableA(appender, NULL, 0);
if (nSize)
{
env = (LPSTR) malloc(nSize);
if (!env)
goto fail;
if (GetEnvironmentVariableA(appender, env, nSize) != nSize - 1)
{
fprintf(stderr, "%s environment variable modified in my back", appender);
free(env);
goto fail;
}
if (_stricmp(env, "CONSOLE") == 0)
logAppenderType = WLOG_APPENDER_CONSOLE;
else if (_stricmp(env, "FILE") == 0)
logAppenderType = WLOG_APPENDER_FILE;
else if (_stricmp(env, "BINARY") == 0)
logAppenderType = WLOG_APPENDER_BINARY;
#ifdef HAVE_SYSLOG_H
else if (_stricmp(env, "SYSLOG") == 0)
logAppenderType = WLOG_APPENDER_SYSLOG;
#endif /* HAVE_SYSLOG_H */
#ifdef HAVE_JOURNALD_H
else if (_stricmp(env, "JOURNALD") == 0)
logAppenderType = WLOG_APPENDER_JOURNALD;
#endif
else if (_stricmp(env, "UDP") == 0)
logAppenderType = WLOG_APPENDER_UDP;
free(env);
}
if (!WLog_SetLogAppenderType(g_RootLog, logAppenderType))
goto fail;
}
if (!InitOnceExecuteOnce(&_WLogInitialized, WLog_InitializeRoot, NULL, NULL))
return NULL;
return g_RootLog;
fail:
free(g_RootLog);
g_RootLog = NULL;
return NULL;
}
BOOL WLog_AddChild(wLog* parent, wLog* child)
static BOOL WLog_AddChild(wLog* parent, wLog* child)
{
if (parent->ChildrenCount >= parent->ChildrenSize)
{
@ -848,7 +875,7 @@ BOOL WLog_AddChild(wLog* parent, wLog* child)
return TRUE;
}
wLog* WLog_FindChild(LPCSTR name)
static wLog* WLog_FindChild(LPCSTR name)
{
DWORD index;
wLog* root;
@ -904,21 +931,6 @@ BOOL WLog_Init(void)
BOOL WLog_Uninit(void)
{
DWORD index;
wLog* child = NULL;
wLog* root = g_RootLog;
if (!root)
return FALSE;
for (index = 0; index < root->ChildrenCount; index++)
{
child = root->Children[index];
WLog_Free(child);
}
WLog_Free(root);
g_RootLog = NULL;
return TRUE;
}