aboutsummaryrefslogtreecommitdiff
path: root/src/util/system.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/system.h')
-rw-r--r--src/util/system.h389
1 files changed, 389 insertions, 0 deletions
diff --git a/src/util/system.h b/src/util/system.h
new file mode 100644
index 0000000000..dca32cc6fc
--- /dev/null
+++ b/src/util/system.h
@@ -0,0 +1,389 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+/**
+ * Server/client environment: argument handling, config file parsing,
+ * thread wrappers, startup time
+ */
+#ifndef BITCOIN_UTIL_SYSTEM_H
+#define BITCOIN_UTIL_SYSTEM_H
+
+#if defined(HAVE_CONFIG_H)
+#include <config/bitcoin-config.h>
+#endif
+
+#include <attributes.h>
+#include <compat.h>
+#include <fs.h>
+#include <logging.h>
+#include <sync.h>
+#include <tinyformat.h>
+#include <util/memory.h>
+#include <util/time.h>
+
+#include <atomic>
+#include <exception>
+#include <map>
+#include <set>
+#include <stdint.h>
+#include <string>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+#include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
+
+// Application startup time (used for uptime calculation)
+int64_t GetStartupTime();
+
+extern const char * const BITCOIN_CONF_FILENAME;
+extern const char * const BITCOIN_PID_FILENAME;
+
+/** Translate a message to the native language of the user. */
+const extern std::function<std::string(const char*)> G_TRANSLATION_FUN;
+
+/**
+ * Translation function.
+ * If no translation function is set, simply return the input.
+ */
+inline std::string _(const char* psz)
+{
+ return G_TRANSLATION_FUN ? (G_TRANSLATION_FUN)(psz) : psz;
+}
+
+void SetupEnvironment();
+bool SetupNetworking();
+
+template<typename... Args>
+bool error(const char* fmt, const Args&... args)
+{
+ LogPrintf("ERROR: %s\n", tfm::format(fmt, args...));
+ return false;
+}
+
+void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
+bool FileCommit(FILE *file);
+bool TruncateFile(FILE *file, unsigned int length);
+int RaiseFileDescriptorLimit(int nMinFD);
+void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
+bool RenameOver(fs::path src, fs::path dest);
+bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false);
+bool DirIsWritable(const fs::path& directory);
+
+/** Release all directory locks. This is used for unit testing only, at runtime
+ * the global destructor will take care of the locks.
+ */
+void ReleaseDirectoryLocks();
+
+bool TryCreateDirectories(const fs::path& p);
+fs::path GetDefaultDataDir();
+const fs::path &GetBlocksDir(bool fNetSpecific = true);
+const fs::path &GetDataDir(bool fNetSpecific = true);
+void ClearDatadirCache();
+fs::path GetConfigFile(const std::string& confPath);
+#ifndef WIN32
+fs::path GetPidFile();
+void CreatePidFile(const fs::path &path, pid_t pid);
+#endif
+#ifdef WIN32
+fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
+#endif
+void runCommand(const std::string& strCommand);
+
+/**
+ * Most paths passed as configuration arguments are treated as relative to
+ * the datadir if they are not absolute.
+ *
+ * @param path The path to be conditionally prefixed with datadir.
+ * @param net_specific Forwarded to GetDataDir().
+ * @return The normalized path.
+ */
+fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific = true);
+
+inline bool IsSwitchChar(char c)
+{
+#ifdef WIN32
+ return c == '-' || c == '/';
+#else
+ return c == '-';
+#endif
+}
+
+enum class OptionsCategory {
+ OPTIONS,
+ CONNECTION,
+ WALLET,
+ WALLET_DEBUG_TEST,
+ ZMQ,
+ DEBUG_TEST,
+ CHAINPARAMS,
+ NODE_RELAY,
+ BLOCK_CREATION,
+ RPC,
+ GUI,
+ COMMANDS,
+ REGISTER_COMMANDS,
+
+ HIDDEN // Always the last option to avoid printing these in the help
+};
+
+class ArgsManager
+{
+protected:
+ friend class ArgsManagerHelper;
+
+ struct Arg
+ {
+ std::string m_help_param;
+ std::string m_help_text;
+ bool m_debug_only;
+
+ Arg(const std::string& help_param, const std::string& help_text, bool debug_only) : m_help_param(help_param), m_help_text(help_text), m_debug_only(debug_only) {};
+ };
+
+ mutable CCriticalSection cs_args;
+ std::map<std::string, std::vector<std::string>> m_override_args GUARDED_BY(cs_args);
+ std::map<std::string, std::vector<std::string>> m_config_args GUARDED_BY(cs_args);
+ std::string m_network GUARDED_BY(cs_args);
+ std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
+ std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
+ std::set<std::string> m_config_sections GUARDED_BY(cs_args);
+
+ NODISCARD bool ReadConfigStream(std::istream& stream, std::string& error, bool ignore_invalid_keys = false);
+
+public:
+ ArgsManager();
+
+ /**
+ * Select the network in use
+ */
+ void SelectConfigNetwork(const std::string& network);
+
+ NODISCARD bool ParseParameters(int argc, const char* const argv[], std::string& error);
+ NODISCARD bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
+
+ /**
+ * Log warnings for options in m_section_only_args when
+ * they are specified in the default section but not overridden
+ * on the command line or in a network-specific section in the
+ * config file.
+ */
+ const std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
+
+ /**
+ * Log warnings for unrecognized section names in the config file.
+ */
+ const std::set<std::string> GetUnrecognizedSections() const;
+
+ /**
+ * Return a vector of strings of the given argument
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @return command-line arguments
+ */
+ std::vector<std::string> GetArgs(const std::string& strArg) const;
+
+ /**
+ * Return true if the given argument has been manually set
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @return true if the argument has been set
+ */
+ bool IsArgSet(const std::string& strArg) const;
+
+ /**
+ * Return true if the argument was originally passed as a negated option,
+ * i.e. -nofoo.
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @return true if the argument was passed negated
+ */
+ bool IsArgNegated(const std::string& strArg) const;
+
+ /**
+ * Return string argument or default value
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @param strDefault (e.g. "1")
+ * @return command-line argument or default value
+ */
+ std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
+
+ /**
+ * Return integer argument or default value
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @param nDefault (e.g. 1)
+ * @return command-line argument (0 if invalid number) or default value
+ */
+ int64_t GetArg(const std::string& strArg, int64_t nDefault) const;
+
+ /**
+ * Return boolean argument or default value
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @param fDefault (true or false)
+ * @return command-line argument or default value
+ */
+ bool GetBoolArg(const std::string& strArg, bool fDefault) const;
+
+ /**
+ * Set an argument if it doesn't already have a value
+ *
+ * @param strArg Argument to set (e.g. "-foo")
+ * @param strValue Value (e.g. "1")
+ * @return true if argument gets set, false if it already had a value
+ */
+ bool SoftSetArg(const std::string& strArg, const std::string& strValue);
+
+ /**
+ * Set a boolean argument if it doesn't already have a value
+ *
+ * @param strArg Argument to set (e.g. "-foo")
+ * @param fValue Value (e.g. false)
+ * @return true if argument gets set, false if it already had a value
+ */
+ bool SoftSetBoolArg(const std::string& strArg, bool fValue);
+
+ // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
+ // been set. Also called directly in testing.
+ void ForceSetArg(const std::string& strArg, const std::string& strValue);
+
+ /**
+ * Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
+ * @return CBaseChainParams::MAIN by default; raises runtime error if an invalid combination is given.
+ */
+ std::string GetChainName() const;
+
+ /**
+ * Add argument
+ */
+ void AddArg(const std::string& name, const std::string& help, const bool debug_only, const OptionsCategory& cat);
+
+ /**
+ * Add many hidden arguments
+ */
+ void AddHiddenArgs(const std::vector<std::string>& args);
+
+ /**
+ * Clear available arguments
+ */
+ void ClearArgs() {
+ LOCK(cs_args);
+ m_available_args.clear();
+ }
+
+ /**
+ * Get the help string
+ */
+ std::string GetHelpMessage() const;
+
+ /**
+ * Check whether we know of this arg
+ */
+ bool IsArgKnown(const std::string& key) const;
+};
+
+extern ArgsManager gArgs;
+
+/**
+ * @return true if help has been requested via a command-line arg
+ */
+bool HelpRequested(const ArgsManager& args);
+
+/**
+ * Format a string to be used as group of options in help messages
+ *
+ * @param message Group name (e.g. "RPC server options:")
+ * @return the formatted string
+ */
+std::string HelpMessageGroup(const std::string& message);
+
+/**
+ * Format a string to be used as option description in help messages
+ *
+ * @param option Option message (e.g. "-rpcuser=<user>")
+ * @param message Option description (e.g. "Username for JSON-RPC connections")
+ * @return the formatted string
+ */
+std::string HelpMessageOpt(const std::string& option, const std::string& message);
+
+/**
+ * Return the number of cores available on the current system.
+ * @note This does count virtual cores, such as those provided by HyperThreading.
+ */
+int GetNumCores();
+
+void RenameThread(const char* name);
+
+/**
+ * .. and a wrapper that just calls func once
+ */
+template <typename Callable> void TraceThread(const char* name, Callable func)
+{
+ std::string s = strprintf("bitcoin-%s", name);
+ RenameThread(s.c_str());
+ try
+ {
+ LogPrintf("%s thread start\n", name);
+ func();
+ LogPrintf("%s thread exit\n", name);
+ }
+ catch (const boost::thread_interrupted&)
+ {
+ LogPrintf("%s thread interrupt\n", name);
+ throw;
+ }
+ catch (const std::exception& e) {
+ PrintExceptionContinue(&e, name);
+ throw;
+ }
+ catch (...) {
+ PrintExceptionContinue(nullptr, name);
+ throw;
+ }
+}
+
+std::string CopyrightHolders(const std::string& strPrefix);
+
+/**
+ * On platforms that support it, tell the kernel the calling thread is
+ * CPU-intensive and non-interactive. See SCHED_BATCH in sched(7) for details.
+ *
+ * @return The return value of sched_setschedule(), or 1 on systems without
+ * sched_setschedule().
+ */
+int ScheduleBatchPriority();
+
+namespace util {
+
+//! Simplification of std insertion
+template <typename Tdst, typename Tsrc>
+inline void insert(Tdst& dst, const Tsrc& src) {
+ dst.insert(dst.begin(), src.begin(), src.end());
+}
+template <typename TsetT, typename Tsrc>
+inline void insert(std::set<TsetT>& dst, const Tsrc& src) {
+ dst.insert(src.begin(), src.end());
+}
+
+#ifdef WIN32
+class WinCmdLineArgs
+{
+public:
+ WinCmdLineArgs();
+ ~WinCmdLineArgs();
+ std::pair<int, char**> get();
+
+private:
+ int argc;
+ char** argv;
+ std::vector<std::string> args;
+};
+#endif
+
+} // namespace util
+
+#endif // BITCOIN_UTIL_SYSTEM_H