console_handler: catch exception inside the input loop

This prevents an exception from existing the loop without
calling the exit handler, if one is defined.
The daemon defines one, which stops the p2p layer, and will
only exit once the p2p layer is shut down. This would cause
a hang upon an exception, as the input thread would have
exited and the daemon would wait forever with no console
user input.
This commit is contained in:
moneromooo-monero 2015-12-06 22:03:53 +00:00
parent 0252ffc37b
commit 4cede1830e
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3

View File

@ -268,52 +268,57 @@ namespace epee
template<typename t_cmd_handler> template<typename t_cmd_handler>
bool run(const std::string& prompt, const std::string& usage, const t_cmd_handler& cmd_handler, std::function<void(void)> exit_handler) bool run(const std::string& prompt, const std::string& usage, const t_cmd_handler& cmd_handler, std::function<void(void)> exit_handler)
{ {
TRY_ENTRY();
bool continue_handle = true; bool continue_handle = true;
m_prompt = prompt; m_prompt = prompt;
while(continue_handle) while(continue_handle)
{ {
if (!m_running) try
{ {
break; if (!m_running)
} {
print_prompt(); break;
}
print_prompt();
std::string command; std::string command;
bool get_line_ret = m_stdin_reader.get_line(command); bool get_line_ret = m_stdin_reader.get_line(command);
if (!m_running || m_stdin_reader.eos()) if (!m_running || m_stdin_reader.eos())
{ {
break; break;
} }
if (!get_line_ret) if (!get_line_ret)
{ {
LOG_PRINT("Failed to read line.", LOG_LEVEL_0); LOG_PRINT("Failed to read line.", LOG_LEVEL_0);
} }
string_tools::trim(command); string_tools::trim(command);
LOG_PRINT_L2("Read command: " << command); LOG_PRINT_L2("Read command: " << command);
if (command.empty()) if (command.empty())
{ {
continue; continue;
}
else if(cmd_handler(command))
{
continue;
}
else if(0 == command.compare("exit") || 0 == command.compare("q"))
{
continue_handle = false;
}
else
{
std::cout << "unknown command: " << command << std::endl;
std::cout << usage;
}
} }
else if(cmd_handler(command)) catch (const std::exception &ex)
{ {
continue; LOG_ERROR("Exception at [console_handler], what=" << ex.what());
}
else if(0 == command.compare("exit") || 0 == command.compare("q"))
{
continue_handle = false;
}
else
{
std::cout << "unknown command: " << command << std::endl;
std::cout << usage;
} }
} }
if (exit_handler) if (exit_handler)
exit_handler(); exit_handler();
return true; return true;
CATCH_ENTRY_L0("console_handler", false);
} }
private: private: