Bitcoin ABC  0.22.12
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 <attributes.h>
18 #include <compat.h>
19 #include <compat/assumptions.h>
20 #include <fs.h>
21 #include <logging.h>
22 #include <sync.h>
23 #include <tinyformat.h>
24 #include <util/settings.h>
25 #include <util/threadnames.h>
26 #include <util/time.h>
27 
28 #include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
29 
30 #include <cstdint>
31 #include <exception>
32 #include <map>
33 #include <set>
34 #include <string>
35 #include <utility>
36 #include <vector>
37 
38 // Application startup time (used for uptime calculation)
39 int64_t GetStartupTime();
40 
41 extern const char *const BITCOIN_CONF_FILENAME;
42 extern const char *const BITCOIN_SETTINGS_FILENAME;
43 
44 void SetupEnvironment();
45 bool SetupNetworking();
46 
47 template <typename... Args> bool error(const char *fmt, const Args &... args) {
48  LogPrintf("ERROR: %s\n", tfm::format(fmt, args...));
49  return false;
50 }
51 
52 void PrintExceptionContinue(const std::exception *pex, const char *pszThread);
53 bool FileCommit(FILE *file);
54 bool TruncateFile(FILE *file, unsigned int length);
55 int RaiseFileDescriptorLimit(int nMinFD);
56 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
57 bool RenameOver(fs::path src, fs::path dest);
58 bool LockDirectory(const fs::path &directory, const std::string lockfile_name,
59  bool probe_only = false);
60 void UnlockDirectory(const fs::path &directory,
61  const std::string &lockfile_name);
62 bool DirIsWritable(const fs::path &directory);
63 bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes = 0);
64 
72 std::streampos
73 GetFileSize(const char *path,
74  std::streamsize max = std::numeric_limits<std::streamsize>::max());
75 
81 
82 bool TryCreateDirectories(const fs::path &p);
83 fs::path GetDefaultDataDir();
84 // The blocks directory is always net specific.
85 const fs::path &GetBlocksDir();
86 const fs::path &GetDataDir(bool fNetSpecific = true);
87 // Return true if -datadir option points to a valid directory or is not
88 // specified.
89 bool CheckDataDirOption();
91 void ClearDatadirCache();
92 fs::path GetConfigFile(const std::string &confPath);
93 #ifdef WIN32
94 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
95 #endif
96 #ifndef WIN32
97 std::string ShellEscape(const std::string &arg);
98 #endif
99 #if defined(HAVE_SYSTEM)
100 void runCommand(const std::string &strCommand);
101 #endif
102 
103 NODISCARD bool ParseKeyValue(std::string &key, std::string &val);
104 
113 fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific = true);
114 
115 inline bool IsSwitchChar(char c) {
116 #ifdef WIN32
117  return c == '-' || c == '/';
118 #else
119  return c == '-';
120 #endif
121 }
122 
123 enum class OptionsCategory {
124  OPTIONS,
125  CONNECTION,
126  WALLET,
128  ZMQ,
129  DEBUG_TEST,
130  CHAINPARAMS,
131  NODE_RELAY,
133  RPC,
134  GUI,
135  COMMANDS,
137 
138  // Always the last option to avoid printing these in the help
139  HIDDEN,
140 
141  // Avalanche is still experimental, so we keep it hidden for now.
142  AVALANCHE,
143 };
144 
145 struct SectionInfo {
146  std::string m_name;
147  std::string m_file;
148  int m_line;
149 };
150 
151 class ArgsManager {
152 public:
153  enum Flags {
154  // Boolean options can accept negation syntax -noOPTION or -noOPTION=1
155  ALLOW_BOOL = 0x01,
156  ALLOW_INT = 0x02,
157  ALLOW_STRING = 0x04,
158  ALLOW_ANY = ALLOW_BOOL | ALLOW_INT | ALLOW_STRING,
159  DEBUG_ONLY = 0x100,
160  /* Some options would cause cross-contamination if values for
161  * mainnet were used while running on regtest/testnet (or vice-versa).
162  * Setting them as NETWORK_ONLY ensures that sharing a config file
163  * between mainnet and regtest/testnet won't cause problems due to these
164  * parameters by accident. */
165  NETWORK_ONLY = 0x200,
166  // This argument's value is sensitive (such as a password).
167  SENSITIVE = 0x400,
168  };
169 
170 protected:
171  struct Arg {
172  std::string m_help_param;
173  std::string m_help_text;
174  unsigned int m_flags;
175  };
176 
178  util::Settings m_settings GUARDED_BY(cs_args);
179  std::string m_network GUARDED_BY(cs_args);
180  std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
181  std::map<OptionsCategory, std::map<std::string, Arg>>
182  m_available_args GUARDED_BY(cs_args);
183  std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
184 
185  NODISCARD bool ReadConfigStream(std::istream &stream,
186  const std::string &filepath,
187  std::string &error,
188  bool ignore_invalid_keys = false);
189 
195  bool UseDefaultSection(const std::string &arg) const
196  EXCLUSIVE_LOCKS_REQUIRED(cs_args);
197 
205  util::SettingsValue GetSetting(const std::string &arg) const;
206 
210  std::vector<util::SettingsValue>
211  GetSettingsList(const std::string &arg) const;
212 
213 public:
214  ArgsManager();
215  ~ArgsManager();
216 
220  void SelectConfigNetwork(const std::string &network);
221 
222  NODISCARD bool ParseParameters(int argc, const char *const argv[],
223  std::string &error);
224  NODISCARD bool ReadConfigFiles(std::string &error,
225  bool ignore_invalid_keys = false);
226 
232  const std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
233 
237  const std::list<SectionInfo> GetUnrecognizedSections() const;
238 
245  std::vector<std::string> GetArgs(const std::string &strArg) const;
246 
253  bool IsArgSet(const std::string &strArg) const;
254 
262  bool IsArgNegated(const std::string &strArg) const;
263 
271  std::string GetArg(const std::string &strArg,
272  const std::string &strDefault) const;
273 
281  int64_t GetArg(const std::string &strArg, int64_t nDefault) const;
282 
290  bool GetBoolArg(const std::string &strArg, bool fDefault) const;
291 
299  bool SoftSetArg(const std::string &strArg, const std::string &strValue);
300 
308  bool SoftSetBoolArg(const std::string &strArg, bool fValue);
309 
310  // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
311  // been set. Also called directly in testing.
312  void ForceSetArg(const std::string &strArg, const std::string &strValue);
313 
314  // Forces a multi arg setting, used only in testing
315  void ForceSetMultiArg(const std::string &strArg,
316  const std::vector<std::string> &values);
317 
324  std::string GetChainName() const;
325 
329  void AddArg(const std::string &name, const std::string &help,
330  unsigned int flags, const OptionsCategory &cat);
331 
335  void ClearForcedArg(const std::string &strArg);
336 
340  void AddHiddenArgs(const std::vector<std::string> &args);
341 
345  void ClearArgs() {
346  LOCK(cs_args);
347  m_available_args.clear();
348  m_network_only_args.clear();
349  }
350 
354  std::string GetHelpMessage() const;
355 
360  std::optional<unsigned int> GetArgFlags(const std::string &name) const;
361 
367  bool InitSettings(std::string &error);
368 
373  bool GetSettingsPath(fs::path *filepath = nullptr, bool temp = false) const;
374 
378  bool ReadSettingsFile(std::vector<std::string> *errors = nullptr);
379 
383  bool WriteSettingsFile(std::vector<std::string> *errors = nullptr) const;
384 
388  template <typename Fn> void LockSettings(Fn &&fn) {
389  LOCK(cs_args);
390  fn(m_settings);
391  }
392 
397  void LogArgs() const;
398 
399 private:
400  // Helper function for LogArgs().
401  void
402  logArgsPrefix(const std::string &prefix, const std::string &section,
403  const std::map<std::string, std::vector<util::SettingsValue>>
404  &args) const;
405 };
406 
407 extern ArgsManager gArgs;
408 
412 bool HelpRequested(const ArgsManager &args);
413 
415 void SetupHelpOptions(ArgsManager &args);
416 
423 std::string HelpMessageGroup(const std::string &message);
424 
432 std::string HelpMessageOpt(const std::string &option,
433  const std::string &message);
434 
440 int GetNumCores();
441 
445 template <typename Callable> void TraceThread(const char *name, Callable func) {
446  util::ThreadRename(name);
447  try {
448  LogPrintf("%s thread start\n", name);
449  func();
450  LogPrintf("%s thread exit\n", name);
451  } catch (const boost::thread_interrupted &) {
452  LogPrintf("%s thread interrupt\n", name);
453  throw;
454  } catch (const std::exception &e) {
455  PrintExceptionContinue(&e, name);
456  throw;
457  } catch (...) {
458  PrintExceptionContinue(nullptr, name);
459  throw;
460  }
461 }
462 
463 std::string CopyrightHolders(const std::string &strPrefix);
464 
470 void ScheduleBatchPriority();
471 
472 namespace util {
473 
475 template <typename Tdst, typename Tsrc>
476 inline void insert(Tdst &dst, const Tsrc &src) {
477  dst.insert(dst.begin(), src.begin(), src.end());
478 }
479 template <typename TsetT, typename Tsrc>
480 inline void insert(std::set<TsetT> &dst, const Tsrc &src) {
481  dst.insert(src.begin(), src.end());
482 }
483 
484 #ifdef WIN32
485 class WinCmdLineArgs {
486 public:
487  WinCmdLineArgs();
488  ~WinCmdLineArgs();
489  std::pair<int, char **> get();
490 
491 private:
492  int argc;
493  char **argv;
494  std::vector<std::string> args;
495 };
496 #endif
497 
498 } // namespace util
499 
500 #endif // BITCOIN_UTIL_SYSTEM_H
Stored settings.
Definition: settings.h:31
static UniValue help(Config &config, const JSONRPCRequest &jsonRequest)
Definition: server.cpp:175
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:1352
bool TruncateFile(FILE *file, unsigned int length)
Definition: system.cpp:1156
Definition: httprpc.h:13
void SetupEnvironment()
Definition: system.cpp:1287
unsigned int m_flags
Definition: system.h:174
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:812
const char * prefix
Definition: rest.cpp:754
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:130
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:48
int m_line
Definition: system.h:148
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:171
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1359
RecursiveMutex cs_args
Definition: system.h:177
bool RenameOver(fs::path src, fs::path dest)
Definition: system.cpp:1091
const fs::path & GetBlocksDir()
Definition: system.cpp:734
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:657
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:149
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:1195
std::string m_name
Definition: system.h:146
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:697
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:127
int RaiseFileDescriptorLimit(int nMinFD)
This function tries to raise the file descriptor limit to the requested number.
Definition: system.cpp:1169
const fs::path & GetDataDir(bool fNetSpecific=true)
Definition: system.cpp:760
int64_t GetStartupTime()
Server/client environment: argument handling, config file parsing, thread wrappers, startup time.
Definition: system.cpp:1348
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:191
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:73
bool FileCommit(FILE *file)
Definition: system.cpp:1120
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes=0)
Definition: system.cpp:141
#define NODISCARD
Definition: attributes.h:18
#define LOCK(cs)
Definition: sync.h:230
const char * name
Definition: rest.cpp:43
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:1111
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:652
bool CheckDataDirOption()
Definition: system.cpp:799
std::string m_file
Definition: system.h:147
void ClearArgs()
Clear available arguments.
Definition: system.h:345
std::string m_help_text
Definition: system.h:173
void TraceThread(const char *name, Callable func)
Definition: system.h:445
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: system.cpp:667
int flags
Definition: bitcoin-tx.cpp:529
const char *const BITCOIN_SETTINGS_FILENAME
Definition: system.cpp:74
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
fs::path GetDefaultDataDir()
Definition: system.cpp:703
void ClearDatadirCache()
Tests only.
Definition: system.cpp:804
void UnlockDirectory(const fs::path &directory, const std::string &lockfile_name)
Definition: system.cpp:116
#define GUARDED_BY(x)
Definition: threadsafety.h:45
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost&#39;s create_directories if the requested directory exists...
Definition: system.cpp:1106
bool IsSwitchChar(char c)
Definition: system.h:115
OptionsCategory
Definition: system.h:123
std::string CopyrightHolders(const std::string &strPrefix)
Definition: system.cpp:1342
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: system.h:388
std::string m_help_param
Definition: system.h:172
void insert(std::set< TsetT > &dst, const Tsrc &src)
Definition: system.h:480
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:671
bool LockDirectory(const fs::path &directory, const std::string lockfile_name, bool probe_only=false)
Definition: system.cpp:88
ArgsManager gArgs
Definition: system.cpp:76
bool error(const char *fmt, const Args &... args)
Definition: system.h:47
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: system.cpp:122
std::string ShellEscape(const std::string &arg)
Definition: system.cpp:1260
int GetNumCores()
Return the number of cores available on the current system.
Definition: system.cpp:1338
NODISCARD bool ParseKeyValue(std::string &key, std::string &val)
Definition: system.cpp:294
bool SetupNetworking()
Definition: system.cpp:1325