summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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));