summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/extern.h1
-rw-r--r--include/modules.h8
-rw-r--r--include/services.h17
-rw-r--r--include/sockets.h6
-rw-r--r--modules/core/os_restart.cpp3
-rw-r--r--modules/core/os_shutdown.cpp3
-rw-r--r--modules/core/os_update.cpp2
-rw-r--r--src/init.cpp56
-rw-r--r--src/main.cpp98
-rw-r--r--src/sockets.cpp14
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> &params)
{
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();
}