BitCoin-22.0代码分析之bitcoind.cpp中AppInit函数

static bool AppInit(NodeContext& node, int argc, char* argv[])

函数作用:应用初始化,5处出现,包括定义和调用。

函数全局调用情况如下:。

 函数声明情况如下:

函数声明文件如下:

函数流程图如下:

 

函数逻辑顺序图如下:

函数原始代码如下:

static bool AppInit(NodeContext& node, 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()如果使用QT,参数conf的参数赋值给cppmain

    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\n", error)));

    }

    // Process help and version before taking care about datadir

    if (HelpRequested(args) || args.IsArgSet("-version")) {

        std::string strUsage = PACKAGE_NAME " version " + FormatFullVersion() + "\n";

        if (!args.IsArgSet("-version")) {

            strUsage += FormatParagraph(LicenseInfo()) + "\n"

                "\nUsage:  bitcoind [options]                     Start " PACKAGE_NAME "\n"

                "\n";

            strUsage += args.GetHelpMessage();

        }

        tfm::format(std::cout, "%s", strUsage);

        return true;

    }

#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

    // that the parent process can quit, and whether it was successful/unsuccessful.

    // - an unexpected shutdown of the child process creates an unexpected end of stream at the parent

    // end, which is interpreted as failure to start.

    TokenPipeEnd daemon_ep;

#endif

    std::any context{&node};

    try

    {

        if (!CheckDataDirOption()) {

            return InitError(Untranslated(strprintf("Specified data directory \"%s\" does not exist.\n", args.GetArg("-datadir", ""))));

        }

        if (!args.ReadConfigFiles(error, true)) {

            return InitError(Untranslated(strprintf("Error reading configuration file: %s\n", error)));

        }

        // Check for chain settings (Params() calls are only valid after this clause)

        try {

            SelectParams(args.GetChainName());

        } catch (const std::exception& e) {

            return InitError(Untranslated(strprintf("%s\n", e.what())));

        }

        // 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.\n", argv[i])));

            }

        }

        if (!args.InitSettings(error)) {

            InitError(Untranslated(error));

            return false;

        }

        // -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

        InitLogging(args);

        InitParameterInteraction(args);

        if (!AppInitBasicSetup(args)) {

            // InitError will have been called with detailed error, which ends up on console

            return false;

        }

        if (!AppInitParameterInteraction(args)) {

            // InitError will have been called with detailed error, which ends up on console

            return false;

        }

        if (!AppInitSanityChecks())

        {

            // InitError will have been called with detailed error, which ends up on console

            return false;

        }

        if (args.GetBoolArg("-daemon", DEFAULT_DAEMON) || args.GetBoolArg("-daemonwait", DEFAULT_DAEMONWAIT)) {

#if HAVE_DECL_FORK

            tfm::format(std::cout, PACKAGE_NAME " starting\n");

            // Daemonize

            switch (fork_daemon(1, 0, daemon_ep)) { // don't chdir (1), do close FDs (0)

            case 0: // Child: continue.

                // If -daemonwait is not enabled, immediately send a success token the parent.

                if (!args.GetBoolArg("-daemonwait", DEFAULT_DAEMONWAIT)) {

                    daemon_ep.TokenWrite(1);

                    daemon_ep.Close();

                }

                break;

            case -1: // Error happened.

                return InitError(Untranslated(strprintf("fork_daemon() failed: %s\n", strerror(errno))));

            default: { // Parent: wait and exit.

                int token = daemon_ep.TokenRead();

                if (token) { // Success

                    exit(EXIT_SUCCESS);

                } else { // fRet = false or token read error (premature exit).

                    tfm::format(std::cerr, "Error during initializaton - check debug.log for details\n");

                    exit(EXIT_FAILURE);

                }

            }

            }

#else

            return InitError(Untranslated("-daemon is not supported on this operating system\n"));

#endif // HAVE_DECL_FORK

        }

        // Lock data directory after daemonization

        if (!AppInitLockDataDirectory())

        {

            // If locking the data directory failed, exit immediately

            return false;

        }

        fRet = AppInitInterfaces(node) && AppInitMain(node);

    }

    catch (const std::exception& e) {

        PrintExceptionContinue(&e, "AppInit()");

    } catch (...) {

        PrintExceptionContinue(nullptr, "AppInit()");

    }

#if HAVE_DECL_FORK

    if (daemon_ep.IsOpen()) {

        // Signal initialization status to parent, then close pipe.

        daemon_ep.TokenWrite(fRet);

        daemon_ep.Close();

    }

#endif

    if (fRet) {

        WaitForShutdown();

    }

    Interrupt(node);

    Shutdown(node);

    return fRet;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqq9668

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值