diff options
-rw-r--r-- | include/extern.h | 1 | ||||
-rw-r--r-- | include/modules.h | 8 | ||||
-rw-r--r-- | include/services.h | 17 | ||||
-rw-r--r-- | include/sockets.h | 6 | ||||
-rw-r--r-- | modules/core/os_restart.cpp | 3 | ||||
-rw-r--r-- | modules/core/os_shutdown.cpp | 3 | ||||
-rw-r--r-- | modules/core/os_update.cpp | 2 | ||||
-rw-r--r-- | src/init.cpp | 56 | ||||
-rw-r--r-- | src/main.cpp | 98 | ||||
-rw-r--r-- | src/sockets.cpp | 14 |
10 files changed, 118 insertions, 90 deletions
diff --git a/include/extern.h b/include/extern.h index 7774c104f..97bc39d5a 100644 --- a/include/extern.h +++ b/include/extern.h @@ -115,7 +115,6 @@ E bool protocoldebug; E bool quitting; E bool restarting; E Anope::string quitmsg; -E bool save_data; E time_t start_time; E ConnectionSocket *UplinkSock; diff --git a/include/modules.h b/include/modules.h index ff0c576a0..c886e9a74 100644 --- a/include/modules.h +++ b/include/modules.h @@ -572,12 +572,6 @@ class CoreExport Module : public Extensible */ virtual void OnShutdown() { } - /** Called on signal - * @param signum The signum - * @param msg The quitmsg - */ - virtual void OnSignal(int signum, const Anope::string &msg) { } - /** Called before a nick expires * @param na The nick * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it @@ -1077,7 +1071,7 @@ enum Implementation /* Other */ I_OnReload, I_OnNewServer, I_OnPreServerConnect, I_OnServerConnect, I_OnPreUplinkSync, I_OnServerDisconnect, I_OnPreCommandRun, - I_OnPreCommand, I_OnPostCommand, I_OnRestart, I_OnShutdown, I_OnSignal, + I_OnPreCommand, I_OnPostCommand, I_OnRestart, I_OnShutdown, I_OnServerQuit, I_OnTopicUpdated, I_OnEncrypt, I_OnDecrypt, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd, diff --git a/include/services.h b/include/services.h index f329f99ef..35342e1da 100644 --- a/include/services.h +++ b/include/services.h @@ -241,6 +241,23 @@ class DatabaseException : public CoreException virtual ~DatabaseException() throw() { } }; +class Signal +{ + static std::vector<Signal *> SignalHandlers; + static void SignalHandler(int signal); + + struct sigaction action; + sig_atomic_t called; + public: + static void Process(); + + int signal; + + Signal(int s); + ~Signal(); + virtual void OnSignal() = 0; +}; + /** Debug cast to be used instead of dynamic_cast, this uses dynamic_cast * for debug builds and static_cast on releass builds to speed up the program * because dynamic_cast relies on RTTI. diff --git a/include/sockets.h b/include/sockets.h index eca2635e8..5e5ca1fde 100644 --- a/include/sockets.h +++ b/include/sockets.h @@ -254,7 +254,7 @@ class CoreExport BufferedSocket : public Socket /* Part of a message sent from the server, but not totally received */ Anope::string extrabuf; /* How much data was received from this socket */ - size_t RecvLen; + int RecvLen; public: /** Blank constructor @@ -297,12 +297,12 @@ class CoreExport BufferedSocket : public Socket /** Get the length of the read buffer * @return The length of the read buffer */ - size_t ReadBufferLen() const; + int ReadBufferLen() const; /** Get the length of the write buffer * @return The length of the write buffer */ - size_t WriteBufferLen() const; + int WriteBufferLen() const; }; class CoreExport ListenSocket : public Socket diff --git a/modules/core/os_restart.cpp b/modules/core/os_restart.cpp index 196d0a3ab..ea8f4b864 100644 --- a/modules/core/os_restart.cpp +++ b/modules/core/os_restart.cpp @@ -26,7 +26,8 @@ class CommandOSRestart : public Command { User *u = source.u; quitmsg = "RESTART command received from " + u->nick; - quitting = save_data = restarting = true; + save_databases(); + quitting = restarting = true; return MOD_CONT; } diff --git a/modules/core/os_shutdown.cpp b/modules/core/os_shutdown.cpp index 35f76f0c9..ac37fe0b8 100644 --- a/modules/core/os_shutdown.cpp +++ b/modules/core/os_shutdown.cpp @@ -26,7 +26,8 @@ class CommandOSShutdown : public Command { User *u = source.u; quitmsg = "SHUTDOWN command received from " + u->nick; - quitting = save_data = true; + save_databases(); + quitting = true; return MOD_CONT; } diff --git a/modules/core/os_update.cpp b/modules/core/os_update.cpp index 9f85d8b64..d4793c124 100644 --- a/modules/core/os_update.cpp +++ b/modules/core/os_update.cpp @@ -25,7 +25,7 @@ class CommandOSUpdate : public Command CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { source.Reply(_("Updating databases.")); - save_data = true; + save_databases(); return MOD_CONT; } diff --git a/src/init.cpp b/src/init.cpp index 7fa684336..0f3a5650d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -209,6 +209,52 @@ static void write_pidfile() /*************************************************************************/ +class SignalReload : public Signal +{ + public: + SignalReload(int sig) : Signal(sig) { } + + void OnSignal() + { + Log() << "Received SIGHUP: Saving databases & rehashing configuration"; + + save_databases(); + + ServerConfig *old_config = Config; + try + { + Config = new ServerConfig(); + FOREACH_MOD(I_OnReload, OnReload()); + delete old_config; + } + catch (const ConfigException &ex) + { + Config = old_config; + Log() << "Error reloading configuration file: " << ex.GetReason(); + } + } +}; + +class SignalExit : public Signal +{ + public: + SignalExit(int sig) : Signal(sig) { } + + void OnSignal() + { +#ifndef _WIN32 + Log() << "Received " << strsignal(this->signal) << " signal (" << this->signal << "), exiting."; + quitmsg = Anope::string("Services terminating via signal ") + strsignal(this->signal) + " (" + stringify(this->signal) + ")"; +#else + Log() << "Received signal " << this->signal << ", exiting."; + quitmsg = Anope::string("Services terminating via signal ") + stringify(this->signal); +#endif + + save_databases(); + quitting = true; + } +}; + void Init(int ac, char **av) { int started_from_term = isatty(0) && isatty(1) && isatty(2); @@ -377,14 +423,8 @@ void Init(int ac, char **av) /* Announce ourselves to the logfile. */ Log() << "Anope " << Anope::Version() << " starting up" << (debug || readonly ? " (options:" : "") << (debug ? " debug" : "") << (readonly ? " readonly" : "") << (debug || readonly ? ")" : ""); - /* Set signal handlers. Catch certain signals to let us do things or - * panic as necessary, and ignore all others. - */ -#ifndef _WIN32 - signal(SIGHUP, sighandler); -#endif - signal(SIGTERM, sighandler); - signal(SIGINT, sighandler); + static SignalReload sig_hup(SIGHUP); + static SignalExit sig_term(SIGTERM), sig_int(SIGINT); /* Initialize multi-language support */ Log(LOG_DEBUG) << "Loading Languages..."; diff --git a/src/main.cpp b/src/main.cpp index 199b3162f..4a02e532d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -61,9 +61,6 @@ bool restarting = false; /* Contains a message as to why services is terminating */ Anope::string quitmsg; -/* Should we update the databases now? */ -bool save_data = false; - /* At what time were we started? */ time_t start_time = time(NULL); @@ -83,8 +80,7 @@ class UpdateTimer : public Timer void Tick(time_t) { - if (!readonly) - save_databases(); + save_databases(); } }; @@ -212,66 +208,45 @@ void save_databases() /*************************************************************************/ -/* If we get a weird signal, come here. */ +std::vector<Signal *> Signal::SignalHandlers; -void sighandler(int signum) +void Signal::SignalHandler(int signal) { - if (quitmsg.empty()) -#ifndef _WIN32 - quitmsg = Anope::string("Services terminating via signal ") + strsignal(signum) + " (" + stringify(signum) + ")"; -#else - quitmsg = Anope::string("Services terminating via signal ") + stringify(signum); -#endif + for (unsigned i = 0, j = SignalHandlers.size(); i < j; ++i) + if (SignalHandlers[i]->signal == signal) + SignalHandlers[i]->called = true; +} - if (started) - { - switch (signum) +void Signal::Process() +{ + for (unsigned i = 0, j = SignalHandlers.size(); i < j; ++i) + if (SignalHandlers[i]->called == true) { -#ifndef _WIN32 - case SIGHUP: - { - Log() << "Received SIGHUP: Saving databases & rehashing configuration"; - - save_databases(); - - ServerConfig *old_config = Config; - try - { - Config = new ServerConfig(); - FOREACH_MOD(I_OnReload, OnReload()); - delete old_config; - } - catch (const ConfigException &ex) - { - Config = old_config; - Log() << "Error reloading configuration file: " << ex.GetReason(); - } - break; - } -#endif - case SIGINT: - case SIGTERM: - signal(signum, SIG_IGN); -#ifndef _WIN32 - signal(SIGHUP, SIG_IGN); -#endif + Signal *s = SignalHandlers[i]; + s->called = false; + s->OnSignal(); + } +} -#ifndef _WIN32 - Log() << "Received " << strsignal(signum) << " signal (" << signum << "), exiting."; -#else - Log() << "Received signal " << signum << ", exiting."; -#endif +Signal::Signal(int s) : called(false), signal(s) +{ + this->action.sa_flags = 0; + sigemptyset(&this->action.sa_mask); + this->action.sa_handler = SignalHandler; + + sigaction(s, &this->action, NULL); - save_databases(); - quitting = true; - default: - break; - } - } + SignalHandlers.push_back(this); +} - FOREACH_MOD(I_OnSignal, OnSignal(signum, quitmsg)); +Signal::~Signal() +{ + std::vector<Signal *>::iterator it = std::find(SignalHandlers.begin(), SignalHandlers.end(), this); + if (it != SignalHandlers.end()) + SignalHandlers.erase(it); } + /*************************************************************************/ /** The following comes from InspIRCd to get the full path of the Anope executable @@ -388,6 +363,10 @@ int main(int ac, char **av, char **envp) { Log(LOG_DEBUG_2) << "Top of main loop"; + /* Process signals */ + Signal::Process(); + + /* Process timers */ if (Anope::CurTime - last_check >= Config->TimeoutCheck) { TimerManager::TickTimers(Anope::CurTime); @@ -405,13 +384,6 @@ int main(int ac, char **av, char **envp) SocketEngine::Process(); } - if (save_data) - { - ircdproto->SendGlobops(NULL, "Updating databases on shutdown, please wait."); - save_databases(); - save_data = false; - } - if (restarting) { FOREACH_MOD(I_OnRestart, OnRestart()); diff --git a/src/sockets.cpp b/src/sockets.cpp index c9758cb12..f255a4edf 100644 --- a/src/sockets.cpp +++ b/src/sockets.cpp @@ -467,11 +467,15 @@ bool BufferedSocket::ProcessRead() { char tbuffer[NET_BUFSIZE] = ""; - RecvLen = this->IO->Recv(this, tbuffer, sizeof(tbuffer) - 1); - if (RecvLen == -2) + this->RecvLen = 0; + + int len = this->IO->Recv(this, tbuffer, sizeof(tbuffer) - 1); + if (len == -2) return true; - else if (RecvLen <= 0) + else if (len <= 0) return false; + + this->RecvLen = len; Anope::string sbuffer = this->extrabuf; sbuffer += tbuffer; @@ -559,7 +563,7 @@ void BufferedSocket::Write(const Anope::string &message) /** Get the length of the read buffer * @return The length of the read buffer */ -size_t BufferedSocket::ReadBufferLen() const +int BufferedSocket::ReadBufferLen() const { return RecvLen; } @@ -567,7 +571,7 @@ size_t BufferedSocket::ReadBufferLen() const /** Get the length of the write buffer * @return The length of the write buffer */ -size_t BufferedSocket::WriteBufferLen() const +int BufferedSocket::WriteBufferLen() const { return this->WriteBuffer.length(); } |