📄 application.cpp
字号:
/******************************************************************************** application.cpp: Application class*-------------------------------------------------------------------------------* (c)1999-2001 VideoLAN* $Id: application.cpp,v 1.11 2002/10/07 15:01:21 sam Exp $** Authors: Benoit Steiner <benny@via.ecp.fr>** 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 the Free Software Foundation; either version 2* of the License, or (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**-------------------------------------------------------------------------------* The C_Application class provides some core mecanisms for applications, such* as a global logging service********************************************************************************///------------------------------------------------------------------------------// Preamble//------------------------------------------------------------------------------#include "defs.h"#include <stddef.h>#include <stdlib.h>#include <stdio.h>#ifdef HAVE_OPENDIR#include <dirent.h>#endif#include <signal.h>#include <sys/types.h>#ifdef SYSLOG#include <syslog.h>#endif#include "common.h"#include "debug.h"#include "reflect.h"#include "serialization.h"#include "string.h"#include "stack.h"#include "vector.h"#include "hashtable.h"#include "buffers.h"#include "exception.h"#include "file.h"#include "stream.h"#include "parsers.h"#include "settings.h"#include "log.h"#include "library.h"#include "module.h"#include "application.h"#include "stack.cpp"#include "vector.cpp"#include "hashtable.cpp"#include "library.cpp"//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_Application* C_Application::s_pApplication = NULL;//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_Application::C_Application(const C_String& strName) : m_strName(strName){ ASSERT(s_pApplication == NULL); s_pApplication = this; m_hLog = NULL; m_pModuleManager = NULL; m_bOnStop = false; m_iLogFlags = LOG_DBGMSG;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_Application::~C_Application(){ ASSERT(this == s_pApplication); s_pApplication = NULL; delete m_pModuleManager;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Application::Init(int iArgc, char* paArg[]){ // Retrieve global configuration from cmd line and cfg file // Shortly, this step will build a properties table int iRc = RetrieveConfig(iArgc, paArg); // Init the logger if(!iRc) { C_String strLogFileSetting = m_strName + ".LogFile"; C_String strDfltLogFile = m_strName.ToLower() + ".log"; C_String strLogFile = GetSetting(strLogFileSetting, strDfltLogFile); if (strLogFile != "") { iRc |= m_cLog.Init(strLogFile); m_iLogFlags |= LOG_FILE; } } // Check if System Logging is enabled in the vls.cfg C_String strSystemLog = GetSetting(m_strName + ".SystemLog", "disable"); if (strSystemLog == "enable") m_iLogFlags |= LOG_SYSTEM; // Check if screen Logging is enabled in the vls.cfg C_String strScrLog = GetSetting(m_strName + ".ScreenLog", "enable"); if (strScrLog == "enable") m_iLogFlags |= LOG_SCR; // Register the application object by the logger if(!iRc) { m_hLog = StartLog(m_strName, m_iLogFlags ); if(!m_hLog) iRc = GEN_ERR; } // First install the signal handler if(!iRc) iRc = InstallSigHandler(); // Create the module manager m_pModuleManager = new C_ModuleManager(m_hLog); // Do application specific initialisations if(!iRc) iRc = OnAppInit(); return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Application::Run(){ return OnAppRun();}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Application::Stop(){ if(!m_bOnStop) { m_bOnStop = true; return OnAppExit(); } else return GEN_ERR;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Application::Destroy(){ int iRc = OnAppDestroy(); if(!iRc) { if(m_hLog) StopLog(m_hLog); iRc = m_cLog.End(); } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------handle C_Application::StartLog(const C_String& strClientDescr, u8 iFlags){ handle hLog = m_cLog.Register(strClientDescr, iFlags); ASSERT(hLog); // Init the syslog if (iFlags & LOG_SYSTEM) {#ifdef SYSLOG openlog("vls", LOG_NOWAIT | LOG_NDELAY | LOG_PID, LOG_USER);#endif } return hLog;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Application::StopLog(handle hLog){ ASSERT(hLog); // close the syslog if (m_iLogFlags & LOG_SYSTEM) {#ifdef SYSLOG closelog();#endif } m_cLog.Unregister(hLog);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Application::LogMsg(handle hLog, int iLevel, const C_String& strMsg){ if(hLog) { // Use the given handle to log m_cLog.Append(hLog, iLevel, strMsg); } else { // Use the application handle to log m_cLog.Append(m_hLog, iLevel, strMsg); }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Application::InstallSigHandler(){ int iRc = NO_ERR;#ifdef HAVE_SIGACTION sigset_t sSigSet; sigemptyset(&sSigSet); struct sigaction sSigAction; sSigAction.sa_mask = sSigSet; sSigAction.sa_flags = 0; //sSigAction.sa_restorer = NULL; sSigAction.sa_handler = SignalHandler; if(sigaction(SIGHUP, &sSigAction, NULL) != 0) { Log(m_hLog, LOG_ERROR, "Could not install handler for signal SIG_HUP"); iRc |= 1; } sSigAction.sa_handler = SignalHandler; if(sigaction(SIGINT, &sSigAction, NULL) != 0) { Log(m_hLog, LOG_ERROR, "Could not install handler for signal SIG_INT"); iRc |= 1; } sSigAction.sa_handler = SignalHandler; if(sigaction(SIGQUIT, &sSigAction, NULL) != 0) { Log(m_hLog, LOG_ERROR, "Could not install handler for signal SIG_QUIT"); iRc |= 1; } sSigAction.sa_handler = SignalHandler; if(sigaction(SIGPIPE, &sSigAction, NULL) != 0) { Log(m_hLog, LOG_ERROR, "Could not install handler for signal SIG_PIPE"); iRc |= 1; } sSigAction.sa_handler = SignalHandler; if(sigaction(SIGURG, &sSigAction, NULL) != 0) { Log(m_hLog, LOG_ERROR, "Could not install handler for signal SIG_URG"); iRc |= 1; } // Don't catch the signal if we are in debug mode unless we wouldn't get a core file#ifndef DEBUG sSigAction.sa_handler = SignalHandler; if(sigaction(SIGSEGV, &sSigAction, NULL) != 0) { Log(m_hLog, LOG_ERROR, "Could not install handler for signal SIG_SEGV"); iRc |= 1; }#endif sSigAction.sa_handler = SignalHandler; if(sigaction(SIGTERM, &sSigAction, NULL) != 0) { Log(m_hLog, LOG_ERROR, "Could not install handler for signal SIG_TERM"); iRc |= 1; }#endif return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Application::RetrieveConfig(int iArgc, char* paArg[]){ C_String strCfgFile; int iRc = NO_ERR; C_String strName = m_strName.ToLower() + ".cfg"; if (paArg[1]== NULL) strCfgFile = strName; else strCfgFile = C_String(paArg[1]); #ifndef _WIN32 C_File cFile(strCfgFile); if(!cFile.Exists()) { strCfgFile = CONFIG_PATH "/" + strName; #endif C_File cFile(strCfgFile); if(!cFile.Exists()) { printf("No configuration file found\n"); iRc = GEN_ERR; } #ifndef _WIN32 } #endif if(!iRc) { try { m_cSettings.Load(strCfgFile, false); } catch(E_Exception e) { printf("Could not open configuration file: \n%s", e.Dump().GetString()); iRc = GEN_ERR; } } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Application::SignalHandler(int iSignal){ C_Application* pApp = C_Application::GetApp(); ASSERT(pApp);#ifdef HAVE_SIGACTION handle hLog = pApp->m_hLog; switch(iSignal) { case SIGHUP: { Log(hLog, LOG_WARN, "Received SIGHUP: Hangup detected"); break; } case SIGINT: { Log(hLog, LOG_WARN, "Received SIGINT: Interrupt from keyboard, launching shutdown sequence..."); pApp->Stop(); break; } case SIGQUIT: { Log(hLog, LOG_WARN, "Received SIGQUIT: Quit from keyboard, launching shutdown sequence..."); pApp->Stop(); break; } case SIGTERM: { Log(hLog, LOG_WARN, "Received SIGTERM: Software termination signal, launching shutdown sequence..."); pApp->Stop(); break; } case SIGSEGV: { Log(hLog, LOG_WARN, "Received SIGSEGV: Segmentation Violation, exiting..."); exit(1); break; } case SIGPIPE: { // This signal is sent upon attempt to write on a broken stream // (such as a dead socket) Log(hLog, LOG_WARN, "Received SIGPIPE: Unexpected Broken Pipe encountered"); break; } case SIGURG: { // This signal is sent when AOB data is received on a TCP connection Log(hLog, LOG_NOTE, "Received SIGURG: unexpected AOB data received"); break; } default: { Log(hLog, LOG_NOTE, "Received signal " + iSignal); break; } }#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -