Bitcoin ABC  0.29.1
P2P Digital Currency
system.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2019 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 <compat.h>
18 #include <compat/assumptions.h>
19 #include <fs.h>
20 #include <logging.h>
21 #include <sync.h>
22 #include <tinyformat.h>
23 #include <util/settings.h>
24 #include <util/time.h>
25 
26 #include <any>
27 #include <cstdint>
28 #include <exception>
29 #include <map>
30 #include <optional>
31 #include <set>
32 #include <string>
33 #include <utility>
34 #include <vector>
35 
36 // Application startup time (used for uptime calculation)
37 int64_t GetStartupTime();
38 
39 extern const char *const BITCOIN_CONF_FILENAME;
40 extern const char *const BITCOIN_SETTINGS_FILENAME;
41 
42 void SetupEnvironment();
43 bool SetupNetworking();
44 
45 template <typename... Args> bool error(const char *fmt, const Args &...args) {
46  LogPrintf("ERROR: %s\n", tfm::format(fmt, args...));
47  return false;
48 }
49 
50 void PrintExceptionContinue(const std::exception *pex, const char *pszThread);
51 bool FileCommit(FILE *file);
52 bool TruncateFile(FILE *file, unsigned int length);
53 int RaiseFileDescriptorLimit(int nMinFD);
54 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
55 [[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
56 bool LockDirectory(const fs::path &directory, const std::string lockfile_name,
57  bool probe_only = false);
58 void UnlockDirectory(const fs::path &directory,
59  const std::string &lockfile_name);
60 bool DirIsWritable(const fs::path &directory);
61 bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes = 0);
62 
70 std::streampos
71 GetFileSize(const char *path,
72  std::streamsize max = std::numeric_limits<std::streamsize>::max());
73 
79 
80 bool TryCreateDirectories(const fs::path &p);
82 // Return true if -datadir option points to a valid directory or is not
83 // specified.
84 bool CheckDataDirOption();
85 fs::path GetConfigFile(const std::string &confPath);
86 #ifdef WIN32
87 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
88 #endif
89 #ifndef WIN32
90 std::string ShellEscape(const std::string &arg);
91 #endif
92 #if defined(HAVE_SYSTEM)
93 void runCommand(const std::string &strCommand);
94 #endif
95 
96 [[nodiscard]] bool ParseKeyValue(std::string &key, std::string &val);
97 
106 fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific = true);
107 
108 inline bool IsSwitchChar(char c) {
109 #ifdef WIN32
110  return c == '-' || c == '/';
111 #else
112  return c == '-';
113 #endif
114 }
115 
116 enum class OptionsCategory {
117  OPTIONS,
118  CONNECTION,
119  WALLET,
121  ZMQ,
122  DEBUG_TEST,
123  CHAINPARAMS,
124  NODE_RELAY,
126  RPC,
127  GUI,
128  COMMANDS,
130  AVALANCHE,
131  CHRONIK,
132 
133  // Always the last option to avoid printing these in the help
134  HIDDEN,
135 };
136 
137 struct SectionInfo {
138  std::string m_name;
139  std::string m_file;
140  int m_line;
141 };
142 
143 std::string SettingToString(const util::SettingsValue &, const std::string &);
144 std::optional<std::string> SettingToString(const util::SettingsValue &);
145 
146 int64_t SettingToInt(const util::SettingsValue &, int64_t);
147 std::optional<int64_t> SettingToInt(const util::SettingsValue &);
148 
149 bool SettingToBool(const util::SettingsValue &, bool);
150 std::optional<bool> SettingToBool(const util::SettingsValue &);
151 
152 class ArgsManager {
153 public:
154  enum Flags {
155  // Boolean options can accept negation syntax -noOPTION or -noOPTION=1
156  ALLOW_BOOL = 0x01,
157  ALLOW_INT = 0x02,
158  ALLOW_STRING = 0x04,
160  DEBUG_ONLY = 0x100,
161  /* Some options would cause cross-contamination if values for
162  * mainnet were used while running on regtest/testnet (or vice-versa).
163  * Setting them as NETWORK_ONLY ensures that sharing a config file
164  * between mainnet and regtest/testnet won't cause problems due to these
165  * parameters by accident. */
166  NETWORK_ONLY = 0x200,
167  // This argument's value is sensitive (such as a password).
168  SENSITIVE = 0x400,
169  };
170 
171 protected:
172  struct Arg {
173  std::string m_help_param;
174  std::string m_help_text;
175  unsigned int m_flags;
176  };
177 
180  std::string m_network GUARDED_BY(cs_args);
181  std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
182  std::map<OptionsCategory, std::map<std::string, Arg>>
183  m_available_args GUARDED_BY(cs_args);
184  std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
185  mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args);
186  mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args);
187  mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args);
188 
189  [[nodiscard]] bool ReadConfigStream(std::istream &stream,
190  const std::string &filepath,
191  std::string &error,
192  bool ignore_invalid_keys = false);
193 
199  bool UseDefaultSection(const std::string &arg) const
201 
202 public:
210  util::SettingsValue GetSetting(const std::string &arg) const;
211 
215  std::vector<util::SettingsValue>
216  GetSettingsList(const std::string &arg) const;
217 
218  ArgsManager();
219  ~ArgsManager();
220 
224  void SelectConfigNetwork(const std::string &network);
225 
226  [[nodiscard]] bool ParseParameters(int argc, const char *const argv[],
227  std::string &error);
228  [[nodiscard]] bool ReadConfigFiles(std::string &error,
229  bool ignore_invalid_keys = false);
230 
236  const std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
237 
241  const std::list<SectionInfo> GetUnrecognizedSections() const;
242 
248  const fs::path &GetBlocksDirPath() const;
249 
257  const fs::path &GetDataDirBase() const { return GetDataDir(false); }
258 
266  const fs::path &GetDataDirNet() const { return GetDataDir(true); }
267 
271  void ClearPathCache();
272 
279  std::vector<std::string> GetArgs(const std::string &strArg) const;
280 
287  bool IsArgSet(const std::string &strArg) const;
288 
296  bool IsArgNegated(const std::string &strArg) const;
297 
305  std::string GetArg(const std::string &strArg,
306  const std::string &strDefault) const;
307  std::optional<std::string> GetArg(const std::string &strArg) const;
308 
321  fs::path GetPathArg(std::string arg,
322  const fs::path &default_value = {}) const;
323 
331  int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const;
332  std::optional<int64_t> GetIntArg(const std::string &strArg) const;
333 
341  bool GetBoolArg(const std::string &strArg, bool fDefault) const;
342  std::optional<bool> GetBoolArg(const std::string &strArg) const;
343 
351  bool SoftSetArg(const std::string &strArg, const std::string &strValue);
352 
360  bool SoftSetBoolArg(const std::string &strArg, bool fValue);
361 
362  // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
363  // been set. Also called directly in testing.
364  void ForceSetArg(const std::string &strArg, const std::string &strValue);
365 
366  // Forces a multi arg setting, used only in testing
367  void ForceSetMultiArg(const std::string &strArg,
368  const std::vector<std::string> &values);
369 
376  std::string GetChainName() const;
377 
381  void AddArg(const std::string &name, const std::string &help,
382  unsigned int flags, const OptionsCategory &cat);
383 
387  void ClearForcedArg(const std::string &strArg);
388 
392  void AddHiddenArgs(const std::vector<std::string> &args);
393 
397  void ClearArgs() {
398  LOCK(cs_args);
399  m_available_args.clear();
400  m_network_only_args.clear();
401  }
402 
406  std::string GetHelpMessage() const;
407 
412  std::optional<unsigned int> GetArgFlags(const std::string &name) const;
413 
419  bool InitSettings(std::string &error);
420 
425  bool GetSettingsPath(fs::path *filepath = nullptr, bool temp = false,
426  bool backup = false) const;
427 
431  bool ReadSettingsFile(std::vector<std::string> *errors = nullptr);
432 
437  bool WriteSettingsFile(std::vector<std::string> *errors = nullptr,
438  bool backup = false) const;
439 
444  util::SettingsValue GetPersistentSetting(const std::string &name) const;
445 
449  template <typename Fn> void LockSettings(Fn &&fn) {
450  LOCK(cs_args);
451  fn(m_settings);
452  }
453 
458  void LogArgs() const;
459 
460 private:
469  const fs::path &GetDataDir(bool net_specific) const;
470 
471  // Helper function for LogArgs().
472  void
473  logArgsPrefix(const std::string &prefix, const std::string &section,
474  const std::map<std::string, std::vector<util::SettingsValue>>
475  &args) const;
476 };
477 
478 extern ArgsManager gArgs;
479 
483 bool HelpRequested(const ArgsManager &args);
484 
486 void SetupHelpOptions(ArgsManager &args);
487 
494 std::string HelpMessageGroup(const std::string &message);
495 
503 std::string HelpMessageOpt(const std::string &option,
504  const std::string &message);
505 
511 int GetNumCores();
512 
513 std::string CopyrightHolders(const std::string &strPrefix);
514 
520 void ScheduleBatchPriority();
521 
522 namespace util {
523 
525 template <typename Tdst, typename Tsrc>
526 inline void insert(Tdst &dst, const Tsrc &src) {
527  dst.insert(dst.begin(), src.begin(), src.end());
528 }
529 template <typename TsetT, typename Tsrc>
530 inline void insert(std::set<TsetT> &dst, const Tsrc &src) {
531  dst.insert(src.begin(), src.end());
532 }
533 
539 template <typename T> T *AnyPtr(const std::any &any) noexcept {
540  T *const *ptr = std::any_cast<T *>(&any);
541  return ptr ? *ptr : nullptr;
542 }
543 
544 #ifdef WIN32
545 class WinCmdLineArgs {
546 public:
547  WinCmdLineArgs();
548  ~WinCmdLineArgs();
549  std::pair<int, char **> get();
550 
551 private:
552  int argc;
553  char **argv;
554  std::vector<std::string> args;
555 };
556 #endif
557 
558 } // namespace util
559 
560 #endif // BITCOIN_UTIL_SYSTEM_H
int flags
Definition: bitcoin-tx.cpp:533
const std::set< std::string > GetUnsuitableSectionOnlyArgs() const
Log warnings for options in m_section_only_args when they are specified in the default section but no...
Definition: system.cpp:254
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
Definition: system.cpp:410
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: system.cpp:599
@ NETWORK_ONLY
Definition: system.h:166
@ ALLOW_ANY
Definition: system.h:159
@ DEBUG_ONLY
Definition: system.h:160
@ ALLOW_INT
Definition: system.h:157
@ ALLOW_BOOL
Definition: system.h:156
@ ALLOW_STRING
Definition: system.h:158
@ SENSITIVE
Definition: system.h:168
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: system.cpp:541
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: system.cpp:706
void logArgsPrefix(const std::string &prefix, const std::string &section, const std::map< std::string, std::vector< util::SettingsValue >> &args) const
Definition: system.cpp:1173
bool InitSettings(std::string &error)
Read and update settings file with saved settings.
Definition: system.cpp:494
fs::path m_cached_datadir_path GUARDED_BY(cs_args)
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:322
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:480
util::SettingsValue GetPersistentSetting(const std::string &name) const
Get current setting from config file or read/write settings file, ignoring nonpersistent command line...
Definition: system.cpp:592
std::optional< unsigned int > GetArgFlags(const std::string &name) const
Return Flags for known arg.
Definition: system.cpp:385
const fs::path & GetDataDirBase() const
Get data directory path.
Definition: system.h:257
std::string m_network GUARDED_BY(cs_args)
~ArgsManager()
Definition: system.cpp:252
bool GetSettingsPath(fs::path *filepath=nullptr, bool temp=false, bool backup=false) const
Get settings file path, or return false if read-write settings were disabled with -nosettings.
Definition: system.cpp:513
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: system.h:449
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: system.cpp:688
void SelectConfigNetwork(const std::string &network)
Select the network in use.
Definition: system.cpp:293
std::string GetHelpMessage() const
Get the help string.
Definition: system.cpp:762
void ForceSetMultiArg(const std::string &strArg, const std::vector< std::string > &values)
This function is only used for testing purpose so so we should not worry about element uniqueness and...
Definition: system.cpp:717
void ClearPathCache()
Clear cached directory paths.
Definition: system.cpp:472
fs::path m_cached_blocks_path GUARDED_BY(cs_args)
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:490
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:266
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const
Write settings file or backup settings file.
Definition: system.cpp:566
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:635
std::map< OptionsCategory, std::map< std::string, Arg > > m_available_args GUARDED_BY(cs_args)
const fs::path & GetDataDir(bool net_specific) const
Get data directory path.
Definition: system.cpp:436
void ClearArgs()
Clear available arguments.
Definition: system.h:397
util::Settings m_settings GUARDED_BY(cs_args)
void ClearForcedArg(const std::string &strArg)
Remove a forced arg setting, used only in testing.
Definition: system.cpp:757
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: system.cpp:1167
void LogArgs() const
Log the config file options and the command line arguments, useful for troubleshooting.
Definition: system.cpp:1190
RecursiveMutex cs_args
Definition: system.h:178
fs::path m_cached_network_datadir_path GUARDED_BY(cs_args)
bool UseDefaultSection(const std::string &arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args)
Returns true if settings values from the default section should be used, depending on the current net...
Definition: system.cpp:1153
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:603
std::set< std::string > m_network_only_args GUARDED_BY(cs_args)
util::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: system.cpp:1158
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:986
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: system.cpp:698
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:1021
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:665
void AddHiddenArgs(const std::vector< std::string > &args)
Add many hidden arguments.
Definition: system.cpp:751
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:729
fs::path GetPathArg(std::string arg, const fs::path &default_value={}) const
Return path argument or default value.
Definition: system.cpp:396
std::list< SectionInfo > m_config_sections GUARDED_BY(cs_args)
const std::list< SectionInfo > GetUnrecognizedSections() const
Log warnings for unrecognized section names in the config file.
Definition: system.cpp:278
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
Definition: system.cpp:1123
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
#define LogPrintf(...)
Definition: logging.h:206
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:1112
Definition: result.h:13
T * AnyPtr(const std::any &any) noexcept
Helper function to access the contained object of a std::any instance.
Definition: system.h:539
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
Definition: system.h:526
const char * prefix
Definition: rest.cpp:819
const char * name
Definition: rest.cpp:48
static RPCHelpMan help()
Definition: server.cpp:180
std::string m_help_param
Definition: system.h:173
unsigned int m_flags
Definition: system.h:175
std::string m_help_text
Definition: system.h:174
int m_line
Definition: system.h:140
std::string m_file
Definition: system.h:139
std::string m_name
Definition: system.h:138
Stored settings.
Definition: settings.h:31
#define LOCK(cs)
Definition: sync.h:306
bool error(const char *fmt, const Args &...args)
Definition: system.h:45
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:841
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:846
fs::path GetDefaultDataDir()
Definition: system.cpp:892
int64_t GetStartupTime()
Server/client environment: argument handling, config file parsing, thread wrappers,...
Definition: system.cpp:1449
OptionsCategory
Definition: system.h:116
const char *const BITCOIN_SETTINGS_FILENAME
Definition: system.cpp:78
bool ParseKeyValue(std::string &key, std::string &val)
Definition: system.cpp:298
std::string CopyrightHolders(const std::string &strPrefix)
Definition: system.cpp:1443
bool SettingToBool(const util::SettingsValue &, bool)
Definition: system.cpp:684
void UnlockDirectory(const fs::path &directory, const std::string &lockfile_name)
Definition: system.cpp:120
bool CheckDataDirOption()
Definition: system.cpp:917
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:131
bool RenameOver(fs::path src, fs::path dest)
Definition: system.cpp:1202
int64_t SettingToInt(const util::SettingsValue &, int64_t)
Definition: system.cpp:661
bool SetupNetworking()
Definition: system.cpp:1426
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1461
int RaiseFileDescriptorLimit(int nMinFD)
This function tries to raise the file descriptor limit to the requested number.
Definition: system.cpp:1280
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:153
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: system.cpp:126
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by create_directories if the requested directory exists.
Definition: system.cpp:1217
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:1306
ArgsManager gArgs
Definition: system.cpp:80
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:1453
void SetupEnvironment()
Definition: system.cpp:1398
bool LockDirectory(const fs::path &directory, const std::string lockfile_name, bool probe_only=false)
Definition: system.cpp:92
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:922
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:886
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: system.cpp:856
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:77
bool IsSwitchChar(char c)
Definition: system.h:108
bool TruncateFile(FILE *file, unsigned int length)
Definition: system.cpp:1267
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes=0)
Definition: system.cpp:145
int GetNumCores()
Return the number of cores available on the current system.
Definition: system.cpp:1439
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:860
bool FileCommit(FILE *file)
Definition: system.cpp:1231
std::string SettingToString(const util::SettingsValue &, const std::string &)
Definition: system.cpp:630
std::string ShellEscape(const std::string &arg)
Definition: system.cpp:1371
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
@ AVALANCHE
Removed by avalanche vote.