Changeset View
Changeset View
Standalone View
Standalone View
src/bitcoind.cpp
Show All 13 Lines | |||||
#include <fs.h> | #include <fs.h> | ||||
#include <httprpc.h> | #include <httprpc.h> | ||||
#include <httpserver.h> | #include <httpserver.h> | ||||
#include <init.h> | #include <init.h> | ||||
#include <interfaces/chain.h> | #include <interfaces/chain.h> | ||||
#include <noui.h> | #include <noui.h> | ||||
#include <rpc/server.h> | #include <rpc/server.h> | ||||
#include <shutdown.h> | #include <shutdown.h> | ||||
#include <ui_interface.h> | |||||
#include <util/strencodings.h> | #include <util/strencodings.h> | ||||
#include <util/system.h> | #include <util/system.h> | ||||
#include <util/threadnames.h> | #include <util/threadnames.h> | ||||
#include <walletinitinterface.h> | #include <walletinitinterface.h> | ||||
#include <cstdio> | |||||
const std::function<std::string(const char *)> G_TRANSLATION_FUN = nullptr; | const std::function<std::string(const char *)> G_TRANSLATION_FUN = nullptr; | ||||
/* Introduction text for doxygen: */ | /* Introduction text for doxygen: */ | ||||
/*! \mainpage Developer documentation | /*! \mainpage Developer documentation | ||||
* | * | ||||
* \section intro_sec Introduction | * \section intro_sec Introduction | ||||
* | * | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | static bool AppInit(int argc, char *argv[]) { | ||||
// | // | ||||
// Parameters | // Parameters | ||||
// | // | ||||
// If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's | // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's | ||||
// main() | // main() | ||||
SetupServerArgs(); | SetupServerArgs(); | ||||
std::string error; | std::string error; | ||||
if (!gArgs.ParseParameters(argc, argv, error)) { | if (!gArgs.ParseParameters(argc, argv, error)) { | ||||
tfm::format(std::cerr, "Error parsing command line arguments: %s\n", | return InitError( | ||||
error.c_str()); | strprintf("Error parsing command line arguments: %s\n", error)); | ||||
return false; | |||||
} | } | ||||
// Process help and version before taking care about datadir | // Process help and version before taking care about datadir | ||||
if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { | if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { | ||||
std::string strUsage = | std::string strUsage = | ||||
PACKAGE_NAME " Daemon version " + FormatFullVersion() + "\n"; | PACKAGE_NAME " Daemon version " + FormatFullVersion() + "\n"; | ||||
if (gArgs.IsArgSet("-version")) { | if (gArgs.IsArgSet("-version")) { | ||||
strUsage += FormatParagraph(LicenseInfo()); | strUsage += FormatParagraph(LicenseInfo()); | ||||
} else { | } else { | ||||
strUsage += "\nUsage: bitcoind [options] " | strUsage += "\nUsage: bitcoind [options] " | ||||
"Start " PACKAGE_NAME " Daemon\n"; | "Start " PACKAGE_NAME " Daemon\n"; | ||||
strUsage += "\n" + gArgs.GetHelpMessage(); | strUsage += "\n" + gArgs.GetHelpMessage(); | ||||
} | } | ||||
tfm::format(std::cout, "%s", strUsage.c_str()); | tfm::format(std::cout, "%s", strUsage.c_str()); | ||||
return true; | return true; | ||||
} | } | ||||
try { | try { | ||||
if (!fs::is_directory(GetDataDir(false))) { | if (!fs::is_directory(GetDataDir(false))) { | ||||
tfm::format( | return InitError( | ||||
std::cerr, | strprintf("Specified data directory \"%s\" does not exist.\n", | ||||
"Error: Specified data directory \"%s\" does not exist.\n", | gArgs.GetArg("-datadir", ""))); | ||||
gArgs.GetArg("-datadir", "").c_str()); | |||||
return false; | |||||
} | } | ||||
if (!gArgs.ReadConfigFiles(error, true)) { | if (!gArgs.ReadConfigFiles(error, true)) { | ||||
tfm::format(std::cerr, "Error reading configuration file: %s\n", | return InitError( | ||||
error.c_str()); | strprintf("Error reading configuration file: %s\n", error)); | ||||
return false; | |||||
} | } | ||||
// Check for -testnet or -regtest parameter (Params() calls are only | // Check for -testnet or -regtest parameter (Params() calls are only | ||||
// valid after this clause) | // valid after this clause) | ||||
try { | try { | ||||
SelectParams(gArgs.GetChainName()); | SelectParams(gArgs.GetChainName()); | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
tfm::format(std::cerr, "Error: %s\n", e.what()); | return InitError(strprintf("%s\n", e.what())); | ||||
return false; | |||||
} | } | ||||
// Make sure we create the net-specific data directory early on: if it | // Make sure we create the net-specific data directory early on: if it | ||||
// is new, this has a side effect of also creating | // is new, this has a side effect of also creating | ||||
// <datadir>/<net>/wallets/. | // <datadir>/<net>/wallets/. | ||||
// | // | ||||
// TODO: this should be removed once GetDataDir() no longer creates the | // TODO: this should be removed once GetDataDir() no longer creates the | ||||
// wallets/ subdirectory. | // wallets/ subdirectory. | ||||
// See more info at: | // See more info at: | ||||
// https://reviews.bitcoinabc.org/D3312 | // https://reviews.bitcoinabc.org/D3312 | ||||
GetDataDir(true); | GetDataDir(true); | ||||
// Error out when loose non-argument tokens are encountered on command | // Error out when loose non-argument tokens are encountered on command | ||||
// line | // line | ||||
for (int i = 1; i < argc; i++) { | for (int i = 1; i < argc; i++) { | ||||
if (!IsSwitchChar(argv[i][0])) { | if (!IsSwitchChar(argv[i][0])) { | ||||
tfm::format( | return InitError( | ||||
std::cerr, | strprintf("Command line contains unexpected token '%s', " | ||||
"Error: Command line contains unexpected token '%s', " | |||||
"see bitcoind -h for a list of options.\n", | "see bitcoind -h for a list of options.\n", | ||||
argv[i]); | argv[i])); | ||||
return false; | |||||
} | } | ||||
} | } | ||||
// -server defaults to true for bitcoind but not for the GUI so do this | // -server defaults to true for bitcoind but not for the GUI so do this | ||||
// here | // here | ||||
gArgs.SoftSetBoolArg("-server", true); | gArgs.SoftSetBoolArg("-server", true); | ||||
// Set this early so that parameter interactions go to console | // Set this early so that parameter interactions go to console | ||||
InitLogging(); | InitLogging(); | ||||
Show All 14 Lines | try { | ||||
return false; | return false; | ||||
} | } | ||||
if (gArgs.GetBoolArg("-daemon", false)) { | if (gArgs.GetBoolArg("-daemon", false)) { | ||||
#if HAVE_DECL_DAEMON | #if HAVE_DECL_DAEMON | ||||
#if defined(MAC_OSX) | #if defined(MAC_OSX) | ||||
#pragma GCC diagnostic push | #pragma GCC diagnostic push | ||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | ||||
#endif | #endif | ||||
tfm::format(std::cout, "Bitcoin server starting\n"); | tfm::format(std::cout, PACKAGE_NAME "daemon starting\n"); | ||||
// Daemonize | // Daemonize | ||||
if (daemon(1, 0)) { | if (daemon(1, 0)) { | ||||
// don't chdir (1), do close FDs (0) | // don't chdir (1), do close FDs (0) | ||||
tfm::format(std::cerr, "Error: daemon() failed: %s\n", | return InitError( | ||||
strerror(errno)); | strprintf("daemon() failed: %s\n", strerror(errno))); | ||||
return false; | |||||
} | } | ||||
#if defined(MAC_OSX) | #if defined(MAC_OSX) | ||||
#pragma GCC diagnostic pop | #pragma GCC diagnostic pop | ||||
#endif | #endif | ||||
#else | #else | ||||
tfm::format( | return InitError( | ||||
std::cerr, | "-daemon is not supported on this operating system\n"); | ||||
"Error: -daemon is not supported on this operating system\n"); | |||||
return false; | |||||
#endif // HAVE_DECL_DAEMON | #endif // HAVE_DECL_DAEMON | ||||
} | } | ||||
// Lock data directory after daemonization | // Lock data directory after daemonization | ||||
if (!AppInitLockDataDirectory()) { | if (!AppInitLockDataDirectory()) { | ||||
// If locking the data directory failed, exit immediately | // If locking the data directory failed, exit immediately | ||||
return false; | return false; | ||||
} | } | ||||
Show All 30 Lines |