Bitcoin Core  24.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-2022 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/compat.h>
18 #include <compat/assumptions.h>
19 #include <fs.h>
20 #include <logging.h>
21 #include <sync.h>
22 #include <util/settings.h>
23 #include <util/time.h>
24 
25 #include <any>
26 #include <map>
27 #include <optional>
28 #include <set>
29 #include <stdint.h>
30 #include <string>
31 #include <utility>
32 #include <vector>
33 
34 class ArgsManager;
35 class UniValue;
36 
37 // Application startup time (used for uptime calculation)
38 int64_t GetStartupTime();
39 
40 extern const char * const BITCOIN_CONF_FILENAME;
41 extern const char * const BITCOIN_SETTINGS_FILENAME;
42 
43 void SetupEnvironment();
44 bool SetupNetworking();
45 
50 bool FileCommit(FILE *file);
51 
56 void DirectoryCommit(const fs::path &dirname);
57 
58 bool TruncateFile(FILE *file, unsigned int length);
59 int RaiseFileDescriptorLimit(int nMinFD);
60 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
61 
66 [[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
67 
68 bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only=false);
69 void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name);
70 bool DirIsWritable(const fs::path& directory);
71 bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
72 
79 std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
80 
85 
86 bool TryCreateDirectories(const fs::path& p);
88 // Return true if -datadir option points to a valid directory or is not specified.
90 fs::path GetConfigFile(const ArgsManager& args, const fs::path& configuration_file_path);
91 #ifdef WIN32
92 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
93 #endif
94 #ifndef WIN32
95 std::string ShellEscape(const std::string& arg);
96 #endif
97 #if HAVE_SYSTEM
98 void runCommand(const std::string& strCommand);
99 #endif
100 
110 fs::path AbsPathForConfigVal(const ArgsManager& args, const fs::path& path, bool net_specific = true);
111 
112 inline bool IsSwitchChar(char c)
113 {
114 #ifdef WIN32
115  return c == '-' || c == '/';
116 #else
117  return c == '-';
118 #endif
119 }
120 
121 enum class OptionsCategory {
122  OPTIONS,
123  CONNECTION,
124  WALLET,
126  ZMQ,
127  DEBUG_TEST,
128  CHAINPARAMS,
129  NODE_RELAY,
131  RPC,
132  GUI,
133  COMMANDS,
135 
136  HIDDEN // Always the last option to avoid printing these in the help
137 };
138 
140 {
141  std::string m_name;
142  std::string m_file;
143  int m_line;
144 };
145 
146 std::string SettingToString(const util::SettingsValue&, const std::string&);
147 std::optional<std::string> SettingToString(const util::SettingsValue&);
148 
149 int64_t SettingToInt(const util::SettingsValue&, int64_t);
150 std::optional<int64_t> SettingToInt(const util::SettingsValue&);
151 
152 bool SettingToBool(const util::SettingsValue&, bool);
153 std::optional<bool> SettingToBool(const util::SettingsValue&);
154 
156 {
157 public:
162  enum Flags : uint32_t {
163  ALLOW_ANY = 0x01,
164  // ALLOW_BOOL = 0x02, //!< unimplemented, draft implementation in #16545
165  // ALLOW_INT = 0x04, //!< unimplemented, draft implementation in #16545
166  // ALLOW_STRING = 0x08, //!< unimplemented, draft implementation in #16545
167  // ALLOW_LIST = 0x10, //!< unimplemented, draft implementation in #16545
170 
171  DEBUG_ONLY = 0x100,
172  /* Some options would cause cross-contamination if values for
173  * mainnet were used while running on regtest/testnet (or vice-versa).
174  * Setting them as NETWORK_ONLY ensures that sharing a config file
175  * between mainnet and regtest/testnet won't cause problems due to these
176  * parameters by accident. */
177  NETWORK_ONLY = 0x200,
178  // This argument's value is sensitive (such as a password).
179  SENSITIVE = 0x400,
180  COMMAND = 0x800,
181  };
182 
183 protected:
184  struct Arg
185  {
186  std::string m_help_param;
187  std::string m_help_text;
188  unsigned int m_flags;
189  };
190 
193  std::vector<std::string> m_command GUARDED_BY(cs_args);
194  std::string m_network GUARDED_BY(cs_args);
195  std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
196  std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
197  bool m_accept_any_command GUARDED_BY(cs_args){true};
198  std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
199  mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args);
200  mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args);
201  mutable fs::path m_cached_network_datadir_path 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 
212  public:
220  util::SettingsValue GetSetting(const std::string& arg) const;
221 
225  std::vector<util::SettingsValue> GetSettingsList(const std::string& arg) const;
226 
229 
233  void SelectConfigNetwork(const std::string& network);
234 
235  [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error);
236 
240  fs::path GetConfigFilePath() const;
241  [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
242 
249  std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
250 
254  std::list<SectionInfo> GetUnrecognizedSections() const;
255 
256  struct Command {
258  std::string command;
263  std::vector<std::string> args;
264  };
268  std::optional<const Command> GetCommand() const;
269 
275  const fs::path& GetBlocksDirPath() const;
276 
282  const fs::path& GetDataDirBase() const { return GetDataDir(false); }
283 
289  const fs::path& GetDataDirNet() const { return GetDataDir(true); }
290 
294  void ClearPathCache();
295 
302  std::vector<std::string> GetArgs(const std::string& strArg) const;
303 
310  bool IsArgSet(const std::string& strArg) const;
311 
319  bool IsArgNegated(const std::string& strArg) const;
320 
328  std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
329  std::optional<std::string> GetArg(const std::string& strArg) const;
330 
341  fs::path GetPathArg(std::string arg, const fs::path& default_value = {}) const;
342 
350  int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const;
351  std::optional<int64_t> GetIntArg(const std::string& strArg) const;
352 
360  bool GetBoolArg(const std::string& strArg, bool fDefault) const;
361  std::optional<bool> GetBoolArg(const std::string& strArg) const;
362 
370  bool SoftSetArg(const std::string& strArg, const std::string& strValue);
371 
379  bool SoftSetBoolArg(const std::string& strArg, bool fValue);
380 
381  // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
382  // been set. Also called directly in testing.
383  void ForceSetArg(const std::string& strArg, const std::string& strValue);
384 
389  std::string GetChainName() const;
390 
394  void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat);
395 
399  void AddCommand(const std::string& cmd, const std::string& help);
400 
404  void AddHiddenArgs(const std::vector<std::string>& args);
405 
409  void ClearArgs() {
410  LOCK(cs_args);
411  m_available_args.clear();
412  m_network_only_args.clear();
413  }
414 
418  std::string GetHelpMessage() const;
419 
424  std::optional<unsigned int> GetArgFlags(const std::string& name) const;
425 
430  bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false, bool backup = false) const;
431 
435  bool ReadSettingsFile(std::vector<std::string>* errors = nullptr);
436 
441  bool WriteSettingsFile(std::vector<std::string>* errors = nullptr, bool backup = false) const;
442 
447  util::SettingsValue GetPersistentSetting(const std::string& name) const;
448 
452  template <typename Fn>
453  void LockSettings(Fn&& fn)
454  {
455  LOCK(cs_args);
456  fn(m_settings);
457  }
458 
463  void LogArgs() const;
464 
465 private:
472  const fs::path& GetDataDir(bool net_specific) const;
473 
474  // Helper function for LogArgs().
475  void logArgsPrefix(
476  const std::string& prefix,
477  const std::string& section,
478  const std::map<std::string, std::vector<util::SettingsValue>>& args) const;
479 };
480 
481 extern ArgsManager gArgs;
482 
486 bool HelpRequested(const ArgsManager& args);
487 
490 
497 std::string HelpMessageGroup(const std::string& message);
498 
506 std::string HelpMessageOpt(const std::string& option, const std::string& message);
507 
512 int GetNumCores();
513 
519 void ScheduleBatchPriority();
520 
521 namespace util {
522 
524 template <typename Tdst, typename Tsrc>
525 inline void insert(Tdst& dst, const Tsrc& src) {
526  dst.insert(dst.begin(), src.begin(), src.end());
527 }
528 template <typename TsetT, typename Tsrc>
529 inline void insert(std::set<TsetT>& dst, const Tsrc& src) {
530  dst.insert(src.begin(), src.end());
531 }
532 
538 template<typename T>
539 T* AnyPtr(const std::any& any) noexcept
540 {
541  T* const* ptr = std::any_cast<T*>(&any);
542  return ptr ? *ptr : nullptr;
543 }
544 
545 #ifdef WIN32
546 class WinCmdLineArgs
547 {
548 public:
549  WinCmdLineArgs();
550  ~WinCmdLineArgs();
551  std::pair<int, char**> get();
552 
553 private:
554  int argc;
555  char** argv;
556  std::vector<std::string> args;
557 };
558 #endif
559 
560 } // namespace util
561 
562 #endif // BITCOIN_UTIL_SYSTEM_H
int flags
Definition: bitcoin-tx.cpp:526
const auto cmd
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:245
std::optional< const Command > GetCommand() const
Get the command and command args (returns std::nullopt if no command provided)
Definition: system.cpp:450
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
Definition: system.cpp:390
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: system.cpp:560
std::list< SectionInfo > GetUnrecognizedSections() const
Log warnings for unrecognized section names in the config file.
Definition: system.cpp:265
Flags
Flags controlling how config and command line arguments are validated and interpreted.
Definition: system.h:162
@ NETWORK_ONLY
Definition: system.h:177
@ ALLOW_ANY
disable validation
Definition: system.h:163
@ DISALLOW_NEGATION
disallow -nofoo syntax
Definition: system.h:168
@ DISALLOW_ELISION
disallow -foo syntax that doesn't assign any value
Definition: system.h:169
@ DEBUG_ONLY
Definition: system.h:171
@ SENSITIVE
Definition: system.h:179
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: system.cpp:510
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: system.cpp:654
void logArgsPrefix(const std::string &prefix, const std::string &section, const std::map< std::string, std::vector< util::SettingsValue >> &args) const
Definition: system.cpp:1065
fs::path m_cached_datadir_path GUARDED_BY(cs_args)
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:287
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:470
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:553
std::optional< unsigned int > GetArgFlags(const std::string &name) const
Return Flags for known arg.
Definition: system.cpp:368
const fs::path & GetDataDirBase() const
Get data directory path.
Definition: system.h:282
std::string m_network GUARDED_BY(cs_args)
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:484
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: system.h:453
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: system.cpp:638
void SelectConfigNetwork(const std::string &network)
Select the network in use.
Definition: system.cpp:281
std::string GetHelpMessage() const
Get the help string.
Definition: system.cpp:700
void ClearPathCache()
Clear cached directory paths.
Definition: system.cpp:441
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:479
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:289
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const
Write settings file or backup settings file.
Definition: system.cpp:533
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:590
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:415
std::vector< std::string > m_command GUARDED_BY(cs_args)
void ClearArgs()
Clear available arguments.
Definition: system.h:409
fs::path GetConfigFilePath() const
Return config file path (read-only)
Definition: system.cpp:919
util::Settings m_settings GUARDED_BY(cs_args)
void AddCommand(const std::string &cmd, const std::string &help)
Add subcommand.
Definition: system.cpp:660
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: system.cpp:1059
bool m_accept_any_command GUARDED_BY(cs_args)
Definition: system.h:197
void LogArgs() const
Log the config file options and the command line arguments, useful for troubleshooting.
Definition: system.cpp:1082
RecursiveMutex cs_args
Definition: system.h:191
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:1046
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:565
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:1051
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:890
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: system.cpp:646
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:924
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:615
void AddHiddenArgs(const std::vector< std::string > &args)
Add many hidden arguments.
Definition: system.cpp:693
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:672
fs::path GetPathArg(std::string arg, const fs::path &default_value={}) const
Return path argument or default value.
Definition: system.cpp:380
std::list< SectionInfo > m_config_sections GUARDED_BY(cs_args)
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
Definition: system.cpp:1016
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:31
#define T(expected, seed, data)
bool error(const char *fmt, const Args &... args)
Definition: logging.h:261
Definition: overloaded.h:8
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:525
CRPCCommand m_command
Definition: interfaces.cpp:499
ArgsManager args
const char * prefix
Definition: rest.cpp:987
const char * name
Definition: rest.cpp:46
static RPCHelpMan help()
Definition: server.cpp:134
std::string m_help_param
Definition: system.h:186
unsigned int m_flags
Definition: system.h:188
std::string m_help_text
Definition: system.h:187
std::vector< std::string > args
If command is non-empty: Any args that followed it If command is empty: The unregistered command and ...
Definition: system.h:263
std::string command
The command (if one has been registered with AddCommand), or empty.
Definition: system.h:258
int m_line
Definition: system.h:143
std::string m_file
Definition: system.h:142
std::string m_name
Definition: system.h:141
Stored settings.
Definition: settings.h:31
#define LOCK(cs)
Definition: sync.h:258
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:769
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:774
fs::path GetDefaultDataDir()
Definition: system.cpp:795
int64_t GetStartupTime()
Definition: system.cpp:1344
OptionsCategory
Definition: system.h:121
bool LockDirectory(const fs::path &directory, const fs::path &lockfile_name, bool probe_only=false)
Definition: system.cpp:84
const char *const BITCOIN_SETTINGS_FILENAME
Definition: system.cpp:71
bool SettingToBool(const util::SettingsValue &, bool)
Definition: system.cpp:633
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:120
bool CheckDataDirOption(const ArgsManager &args)
Definition: system.cpp:820
bool RenameOver(fs::path src, fs::path dest)
Rename src to dest.
Definition: system.cpp:1094
int64_t SettingToInt(const util::SettingsValue &, int64_t)
Definition: system.cpp:610
bool SetupNetworking()
Definition: system.cpp:1326
fs::path AbsPathForConfigVal(const ArgsManager &args, 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:1349
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1357
int RaiseFileDescriptorLimit(int nMinFD)
this function tries to raise the file descriptor limit to the requested number.
Definition: system.cpp:1185
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:141
void DirectoryCommit(const fs::path &dirname)
Sync directory contents.
Definition: system.cpp:1162
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: system.cpp:114
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by create_directories if the requested directory exists.
Definition: system.cpp:1117
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:1208
ArgsManager gArgs
Definition: system.cpp:73
void SetupEnvironment()
Definition: system.cpp:1294
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: system.cpp:784
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:70
bool IsSwitchChar(char c)
Definition: system.h:112
bool TruncateFile(FILE *file, unsigned int length)
Definition: system.cpp:1173
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes=0)
Definition: system.cpp:133
int GetNumCores()
Return the number of cores available on the current system.
Definition: system.cpp:1338
fs::path GetConfigFile(const ArgsManager &args, const fs::path &configuration_file_path)
Definition: system.cpp:826
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:788
bool FileCommit(FILE *file)
Ensure file contents are fully committed to disk, using a platform-specific feature analogous to fsyn...
Definition: system.cpp:1131
void UnlockDirectory(const fs::path &directory, const fs::path &lockfile_name)
Definition: system.cpp:108
std::string SettingToString(const util::SettingsValue &, const std::string &)
Definition: system.cpp:585
std::string ShellEscape(const std::string &arg)
Definition: system.cpp:1271
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49