diff --git a/lib/arch/CArchAppUtilWindows.cpp b/lib/arch/CArchAppUtilWindows.cpp index 872ed3c6..e3567d0e 100644 --- a/lib/arch/CArchAppUtilWindows.cpp +++ b/lib/arch/CArchAppUtilWindows.cpp @@ -20,6 +20,7 @@ #include "CApp.h" #include "LogOutputters.h" #include "CMSWindowsScreen.h" +#include "XSynergy.h" #include #include @@ -189,7 +190,7 @@ exitPause(int code) int c = _getch(); } - exit(code); + throw XExitApp(code); } static diff --git a/lib/synergy/CApp.cpp b/lib/synergy/CApp.cpp index cd69aea5..998ab0cd 100644 --- a/lib/synergy/CApp.cpp +++ b/lib/synergy/CApp.cpp @@ -21,6 +21,7 @@ #include "XArch.h" #include "CArchMiscWindows.h" #include "LogOutputters.h" +#include "XSynergy.h" #include #include @@ -230,34 +231,31 @@ CApp::run(int argc, char** argv, CreateTaskBarReceiverFunc createTaskBarReceiver // create an instance of log CLOG; + + // HACK: fail by default (saves us setting result in each catch) + int result = kExitFailed; - int result; try { result = ARCH->run(argc, argv, createTaskBarReceiver); } + catch (XExitApp& e) { + LOG((CLOG_WARN "Forced exit: %s\n", e.what())); + } catch (XBase& e) { - LOG((CLOG_CRIT "Uncaught exception: %s\n", e.what())); - result = kExitFailed; + LOG((CLOG_CRIT "Exception: %s\n", e.what())); } catch (XArch& e) { - LOG((CLOG_CRIT "Initialization failed: %s" BYE, e.what().c_str(), argsBase().m_pname)); - result = kExitFailed; + LOG((CLOG_CRIT "Init failed: %s" BYE, e.what().c_str(), argsBase().m_pname)); } catch (std::exception& e) { - LOG((CLOG_CRIT "Uncaught exception: %s\n", e.what())); - result = kExitFailed; + LOG((CLOG_CRIT "Exception: %s\n", e.what())); } catch (...) { - LOG((CLOG_CRIT "Uncaught exception: \n")); - result = kExitFailed; + LOG((CLOG_CRIT "An unexpected exception occurred.\n")); } delete CLOG; - - // not sure i like what's going on here; m_bye could call exit, but it also does - // some other stuff - if we don't return then we get compiler warning (and it's - // not good practice anyway), but the return will never get hit. - m_bye(result); + return result; } diff --git a/lib/synergy/XSynergy.cpp b/lib/synergy/XSynergy.cpp index 1e19945f..7a4f1a96 100644 --- a/lib/synergy/XSynergy.cpp +++ b/lib/synergy/XSynergy.cpp @@ -102,3 +102,28 @@ XUnknownClient::getWhat() const throw() { return format("XUnknownClient", "unknown client %{1}", m_name.c_str()); } + + +// +// XExitApp +// + +XExitApp::XExitApp(int code) : + m_code(code) +{ + // do nothing +} + +int +XExitApp::getCode() const throw() +{ + return m_code; +} + +CString +XExitApp::getWhat() const throw() +{ + return format( + "XExitApp", "exiting with code %{1}", + CStringUtil::print("%d", m_code).c_str()); +} diff --git a/lib/synergy/XSynergy.h b/lib/synergy/XSynergy.h index 23131194..4dce6c2a 100644 --- a/lib/synergy/XSynergy.h +++ b/lib/synergy/XSynergy.h @@ -102,4 +102,24 @@ private: CString m_name; }; +//! Generic exit eception +/*! +Thrown when we want to abort, with the opportunity to clean up. This is a +little bit of a hack, but it's a better way of exiting, than just calling +exit(int). +*/ +class XExitApp : public XSynergy { +public: + XExitApp(int code); + + //! Get the exit code + int getCode() const throw(); + +protected: + virtual CString getWhat() const throw(); + +private: + int m_code; +}; + #endif