Bitcoin Core  21.99.0
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 class UniValue;
41 
42 // Application startup time (used for uptime calculation)
43 int64_t GetStartupTime();
44 
45 extern const char * const BITCOIN_CONF_FILENAME;
46 extern const char * const BITCOIN_SETTINGS_FILENAME;
47 
48 void SetupEnvironment();
49 bool SetupNetworking();
50 
51 template<typename... Args>
52 bool error(const char* fmt, const Args&... args)
53 {
54  LogPrintf("ERROR: %s\n", tfm::format(fmt, args...));
55  return false;
56 }
57 
58 void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
59 
64 bool FileCommit(FILE *file);
65 
70 void DirectoryCommit(const fs::path &dirname);
71 
72 bool TruncateFile(FILE *file, unsigned int length);
73 int RaiseFileDescriptorLimit(int nMinFD);
74 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
75 [[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
76 bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false);
77 void UnlockDirectory(const fs::path& directory, const std::string& lockfile_name);
78 bool DirIsWritable(const fs::path& directory);
79 bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
80 
87 std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
88 
93 
94 bool TryCreateDirectories(const fs::path& p);
95 fs::path GetDefaultDataDir();
96 // The blocks directory is always net specific.
97 const fs::path &GetBlocksDir();
98 const fs::path &GetDataDir(bool fNetSpecific = true);
99 // Return true if -datadir option points to a valid directory or is not specified.
100 bool CheckDataDirOption();
102 void ClearDatadirCache();
103 fs::path GetConfigFile(const std::string& confPath);
104 #ifdef WIN32
105 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
106 #endif
107 #ifndef WIN32
108 std::string ShellEscape(const std::string& arg);
109 #endif
110 #if HAVE_SYSTEM
111 void runCommand(const std::string& strCommand);
112 #endif
113 #ifdef HAVE_BOOST_PROCESS
114 
121 UniValue RunCommandParseJSON(const std::string& str_command, const std::string& str_std_in="");
122 #endif // HAVE_BOOST_PROCESS
123 
132 fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific = true);
133 
134 inline bool IsSwitchChar(char c)
135 {
136 #ifdef WIN32
137  return c == '-' || c == '/';
138 #else
139  return c == '-';
140 #endif
141 }
142 
143 enum class OptionsCategory {
144  OPTIONS,
145  CONNECTION,
146  WALLET,
148  ZMQ,
149  DEBUG_TEST,
150  CHAINPARAMS,
151  NODE_RELAY,
153  RPC,
154  GUI,
155  COMMANDS,
157 
158  HIDDEN // Always the last option to avoid printing these in the help
159 };
160 
162 {
163  std::string m_name;
164  std::string m_file;
165  int m_line;
166 };
167 
169 {
170 public:
171  enum Flags {
172  // Boolean options can accept negation syntax -noOPTION or -noOPTION=1
173  ALLOW_BOOL = 0x01,
174  ALLOW_INT = 0x02,
175  ALLOW_STRING = 0x04,
176  ALLOW_ANY = ALLOW_BOOL | ALLOW_INT | ALLOW_STRING,
177  DEBUG_ONLY = 0x100,
178  /* Some options would cause cross-contamination if values for
179  * mainnet were used while running on regtest/testnet (or vice-versa).
180  * Setting them as NETWORK_ONLY ensures that sharing a config file
181  * between mainnet and regtest/testnet won't cause problems due to these
182  * parameters by accident. */
183  NETWORK_ONLY = 0x200,
184  // This argument's value is sensitive (such as a password).
185  SENSITIVE = 0x400,
186  };
187 
188 protected:
189  struct Arg
190  {
191  std::string m_help_param;
192  std::string m_help_text;
193  unsigned int m_flags;
194  };
195 
197  util::Settings m_settings GUARDED_BY(cs_args);
198  std::string m_network GUARDED_BY(cs_args);
199  std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
200  std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
201  std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
202 
203  [[nodiscard]] bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false);
204 
210  bool UseDefaultSection(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
211 
219  util::SettingsValue GetSetting(const std::string& arg) const;
220 
224  std::vector<util::SettingsValue> GetSettingsList(const std::string& arg) const;
225 
226 public:
227  ArgsManager();
228  ~ArgsManager();
229 
233  void SelectConfigNetwork(const std::string& network);
234 
235  [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error);
236  [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
237 
244  const std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
245 
249  const std::list<SectionInfo> GetUnrecognizedSections() const;
250 
257  std::vector<std::string> GetArgs(const std::string& strArg) const;
258 
265  bool IsArgSet(const std::string& strArg) const;
266 
274  bool IsArgNegated(const std::string& strArg) const;
275 
283  std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
284 
292  int64_t GetArg(const std::string& strArg, int64_t nDefault) const;
293 
301  bool GetBoolArg(const std::string& strArg, bool fDefault) const;
302 
310  bool SoftSetArg(const std::string& strArg, const std::string& strValue);
311 
319  bool SoftSetBoolArg(const std::string& strArg, bool fValue);
320 
321  // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
322  // been set. Also called directly in testing.
323  void ForceSetArg(const std::string& strArg, const std::string& strValue);
324 
329  std::string GetChainName() const;
330 
334  void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat);
335 
339  void AddHiddenArgs(const std::vector<std::string>& args);
340 
344  void ClearArgs() {
345  LOCK(cs_args);
346  m_available_args.clear();
347  m_network_only_args.clear();
348  }
349 
353  std::string GetHelpMessage() const;
354 
359  Optional<unsigned int> GetArgFlags(const std::string& name) const;
360 
366  bool InitSettings(std::string& error);
367 
372  bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false) const;
373 
377  bool ReadSettingsFile(std::vector<std::string>* errors = nullptr);
378 
382  bool WriteSettingsFile(std::vector<std::string>* errors = nullptr) const;
383 
387  template <typename Fn>
388  void LockSettings(Fn&& fn)
389  {
390  LOCK(cs_args);
391  fn(m_settings);
392  }
393 
398  void LogArgs() const;
399 
400 private:
401  // Helper function for LogArgs().
402  void logArgsPrefix(
403  const std::string& prefix,
404  const std::string& section,
405  const std::map<std::string, std::vector<util::SettingsValue>>& args) const;
406 };
407 
408 extern ArgsManager gArgs;
409 
413 bool HelpRequested(const ArgsManager& args);
414 
416 void SetupHelpOptions(ArgsManager& args);
417 
424 std::string HelpMessageGroup(const std::string& message);
425 
433 std::string HelpMessageOpt(const std::string& option, const std::string& message);
434 
439 int GetNumCores();
440 
444 template <typename Callable> void TraceThread(const char* name, Callable func)
445 {
446  util::ThreadRename(name);
447  try
448  {
449  LogPrintf("%s thread start\n", name);
450  func();
451  LogPrintf("%s thread exit\n", name);
452  }
453  catch (const boost::thread_interrupted&)
454  {
455  LogPrintf("%s thread interrupt\n", name);
456  throw;
457  }
458  catch (const std::exception& e) {
459  PrintExceptionContinue(&e, name);
460  throw;
461  }
462  catch (...) {
463  PrintExceptionContinue(nullptr, name);
464  throw;
465  }
466 }
467 
468 std::string CopyrightHolders(const std::string& strPrefix);
469 
475 void ScheduleBatchPriority();
476 
477 namespace util {
478 
480 template <typename Tdst, typename Tsrc>
481 inline void insert(Tdst& dst, const Tsrc& src) {
482  dst.insert(dst.begin(), src.begin(), src.end());
483 }
484 template <typename TsetT, typename Tsrc>
485 inline void insert(std::set<TsetT>& dst, const Tsrc& src) {
486  dst.insert(src.begin(), src.end());
487 }
488 
489 #ifdef WIN32
490 class WinCmdLineArgs
491 {
492 public:
493  WinCmdLineArgs();
494  ~WinCmdLineArgs();
495  std::pair<int, char**> get();
496 
497 private:
498  int argc;
499  char** argv;
500  std::vector<std::string> args;
501 };
502 #endif
503 
504 } // namespace util
505 
506 #endif // BITCOIN_UTIL_SYSTEM_H
Stored settings.
Definition: settings.h:31
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:1309
bool TruncateFile(FILE *file, unsigned int length)
Definition: system.cpp:1080
Definition: httprpc.h:8
void SetupEnvironment()
Definition: system.cpp:1237
unsigned int m_flags
Definition: system.h:193
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:766
const char * prefix
Definition: rest.cpp:670
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, runtime read-write settings, and the read-only config file.
Definition: settings.cpp:114
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:165
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:166
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1317
RecursiveMutex cs_args
Definition: system.h:196
bool RenameOver(fs::path src, fs::path dest)
Definition: system.cpp:1008
const fs::path & GetBlocksDir()
Definition: system.cpp:694
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:607
std::streampos GetFileSize(const char *path, std::streamsize max=std::numeric_limits< std::streamsize >::max())
Get the size of a file by scanning it.
Definition: system.cpp:145
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:1115
std::string m_name
Definition: system.h:163
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:644
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:124
int RaiseFileDescriptorLimit(int nMinFD)
this function tries to raise the file descriptor limit to the requested number.
Definition: system.cpp:1092
const fs::path & GetDataDir(bool fNetSpecific=true)
Definition: system.cpp:720
int64_t GetStartupTime()
Definition: system.cpp:1304
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:167
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:74
bool FileCommit(FILE *file)
Ensure file contents are fully committed to disk, using a platform-specific feature analogous to fsyn...
Definition: system.cpp:1038
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes=0)
Definition: system.cpp:137
#define LOCK(cs)
Definition: sync.h:232
const char * name
Definition: rest.cpp:41
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:602
bool CheckDataDirOption()
Definition: system.cpp:751
std::string m_file
Definition: system.h:164
void ClearArgs()
Clear available arguments.
Definition: system.h:344
std::string m_help_text
Definition: system.h:192
void TraceThread(const char *name, Callable func)
Definition: system.h:444
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: system.cpp:617
int flags
Definition: bitcoin-tx.cpp:512
const char *const BITCOIN_SETTINGS_FILENAME
Definition: system.cpp:75
void DirectoryCommit(const fs::path &dirname)
Sync directory contents.
Definition: system.cpp:1069
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
fs::path GetDefaultDataDir()
Definition: system.cpp:651
void ClearDatadirCache()
Tests only.
Definition: system.cpp:757
void UnlockDirectory(const fs::path &directory, const std::string &lockfile_name)
Definition: system.cpp:112
#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:1024
bool IsSwitchChar(char c)
Definition: system.h:134
OptionsCategory
Definition: system.h:143
std::string CopyrightHolders(const std::string &strPrefix)
Definition: system.cpp:1291
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: system.h:388
std::string m_help_param
Definition: system.h:191
void insert(std::set< TsetT > &dst, const Tsrc &src)
Definition: system.h:485
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:621
bool LockDirectory(const fs::path &directory, const std::string lockfile_name, bool probe_only=false)
Definition: system.cpp:88
static RPCHelpMan help()
Definition: server.cpp:133
ArgsManager gArgs
Definition: system.cpp:77
bool error(const char *fmt, const Args &... args)
Definition: system.h:52
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: system.cpp:118
std::string ShellEscape(const std::string &arg)
Definition: system.cpp:1178
int GetNumCores()
Return the number of cores available on the current system.
Definition: system.cpp:1286
std::optional< T > Optional
Substitute for C++17 std::optional DEPRECATED use std::optional in new code.
Definition: optional.h:14
bool SetupNetworking()
Definition: system.cpp:1274
UniValue RunCommandParseJSON(const std::string &str_command, const std::string &str_std_in="")
Execute a command which returns JSON, and parse the result.
Definition: system.cpp:1201