Bitcoin Core  0.19.99
P2P Digital Currency
system.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
10 #ifndef BITCOIN_UTIL_SYSTEM_H
11 #define BITCOIN_UTIL_SYSTEM_H
12 
13 #if defined(HAVE_CONFIG_H)
14 #include <config/bitcoin-config.h>
15 #endif
16 
17 #include <attributes.h>
18 #include <compat.h>
19 #include <compat/assumptions.h>
20 #include <fs.h>
21 #include <logging.h>
22 #include <optional.h>
23 #include <sync.h>
24 #include <tinyformat.h>
25 #include <util/memory.h>
26 #include <util/settings.h>
27 #include <util/threadnames.h>
28 #include <util/time.h>
29 
30 #include <exception>
31 #include <map>
32 #include <set>
33 #include <stdint.h>
34 #include <string>
35 #include <utility>
36 #include <vector>
37 
38 #include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
39 
40 // Application startup time (used for uptime calculation)
41 int64_t GetStartupTime();
42 
43 extern const char * const BITCOIN_CONF_FILENAME;
44 
45 void SetupEnvironment();
46 bool SetupNetworking();
47 
48 template<typename... Args>
49 bool error(const char* fmt, const Args&... args)
50 {
51  LogPrintf("ERROR: %s\n", tfm::format(fmt, args...));
52  return false;
53 }
54 
55 void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
56 bool FileCommit(FILE *file);
57 bool TruncateFile(FILE *file, unsigned int length);
58 int RaiseFileDescriptorLimit(int nMinFD);
59 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
60 bool RenameOver(fs::path src, fs::path dest);
61 bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false);
62 void UnlockDirectory(const fs::path& directory, const std::string& lockfile_name);
63 bool DirIsWritable(const fs::path& directory);
64 bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
65 
70 
71 bool TryCreateDirectories(const fs::path& p);
72 fs::path GetDefaultDataDir();
73 // The blocks directory is always net specific.
74 const fs::path &GetBlocksDir();
75 const fs::path &GetDataDir(bool fNetSpecific = true);
76 // Return true if -datadir option points to a valid directory or is not specified.
77 bool CheckDataDirOption();
79 void ClearDatadirCache();
80 fs::path GetConfigFile(const std::string& confPath);
81 #ifdef WIN32
82 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
83 #endif
84 #ifndef WIN32
85 std::string ShellEscape(const std::string& arg);
86 #endif
87 #if HAVE_SYSTEM
88 void runCommand(const std::string& strCommand);
89 #endif
90 
99 fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific = true);
100 
101 inline bool IsSwitchChar(char c)
102 {
103 #ifdef WIN32
104  return c == '-' || c == '/';
105 #else
106  return c == '-';
107 #endif
108 }
109 
110 enum class OptionsCategory {
111  OPTIONS,
112  CONNECTION,
113  WALLET,
115  ZMQ,
116  DEBUG_TEST,
117  CHAINPARAMS,
118  NODE_RELAY,
120  RPC,
121  GUI,
122  COMMANDS,
124 
125  HIDDEN // Always the last option to avoid printing these in the help
126 };
127 
129 {
130  std::string m_name;
131  std::string m_file;
132  int m_line;
133 };
134 
136 {
137 public:
138  enum Flags {
139  // Boolean options can accept negation syntax -noOPTION or -noOPTION=1
140  ALLOW_BOOL = 0x01,
141  ALLOW_INT = 0x02,
142  ALLOW_STRING = 0x04,
143  ALLOW_ANY = ALLOW_BOOL | ALLOW_INT | ALLOW_STRING,
144  DEBUG_ONLY = 0x100,
145  /* Some options would cause cross-contamination if values for
146  * mainnet were used while running on regtest/testnet (or vice-versa).
147  * Setting them as NETWORK_ONLY ensures that sharing a config file
148  * between mainnet and regtest/testnet won't cause problems due to these
149  * parameters by accident. */
150  NETWORK_ONLY = 0x200,
151  // This argument's value is sensitive (such as a password).
152  SENSITIVE = 0x400,
153  };
154 
155 protected:
156  struct Arg
157  {
158  std::string m_help_param;
159  std::string m_help_text;
160  unsigned int m_flags;
161  };
162 
164  util::Settings m_settings GUARDED_BY(cs_args);
165  std::string m_network GUARDED_BY(cs_args);
166  std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
167  std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
168  std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
169 
170  NODISCARD bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false);
171 
177  bool UseDefaultSection(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
178 
186  util::SettingsValue GetSetting(const std::string& arg) const;
187 
191  std::vector<util::SettingsValue> GetSettingsList(const std::string& arg) const;
192 
193 public:
194  ArgsManager();
195 
199  void SelectConfigNetwork(const std::string& network);
200 
201  NODISCARD bool ParseParameters(int argc, const char* const argv[], std::string& error);
202  NODISCARD bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
203 
210  const std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
211 
215  const std::list<SectionInfo> GetUnrecognizedSections() const;
216 
223  std::vector<std::string> GetArgs(const std::string& strArg) const;
224 
231  bool IsArgSet(const std::string& strArg) const;
232 
240  bool IsArgNegated(const std::string& strArg) const;
241 
249  std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
250 
258  int64_t GetArg(const std::string& strArg, int64_t nDefault) const;
259 
267  bool GetBoolArg(const std::string& strArg, bool fDefault) const;
268 
276  bool SoftSetArg(const std::string& strArg, const std::string& strValue);
277 
285  bool SoftSetBoolArg(const std::string& strArg, bool fValue);
286 
287  // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
288  // been set. Also called directly in testing.
289  void ForceSetArg(const std::string& strArg, const std::string& strValue);
290 
295  std::string GetChainName() const;
296 
300  void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat);
301 
305  void AddHiddenArgs(const std::vector<std::string>& args);
306 
310  void ClearArgs() {
311  LOCK(cs_args);
312  m_available_args.clear();
313  m_network_only_args.clear();
314  }
315 
319  std::string GetHelpMessage() const;
320 
325  Optional<unsigned int> GetArgFlags(const std::string& name) const;
326 
331  void LogArgs() const;
332 
333 private:
334  // Helper function for LogArgs().
335  void logArgsPrefix(
336  const std::string& prefix,
337  const std::string& section,
338  const std::map<std::string, std::vector<util::SettingsValue>>& args) const;
339 };
340 
341 extern ArgsManager gArgs;
342 
346 bool HelpRequested(const ArgsManager& args);
347 
349 void SetupHelpOptions(ArgsManager& args);
350 
357 std::string HelpMessageGroup(const std::string& message);
358 
366 std::string HelpMessageOpt(const std::string& option, const std::string& message);
367 
372 int GetNumCores();
373 
377 template <typename Callable> void TraceThread(const char* name, Callable func)
378 {
379  util::ThreadRename(name);
380  try
381  {
382  LogPrintf("%s thread start\n", name);
383  func();
384  LogPrintf("%s thread exit\n", name);
385  }
386  catch (const boost::thread_interrupted&)
387  {
388  LogPrintf("%s thread interrupt\n", name);
389  throw;
390  }
391  catch (const std::exception& e) {
392  PrintExceptionContinue(&e, name);
393  throw;
394  }
395  catch (...) {
396  PrintExceptionContinue(nullptr, name);
397  throw;
398  }
399 }
400 
401 std::string CopyrightHolders(const std::string& strPrefix);
402 
408 void ScheduleBatchPriority();
409 
410 namespace util {
411 
413 template <typename Tdst, typename Tsrc>
414 inline void insert(Tdst& dst, const Tsrc& src) {
415  dst.insert(dst.begin(), src.begin(), src.end());
416 }
417 template <typename TsetT, typename Tsrc>
418 inline void insert(std::set<TsetT>& dst, const Tsrc& src) {
419  dst.insert(src.begin(), src.end());
420 }
421 
422 #ifdef WIN32
423 class WinCmdLineArgs
424 {
425 public:
426  WinCmdLineArgs();
427  ~WinCmdLineArgs();
428  std::pair<int, char**> get();
429 
430 private:
431  int argc;
432  char** argv;
433  std::vector<std::string> args;
434 };
435 #endif
436 
437 } // namespace util
438 
439 #endif // BITCOIN_UTIL_SYSTEM_H
Stored bitcoin settings.
Definition: settings.h:29
fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific=true)
Most paths passed as configuration arguments are treated as relative to the datadir if they are not a...
Definition: system.cpp:1146
bool TruncateFile(FILE *file, unsigned int length)
Definition: system.cpp:954
Definition: settings.cpp:9
void SetupEnvironment()
Definition: system.cpp:1074
unsigned int m_flags
Definition: system.h:160
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:657
const char * prefix
Definition: rest.cpp:650
SettingsValue GetSetting(const Settings &settings, const std::string &section, const std::string &name, bool ignore_default_section_config, bool get_chain_name)
Get settings value from combined sources: forced settings, command line arguments and the read-only c...
Definition: settings.cpp:52
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name...
Definition: threadnames.cpp:57
int m_line
Definition: system.h:132
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:163
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1154
RecursiveMutex cs_args
Definition: system.h:163
bool RenameOver(fs::path src, fs::path dest)
Definition: system.cpp:891
const fs::path & GetBlocksDir()
Definition: system.cpp:587
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:512
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length)
this function tries to make a particular range of a file allocated (corresponding to disk space) it i...
Definition: system.cpp:989
std::string m_name
Definition: system.h:130
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:549
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:123
int RaiseFileDescriptorLimit(int nMinFD)
this function tries to raise the file descriptor limit to the requested number.
Definition: system.cpp:966
const fs::path & GetDataDir(bool fNetSpecific=true)
Definition: system.cpp:612
int64_t GetStartupTime()
Server/client environment: argument handling, config file parsing, thread wrappers, startup time.
Definition: system.cpp:1141
std::vector< SettingsValue > GetSettingsList(const Settings &settings, const std::string &section, const std::string &name, bool ignore_default_section_config)
Get combined setting value similar to GetSetting(), except if setting was specified multiple times...
Definition: settings.cpp:105
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:74
bool FileCommit(FILE *file)
Definition: system.cpp:921
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes=0)
Definition: system.cpp:136
#define NODISCARD
Definition: attributes.h:18
#define LOCK(cs)
Definition: sync.h:179
const char * name
Definition: rest.cpp:40
void format(std::ostream &out, const char *fmt, const Args &... args)
Format list of arguments to the stream according to given format string.
Definition: tinyformat.h:1062
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:507
bool CheckDataDirOption()
Definition: system.cpp:642
std::string m_file
Definition: system.h:131
UniValue help(const JSONRPCRequest &jsonRequest)
Definition: server.cpp:130
void ClearArgs()
Clear available arguments.
Definition: system.h:310
std::string m_help_text
Definition: system.h:159
void TraceThread(const char *name, Callable func)
Definition: system.h:377
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: system.cpp:522
int flags
Definition: bitcoin-tx.cpp:508
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:51
fs::path GetDefaultDataDir()
Definition: system.cpp:556
void ClearDatadirCache()
Tests only.
Definition: system.cpp:648
void UnlockDirectory(const fs::path &directory, const std::string &lockfile_name)
Definition: system.cpp:111
#define GUARDED_BY(x)
Definition: threadsafety.h:38
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost&#39;s create_directories if the requested directory exists...
Definition: system.cpp:907
bool IsSwitchChar(char c)
Definition: system.h:101
OptionsCategory
Definition: system.h:110
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:14
std::string CopyrightHolders(const std::string &strPrefix)
Definition: system.cpp:1128
std::string m_help_param
Definition: system.h:158
void insert(std::set< TsetT > &dst, const Tsrc &src)
Definition: system.h:418
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
Definition: system.cpp:526
bool LockDirectory(const fs::path &directory, const std::string lockfile_name, bool probe_only=false)
Definition: system.cpp:87
ArgsManager gArgs
Definition: system.cpp:76
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: system.cpp:117
std::string ShellEscape(const std::string &arg)
Definition: system.cpp:1052
int GetNumCores()
Return the number of cores available on the current system.
Definition: system.cpp:1123
bool SetupNetworking()
Definition: system.cpp:1111