mirror of
https://github.com/matrix-construct/construct
synced 2024-09-24 17:38:54 +02:00
charybdis: Add -execute command line option; support console execute.
This commit is contained in:
parent
5b61e1d01f
commit
b832d15ad3
3 changed files with 85 additions and 8 deletions
|
@ -51,6 +51,7 @@ bool printversion;
|
||||||
bool testing_conf;
|
bool testing_conf;
|
||||||
bool cmdline;
|
bool cmdline;
|
||||||
const char *configfile;
|
const char *configfile;
|
||||||
|
const char *execute;
|
||||||
lgetopt opts[] =
|
lgetopt opts[] =
|
||||||
{
|
{
|
||||||
{ "help", nullptr, lgetopt::USAGE, "Print this text" },
|
{ "help", nullptr, lgetopt::USAGE, "Print this text" },
|
||||||
|
@ -59,6 +60,7 @@ lgetopt opts[] =
|
||||||
{ "conftest", &testing_conf, lgetopt::YESNO, "Test the configuration files and exit" },
|
{ "conftest", &testing_conf, lgetopt::YESNO, "Test the configuration files and exit" },
|
||||||
{ "debug", &ircd::debugmode, lgetopt::BOOL, "Enable options for debugging" },
|
{ "debug", &ircd::debugmode, lgetopt::BOOL, "Enable options for debugging" },
|
||||||
{ "console", &cmdline, lgetopt::BOOL, "Drop to a command line immediately after startup" },
|
{ "console", &cmdline, lgetopt::BOOL, "Drop to a command line immediately after startup" },
|
||||||
|
{ "execute", &execute, lgetopt::STRING, "Execute command lines immediately after startup" },
|
||||||
{ nullptr, nullptr, lgetopt::STRING, nullptr },
|
{ nullptr, nullptr, lgetopt::STRING, nullptr },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -144,6 +146,9 @@ try
|
||||||
if(cmdline)
|
if(cmdline)
|
||||||
console_spawn();
|
console_spawn();
|
||||||
|
|
||||||
|
if(execute)
|
||||||
|
console_execute({execute});
|
||||||
|
|
||||||
// Execution.
|
// Execution.
|
||||||
// Blocks until a clean exit from a stop() or an exception comes out of it.
|
// Blocks until a clean exit from a stop() or an exception comes out of it.
|
||||||
ios->run();
|
ios->run();
|
||||||
|
|
|
@ -30,6 +30,7 @@ extern std::unique_ptr<boost::asio::io_service> ios;
|
||||||
//
|
//
|
||||||
|
|
||||||
void console_spawn();
|
void console_spawn();
|
||||||
|
void console_execute(const std::vector<std::string> &lines);
|
||||||
void console_cancel();
|
void console_cancel();
|
||||||
void console_hangup();
|
void console_hangup();
|
||||||
void console_termstop();
|
void console_termstop();
|
||||||
|
|
|
@ -31,13 +31,32 @@ const char *const generic_message
|
||||||
***
|
***
|
||||||
)"};
|
)"};
|
||||||
|
|
||||||
|
const size_t stack_sz
|
||||||
|
{
|
||||||
|
1_MiB
|
||||||
|
};
|
||||||
|
|
||||||
bool console_active;
|
bool console_active;
|
||||||
|
bool console_inwork;
|
||||||
ircd::ctx::ctx *console_ctx;
|
ircd::ctx::ctx *console_ctx;
|
||||||
boost::asio::posix::stream_descriptor *console_in;
|
boost::asio::posix::stream_descriptor *console_in;
|
||||||
|
|
||||||
static bool handle_line(const std::string &line);
|
static bool handle_line(const std::string &line);
|
||||||
|
static void execute(const std::vector<std::string> lines);
|
||||||
static void console();
|
static void console();
|
||||||
|
|
||||||
|
void
|
||||||
|
console_execute(const std::vector<std::string> &lines)
|
||||||
|
{
|
||||||
|
if(console_active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ircd::context
|
||||||
|
{
|
||||||
|
"execute", stack_sz, std::bind(&execute, lines), ircd::context::DETACH
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
console_spawn()
|
console_spawn()
|
||||||
{
|
{
|
||||||
|
@ -46,7 +65,10 @@ console_spawn()
|
||||||
|
|
||||||
// The console function is executed asynchronously.
|
// The console function is executed asynchronously.
|
||||||
// The DETACH indicates it will clean itself up.
|
// The DETACH indicates it will clean itself up.
|
||||||
ircd::context("console", std::bind(&console), ircd::context::DETACH);
|
ircd::context
|
||||||
|
{
|
||||||
|
"console", stack_sz, std::bind(&console), ircd::context::DETACH
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -56,12 +78,18 @@ try
|
||||||
if(!console_active)
|
if(!console_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!console_in)
|
if(console_inwork && console_ctx)
|
||||||
|
{
|
||||||
|
interrupt(*console_ctx);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(console_in)
|
||||||
|
{
|
||||||
console_in->cancel();
|
console_in->cancel();
|
||||||
console_in->close();
|
console_in->close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch(const std::exception &e)
|
catch(const std::exception &e)
|
||||||
{
|
{
|
||||||
ircd::log::error("Interrupting console: %s", e.what());
|
ircd::log::error("Interrupting console: %s", e.what());
|
||||||
|
@ -71,7 +99,6 @@ void
|
||||||
console_hangup()
|
console_hangup()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using namespace ircd;
|
|
||||||
using log::console_quiet;
|
using log::console_quiet;
|
||||||
|
|
||||||
console_cancel();
|
console_cancel();
|
||||||
|
@ -138,7 +165,8 @@ void
|
||||||
console()
|
console()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using namespace ircd;
|
if(ircd::runlevel != ircd::runlevel::RUN)
|
||||||
|
return;
|
||||||
|
|
||||||
const unwind atexit([]
|
const unwind atexit([]
|
||||||
{
|
{
|
||||||
|
@ -189,16 +217,59 @@ catch(const std::exception &e)
|
||||||
|
|
||||||
std::cout << std::flush;
|
std::cout << std::flush;
|
||||||
std::cout.clear();
|
std::cout.clear();
|
||||||
std::cerr.clear();
|
|
||||||
|
|
||||||
ircd::log::debug("The console session has ended: %s", e.what());
|
ircd::log::debug("The console session has ended: %s", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
execute(const std::vector<std::string> lines)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(ircd::runlevel != ircd::runlevel::RUN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const unwind atexit([]
|
||||||
|
{
|
||||||
|
console_active = false;
|
||||||
|
delete moi; moi = nullptr;
|
||||||
|
});
|
||||||
|
|
||||||
|
console_active = true;
|
||||||
|
console_ctx = &ctx::cur();
|
||||||
|
|
||||||
|
for(const auto &line : lines)
|
||||||
|
{
|
||||||
|
if(line.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!handle_line(line))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "***\n";
|
||||||
|
std::cout << "*** The execution aborted: " << e.what() << "\n";
|
||||||
|
std::cout << "***" << std::endl;
|
||||||
|
|
||||||
|
std::cout << std::flush;
|
||||||
|
std::cout.clear();
|
||||||
|
|
||||||
|
ircd::log::debug("The execution aborted: %s", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
handle_line(const std::string &line)
|
handle_line(const std::string &line)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using namespace ircd;
|
// _theirs is copied for recursive reentrance
|
||||||
|
const unwind outwork{[console_inwork_theirs(console_inwork)]
|
||||||
|
{
|
||||||
|
console_inwork = console_inwork_theirs;
|
||||||
|
}};
|
||||||
|
|
||||||
|
console_inwork = true;
|
||||||
|
|
||||||
if(line == "ABORT")
|
if(line == "ABORT")
|
||||||
abort();
|
abort();
|
||||||
|
|
Loading…
Reference in a new issue