0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-26 00:32:35 +01:00

ircd: Improve restart-assist to convey different program options.

This commit is contained in:
Jason Volk 2020-09-30 22:01:21 -07:00
parent fecd009ffb
commit b7b2c44973
4 changed files with 58 additions and 10 deletions

View file

@ -108,6 +108,7 @@ const char *const usererrstr
***
)"};
[[noreturn]] static void do_restart(char *const *const &argv, char *const *const &envp);
static bool startup_checks();
static void applyargs();
static void enable_coredumps();
@ -375,7 +376,7 @@ noexcept try
// The restart flag can be set by the console command "restart" which
// calls ircd::quit() to clean break from the run() loop.
if(ircd::restart)
ircd::syscall(::execve, _argv[0], _argv, _envp);
do_restart(_argv, _envp);
return EXIT_SUCCESS;
}
@ -485,6 +486,26 @@ enable_coredumps()
}
#endif
void
do_restart(char *const *const &_argv,
char *const *const &_envp)
{
const auto args
{
ircd::replace(std::string(ircd::restart) + ' ', ' ', '\0')
};
std::vector<char *> argv{_argv[0]};
for(size_t i(0); i < args.size(); ++i)
{
argv.emplace_back(const_cast<char *>(args.data() + i));
for(; i < args.size() && args.at(i) != '\0'; ++i);
}
argv.emplace_back(nullptr);
ircd::syscall(::execve, _argv[0], argv.data(), _envp);
}
/// These operations are safe to call before ircd::init() and anytime after
/// static initialization.
void

View file

@ -114,8 +114,10 @@ namespace ircd
// Diagnostic Mode Options
extern conf::item<std::string> diagnostic;
// Restart-Assist
extern conf::item<std::string> restart;
// Operating Mode Selectors
extern conf::item<bool> restart;
extern conf::item<bool> debugmode;
extern conf::item<bool> maintenance;
extern conf::item<bool> soft_assert;

View file

@ -41,17 +41,24 @@ ircd::version_abi
"IRCd", info::versions::ABI, 0, {0, 0, 0}, ircd::info::version
};
/// Courtesy indicator; this item allows the library to indicate to the
/// embedder that they should restart their application (or reload this library
/// if available). The use-case here is for features like the `restart` command
/// in the console module. Such a command triggers a normal quit and the
/// application may exit normally; therefor the embedder should check this
/// item to perform a restart rather than exiting.
/// This item allows the library to indicate to the embedder that they should
/// restart their application (or reload this library if available). The
/// use-case here is for features like the `restart` command in the console
/// module. Such a command triggers a normal quit and the application may exit
/// normally; therefor the embedder should check this item to perform a restart
/// rather than exiting.
///
/// This item is a string to allow for different program options at restart.
/// For now this is limited to space-separated arguments without respect for
/// quoting (for now), so no arguments can have spaces.
///
/// Empty string disables restart. The name of the executable should not be
/// prefixed to the string.
decltype(ircd::restart)
ircd::restart
{
{ "name", "ircd.restart" },
{ "default", false },
{ "default", std::string{} },
{ "persist", false },
};

View file

@ -570,7 +570,25 @@ console_cmd__bt(opt &out, const string_view &line)
bool
console_cmd__restart(opt &out, const string_view &line)
{
ircd::restart.set("true");
std::string argv(line);
size_t swargs(0), posargs(0);
ircd::tokens(line, ' ', [&swargs, &posargs]
(const auto &token)
{
swargs += startswith(token, '-');
posargs += !startswith(token, '-');
});
if(!posargs)
{
argv += swargs? " "_sv: ""_sv;
argv += m::origin(m::my());
argv += ' ';
argv += m::server_name(m::my());
}
ircd::restart.set(argv);
ircd::quit();
return false;
}