You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bitcoind.cpp 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2013 The Bitcoin developers
  3. // Distributed under the MIT/X11 software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include "bitcoinrpc.h"
  6. #include "init.h"
  7. #include "main.h"
  8. #include "noui.h"
  9. #include "ui_interface.h"
  10. #include "util.h"
  11. #include <boost/algorithm/string/predicate.hpp>
  12. #include <boost/filesystem.hpp>
  13. void DetectShutdownThread(boost::thread_group* threadGroup)
  14. {
  15. bool fShutdown = ShutdownRequested();
  16. // Tell the main threads to shutdown.
  17. while (!fShutdown)
  18. {
  19. MilliSleep(200);
  20. fShutdown = ShutdownRequested();
  21. }
  22. if (threadGroup)
  23. {
  24. threadGroup->interrupt_all();
  25. threadGroup->join_all();
  26. }
  27. }
  28. //////////////////////////////////////////////////////////////////////////////
  29. //
  30. // Start
  31. //
  32. bool AppInit(int argc, char* argv[])
  33. {
  34. boost::thread_group threadGroup;
  35. boost::thread* detectShutdownThread = NULL;
  36. bool fRet = false;
  37. try
  38. {
  39. //
  40. // Parameters
  41. //
  42. // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
  43. ParseParameters(argc, argv);
  44. if (!boost::filesystem::is_directory(GetDataDir(false)))
  45. {
  46. fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
  47. return false;
  48. }
  49. ReadConfigFile(mapArgs, mapMultiArgs);
  50. // Check for -testnet or -regtest parameter (TestNet() calls are only valid after this clause)
  51. if (!SelectParamsFromCommandLine()) {
  52. fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
  53. return false;
  54. }
  55. if (mapArgs.count("-?") || mapArgs.count("--help"))
  56. {
  57. // First part of help message is specific to bitcoind / RPC client
  58. std::string strUsage = _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
  59. _("Usage:") + "\n" +
  60. " bitcoind [options] " + _("Start Bitcoin server") + "\n" +
  61. _("Usage (deprecated, use bitcoin-cli):") + "\n" +
  62. " bitcoind [options] <command> [params] " + _("Send command to Bitcoin server") + "\n" +
  63. " bitcoind [options] help " + _("List commands") + "\n" +
  64. " bitcoind [options] help <command> " + _("Get help for a command") + "\n";
  65. strUsage += "\n" + HelpMessage(HMM_BITCOIND);
  66. fprintf(stdout, "%s", strUsage.c_str());
  67. return false;
  68. }
  69. // Command-line RPC
  70. bool fCommandLine = false;
  71. for (int i = 1; i < argc; i++)
  72. if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "bitcoin:"))
  73. fCommandLine = true;
  74. if (fCommandLine)
  75. {
  76. int ret = CommandLineRPC(argc, argv);
  77. exit(ret);
  78. }
  79. #ifndef WIN32
  80. fDaemon = GetBoolArg("-daemon", false);
  81. if (fDaemon)
  82. {
  83. // Daemonize
  84. pid_t pid = fork();
  85. if (pid < 0)
  86. {
  87. fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
  88. return false;
  89. }
  90. if (pid > 0) // Parent process, pid is child process id
  91. {
  92. CreatePidFile(GetPidFile(), pid);
  93. return true;
  94. }
  95. // Child process falls through to rest of initialization
  96. pid_t sid = setsid();
  97. if (sid < 0)
  98. fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
  99. }
  100. #endif
  101. detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
  102. fRet = AppInit2(threadGroup, true);
  103. }
  104. catch (std::exception& e) {
  105. PrintExceptionContinue(&e, "AppInit()");
  106. } catch (...) {
  107. PrintExceptionContinue(NULL, "AppInit()");
  108. }
  109. if (!fRet)
  110. {
  111. if (detectShutdownThread)
  112. detectShutdownThread->interrupt();
  113. threadGroup.interrupt_all();
  114. // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
  115. // the startup-failure cases to make sure they don't result in a hang due to some
  116. // thread-blocking-waiting-for-another-thread-during-startup case
  117. }
  118. if (detectShutdownThread)
  119. {
  120. detectShutdownThread->join();
  121. delete detectShutdownThread;
  122. detectShutdownThread = NULL;
  123. }
  124. Shutdown();
  125. return fRet;
  126. }
  127. int main(int argc, char* argv[])
  128. {
  129. bool fRet = false;
  130. // Connect bitcoind signal handlers
  131. noui_connect();
  132. fRet = AppInit(argc, argv);
  133. if (fRet && fDaemon)
  134. return 0;
  135. return (fRet ? 0 : 1);
  136. }