refactor: decouple early return commands from AppInit

Cleaned up the init flow to make it more obvious when
the 'exit_status' value will and won't be returned.

This is because it was confusing that `AppInit` was
returning true under two different circumstances:

1) When bitcoind was launched only to retrieve the "-help"
or "-version" information. In this case, the app was
not initialized.

2) When the user triggers a shutdown. In this case,
the app was fully initialized.
This commit is contained in:
furszy 2023-06-09 11:05:11 -03:00
parent 4927167f85
commit 61c569ab60
No known key found for this signature in database
GPG key ID: 5DD23CCC686AA623

View file

@ -112,20 +112,30 @@ int fork_daemon(bool nochdir, bool noclose, TokenPipeEnd& endpoint)
#endif
static bool AppInit(NodeContext& node, int argc, char* argv[])
static bool ParseArgs(ArgsManager& args, int argc, char* argv[])
{
bool fRet = false;
util::ThreadSetInternalName("init");
// If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
ArgsManager& args = *Assert(node.args);
SetupServerArgs(args);
std::string error;
if (!args.ParseParameters(argc, argv, error)) {
return InitError(Untranslated(strprintf("Error parsing command line arguments: %s", error)));
}
if (auto error = common::InitConfig(args)) {
return InitError(error->message, error->details);
}
// Error out when loose non-argument tokens are encountered on command line
for (int i = 1; i < argc; i++) {
if (!IsSwitchChar(argv[i][0])) {
return InitError(Untranslated(strprintf("Command line contains unexpected token '%s', see bitcoind -h for a list of options.", argv[i])));
}
}
return true;
}
static bool ProcessInitCommands(ArgsManager& args)
{
// Process help and version before taking care about datadir
if (HelpRequested(args) || args.IsArgSet("-version")) {
std::string strUsage = PACKAGE_NAME " version " + FormatFullVersion() + "\n";
@ -142,6 +152,14 @@ static bool AppInit(NodeContext& node, int argc, char* argv[])
return true;
}
return false;
}
static bool AppInit(NodeContext& node)
{
bool fRet = false;
ArgsManager& args = *Assert(node.args);
#if HAVE_DECL_FORK
// Communication with parent after daemonizing. This is used for signalling in the following ways:
// - a boolean token is sent when the initialization process (all the Init* functions) have finished to indicate
@ -153,17 +171,6 @@ static bool AppInit(NodeContext& node, int argc, char* argv[])
std::any context{&node};
try
{
if (auto error = common::InitConfig(args)) {
return InitError(error->message, error->details);
}
// Error out when loose non-argument tokens are encountered on command line
for (int i = 1; i < argc; i++) {
if (!IsSwitchChar(argv[i][0])) {
return InitError(Untranslated(strprintf("Command line contains unexpected token '%s', see bitcoind -h for a list of options.", argv[i])));
}
}
// -server defaults to true for bitcoind but not for the GUI so do this here
args.SoftSetBoolArg("-server", true);
// Set this early so that parameter interactions go to console
@ -236,14 +243,6 @@ static bool AppInit(NodeContext& node, int argc, char* argv[])
}
#endif
SetSyscallSandboxPolicy(SyscallSandboxPolicy::SHUTOFF);
if (fRet) {
WaitForShutdown();
} else {
node.exit_status = EXIT_FAILURE;
}
Interrupt(node);
Shutdown(node);
return fRet;
}
@ -266,5 +265,22 @@ MAIN_FUNCTION
// Connect bitcoind signal handlers
noui_connect();
return AppInit(node, argc, argv) ? node.exit_status.load() : EXIT_FAILURE;
util::ThreadSetInternalName("init");
// Interpret command line arguments
ArgsManager& args = *Assert(node.args);
if (!ParseArgs(args, argc, argv)) return EXIT_FAILURE;
// Process early info return commands such as -help or -version
if (ProcessInitCommands(args)) return EXIT_SUCCESS;
// Start application
if (AppInit(node)) {
WaitForShutdown();
} else {
node.exit_status = EXIT_FAILURE;
}
Interrupt(node);
Shutdown(node);
return node.exit_status;
}