summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorattilamolnar <attilamolnar@hush.com>2012-10-21 16:47:16 +0200
committerattilamolnar <attilamolnar@hush.com>2012-10-21 16:47:53 +0200
commitbf320518c66925c8bbf50da3ddb4113d50139ed3 (patch)
tree9bd9155bf04755e81db86deacc61a10e11841e3a /src
parent569a742b9420b62a538c27fbd38a2bb8db6b9ca6 (diff)
Fix /RESTART not closing file descriptors
Fixes issue #262 reported by @MistrX
Diffstat (limited to 'src')
-rw-r--r--src/commands/cmd_restart.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/commands/cmd_restart.cpp b/src/commands/cmd_restart.cpp
index dc5507548..bdbcfed35 100644
--- a/src/commands/cmd_restart.cpp
+++ b/src/commands/cmd_restart.cpp
@@ -45,6 +45,22 @@ CmdResult CommandRestart::Handle (const std::vector<std::string>& parameters, Us
ServerInstance->SNO->WriteGlobalSno('a', "RESTART command from %s, restarting server.", user->GetFullRealHost().c_str());
ServerInstance->SendError("Server restarting.");
+
+#ifndef _WIN32
+ /* XXX: This hack sets FD_CLOEXEC on all possible file descriptors, so they're closed if the execv() below succeeds.
+ * Certainly, this is not a nice way to do things and it's slow when the fd limit is high.
+ *
+ * A better solution would be to set the close-on-exec flag for each fd we create (or create them with O_CLOEXEC),
+ * however there is no guarantee that third party libs will do the same.
+ */
+ for (int i = getdtablesize(); --i > 2;)
+ {
+ int flags = fcntl(i, F_GETFD);
+ if (flags != -1)
+ fcntl(i, F_SETFD, flags | FD_CLOEXEC);
+ }
+#endif
+
execv(ServerInstance->Config->cmdline.argv[0], ServerInstance->Config->cmdline.argv);
ServerInstance->SNO->WriteGlobalSno('a', "Failed RESTART - could not execute '%s' (%s)",
ServerInstance->Config->cmdline.argv[0], strerror(errno));