Bitcoin Core 22.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)
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/time.h>
26
27#include <any>
28#include <exception>
29#include <map>
30#include <optional>
31#include <set>
32#include <stdint.h>
33#include <string>
34#include <utility>
35#include <vector>
36
37class UniValue;
38
39// Application startup time (used for uptime calculation)
40int64_t GetStartupTime();
41
42extern const char * const BITCOIN_CONF_FILENAME;
43extern const char * const BITCOIN_SETTINGS_FILENAME;
44
45void SetupEnvironment();
46bool SetupNetworking();
47
48template<typename... Args>
49bool error(const char* fmt, const Args&... args)
50{
51 LogPrintf("ERROR: %s\n", tfm::format(fmt, args...));
52 return false;
53}
54
55void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
56
61bool FileCommit(FILE *file);
62
67void DirectoryCommit(const fs::path &dirname);
68
69bool TruncateFile(FILE *file, unsigned int length);
70int RaiseFileDescriptorLimit(int nMinFD);
71void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
72[[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
73bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false);
74void UnlockDirectory(const fs::path& directory, const std::string& lockfile_name);
75bool DirIsWritable(const fs::path& directory);
76bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
77
84std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
85
90
91bool TryCreateDirectories(const fs::path& p);
93// Return true if -datadir option points to a valid directory or is not specified.
95fs::path GetConfigFile(const std::string& confPath);
96#ifdef WIN32
97fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
98#endif
99#ifndef WIN32
100std::string ShellEscape(const std::string& arg);
101#endif
102#if HAVE_SYSTEM
103void runCommand(const std::string& strCommand);
104#endif
112UniValue RunCommandParseJSON(const std::string& str_command, const std::string& str_std_in="");
113
122fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific = true);
123
124inline bool IsSwitchChar(char c)
125{
126#ifdef WIN32
127 return c == '-' || c == '/';
128#else
129 return c == '-';
130#endif
131}
132
133enum class OptionsCategory {
134 OPTIONS,
136 WALLET,
138 ZMQ,
143 RPC,
144 GUI,
145 COMMANDS,
147
148 HIDDEN // Always the last option to avoid printing these in the help
149};
150
152{
153 std::string m_name;
154 std::string m_file;
156};
157
159{
160public:
165 enum Flags : uint32_t {
166 ALLOW_ANY = 0x01,
167 // ALLOW_BOOL = 0x02, //!< unimplemented, draft implementation in #16545
168 // ALLOW_INT = 0x04, //!< unimplemented, draft implementation in #16545
169 // ALLOW_STRING = 0x08, //!< unimplemented, draft implementation in #16545
170 // ALLOW_LIST = 0x10, //!< unimplemented, draft implementation in #16545
172
173 DEBUG_ONLY = 0x100,
174 /* Some options would cause cross-contamination if values for
175 * mainnet were used while running on regtest/testnet (or vice-versa).
176 * Setting them as NETWORK_ONLY ensures that sharing a config file
177 * between mainnet and regtest/testnet won't cause problems due to these
178 * parameters by accident. */
180 // This argument's value is sensitive (such as a password).
181 SENSITIVE = 0x400,
182 COMMAND = 0x800,
183 };
184
185protected:
186 struct Arg
187 {
188 std::string m_help_param;
189 std::string m_help_text;
190 unsigned int m_flags;
191 };
192
195 std::vector<std::string> m_command GUARDED_BY(cs_args);
196 std::string m_network GUARDED_BY(cs_args);
197 std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
198 std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
199 bool m_accept_any_command GUARDED_BY(cs_args){true};
200 std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
201 mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args);
202 mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args);
203 mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args);
204
205 [[nodiscard]] bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false);
206
212 bool UseDefaultSection(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
213
214 public:
222 util::SettingsValue GetSetting(const std::string& arg) const;
223
227 std::vector<util::SettingsValue> GetSettingsList(const std::string& arg) const;
228
229 ArgsManager();
230 ~ArgsManager();
231
235 void SelectConfigNetwork(const std::string& network);
236
237 [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error);
238 [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
239
246 const std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
247
251 const std::list<SectionInfo> GetUnrecognizedSections() const;
252
253 struct Command {
255 std::string command;
260 std::vector<std::string> args;
261 };
265 std::optional<const Command> GetCommand() const;
266
272 const fs::path& GetBlocksDirPath() const;
273
280 const fs::path& GetDataDirBase() const { return GetDataDir(false); }
281
288 const fs::path& GetDataDirNet() const { return GetDataDir(true); }
289
293 void ClearPathCache();
294
301 std::vector<std::string> GetArgs(const std::string& strArg) const;
302
309 bool IsArgSet(const std::string& strArg) const;
310
318 bool IsArgNegated(const std::string& strArg) const;
319
327 std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
328
336 int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const;
337
345 bool GetBoolArg(const std::string& strArg, bool fDefault) const;
346
354 bool SoftSetArg(const std::string& strArg, const std::string& strValue);
355
363 bool SoftSetBoolArg(const std::string& strArg, bool fValue);
364
365 // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
366 // been set. Also called directly in testing.
367 void ForceSetArg(const std::string& strArg, const std::string& strValue);
368
373 std::string GetChainName() const;
374
378 void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat);
379
383 void AddCommand(const std::string& cmd, const std::string& help);
384
388 void AddHiddenArgs(const std::vector<std::string>& args);
389
393 void ClearArgs() {
394 LOCK(cs_args);
395 m_available_args.clear();
396 m_network_only_args.clear();
397 }
398
402 std::string GetHelpMessage() const;
403
408 std::optional<unsigned int> GetArgFlags(const std::string& name) const;
409
415 bool InitSettings(std::string& error);
416
421 bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false) const;
422
426 bool ReadSettingsFile(std::vector<std::string>* errors = nullptr);
427
431 bool WriteSettingsFile(std::vector<std::string>* errors = nullptr) const;
432
436 template <typename Fn>
437 void LockSettings(Fn&& fn)
438 {
439 LOCK(cs_args);
440 fn(m_settings);
441 }
442
447 void LogArgs() const;
448
449private:
457 const fs::path& GetDataDir(bool net_specific) const;
458
459 // Helper function for LogArgs().
460 void logArgsPrefix(
461 const std::string& prefix,
462 const std::string& section,
463 const std::map<std::string, std::vector<util::SettingsValue>>& args) const;
464};
465
466extern ArgsManager gArgs;
467
471bool HelpRequested(const ArgsManager& args);
472
474void SetupHelpOptions(ArgsManager& args);
475
482std::string HelpMessageGroup(const std::string& message);
483
491std::string HelpMessageOpt(const std::string& option, const std::string& message);
492
497int GetNumCores();
498
499std::string CopyrightHolders(const std::string& strPrefix);
500
507
508namespace util {
509
511template <typename Tdst, typename Tsrc>
512inline void insert(Tdst& dst, const Tsrc& src) {
513 dst.insert(dst.begin(), src.begin(), src.end());
514}
515template <typename TsetT, typename Tsrc>
516inline void insert(std::set<TsetT>& dst, const Tsrc& src) {
517 dst.insert(src.begin(), src.end());
518}
519
525template<typename T>
526T* AnyPtr(const std::any& any) noexcept
527{
528 T* const* ptr = std::any_cast<T*>(&any);
529 return ptr ? *ptr : nullptr;
530}
531
532#ifdef WIN32
533class WinCmdLineArgs
534{
535public:
536 WinCmdLineArgs();
537 ~WinCmdLineArgs();
538 std::pair<int, char**> get();
539
540private:
541 int argc;
542 char** argv;
543 std::vector<std::string> args;
544};
545#endif
546
547} // namespace util
548
549#endif // BITCOIN_UTIL_SYSTEM_H
void help(char **argv)
Definition: bench_ecmult.c:21
int flags
Definition: bitcoin-tx.cpp:525
const fs::path & GetDataDirBase() const
Get data directory path.
Definition: system.h:280
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:266
std::optional< const Command > GetCommand() const
Get the command and command args (returns std::nullopt if no command provided)
Definition: system.cpp:467
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
Definition: system.cpp:401
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: system.cpp:585
std::map< OptionsCategory, std::map< std::string, Arg > > m_available_args GUARDED_BY(cs_args)
Flags
Flags controlling how config and command line arguments are validated and interpreted.
Definition: system.h:165
@ NETWORK_ONLY
Definition: system.h:179
@ ALLOW_ANY
disable validation
Definition: system.h:166
@ DISALLOW_NEGATION
disallow -nofoo syntax
Definition: system.h:171
@ DEBUG_ONLY
Definition: system.h:173
@ SENSITIVE
Definition: system.h:181
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: system.cpp:542
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: system.cpp:624
bool InitSettings(std::string &error)
Read and update settings file with saved settings.
Definition: system.cpp:501
fs::path m_cached_datadir_path GUARDED_BY(cs_args)
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr) const
Write settings file.
Definition: system.cpp:565
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:308
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:487
std::optional< unsigned int > GetArgFlags(const std::string &name) const
Return Flags for known arg.
Definition: system.cpp:389
std::list< SectionInfo > m_config_sections GUARDED_BY(cs_args)
std::string m_network GUARDED_BY(cs_args)
~ArgsManager()
Definition: system.cpp:264
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: system.h:437
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: system.cpp:608
void SelectConfigNetwork(const std::string &network)
Select the network in use.
Definition: system.cpp:302
std::string GetHelpMessage() const
Get the help string.
Definition: system.cpp:670
void ClearPathCache()
Clear cached directory paths.
Definition: system.cpp:458
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:496
std::set< std::string > m_network_only_args GUARDED_BY(cs_args)
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:288
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:596
std::vector< std::string > m_command GUARDED_BY(cs_args)
const fs::path & GetDataDir(bool net_specific) const
Get data directory path.
Definition: system.cpp:427
void ClearArgs()
Clear available arguments.
Definition: system.h:393
void logArgsPrefix(const std::string &prefix, const std::string &section, const std::map< std::string, std::vector< util::SettingsValue > > &args) const
Definition: system.cpp:1036
util::Settings m_settings GUARDED_BY(cs_args)
void AddCommand(const std::string &cmd, const std::string &help)
Add subcommand.
Definition: system.cpp:630
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: system.cpp:1030
bool GetSettingsPath(fs::path *filepath=nullptr, bool temp=false) const
Get settings file path, or return false if read-write settings were disabled with -nosettings.
Definition: system.cpp:519
bool m_accept_any_command GUARDED_BY(cs_args)
Definition: system.h:199
void LogArgs() const
Log the config file options and the command line arguments, useful for troubleshooting.
Definition: system.cpp:1053
RecursiveMutex cs_args
Definition: system.h:193
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:1018
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:590
util::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: system.cpp:1023
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:869
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: system.cpp:616
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:897
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:602
void AddHiddenArgs(const std::vector< std::string > &args)
Add many hidden arguments.
Definition: system.cpp:663
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:642
const std::list< SectionInfo > GetUnrecognizedSections() const
Log warnings for unrecognized section names in the config file.
Definition: system.cpp:286
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
Definition: system.cpp:989
Path class wrapper to prepare application code for transition from boost::filesystem library to std::...
Definition: fs.h:34
#define T(expected, seed, data)
#define LogPrintf(...)
Definition: logging.h:187
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
T * AnyPtr(const std::any &any) noexcept
Helper function to access the contained object of a std::any instance.
Definition: system.h:526
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
Definition: system.h:512
CRPCCommand m_command
Definition: interfaces.cpp:425
const char * prefix
Definition: rest.cpp:714
const char * name
Definition: rest.cpp:43
std::string m_help_param
Definition: system.h:188
unsigned int m_flags
Definition: system.h:190
std::string m_help_text
Definition: system.h:189
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:260
std::string command
The command (if one has been registered with AddCommand), or empty.
Definition: system.h:255
int m_line
Definition: system.h:155
std::string m_file
Definition: system.h:154
std::string m_name
Definition: system.h:153
Stored settings.
Definition: settings.h:31
#define LOCK(cs)
Definition: sync.h:226
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:739
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:744
fs::path GetDefaultDataDir()
Definition: system.cpp:788
int64_t GetStartupTime()
Definition: system.cpp:1363
OptionsCategory
Definition: system.h:133
const char *const BITCOIN_SETTINGS_FILENAME
Definition: system.cpp:83
std::string CopyrightHolders(const std::string &strPrefix)
Definition: system.cpp:1350
void UnlockDirectory(const fs::path &directory, const std::string &lockfile_name)
Definition: system.cpp:120
bool CheckDataDirOption()
Definition: system.cpp:813
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:132
bool RenameOver(fs::path src, fs::path dest)
Definition: system.cpp:1065
bool SetupNetworking()
Definition: system.cpp:1333
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1376
int RaiseFileDescriptorLimit(int nMinFD)
this function tries to raise the file descriptor limit to the requested number.
Definition: system.cpp:1149
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 DirectoryCommit(const fs::path &dirname)
Sync directory contents.
Definition: system.cpp:1126
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: system.cpp:126
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:1257
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost's create_directories if the requested directory exists.
Definition: system.cpp:1081
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:1172
ArgsManager gArgs
Definition: system.cpp:85
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:1368
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
void SetupEnvironment()
Definition: system.cpp:1296
bool LockDirectory(const fs::path &directory, const std::string lockfile_name, bool probe_only=false)
Definition: system.cpp:96
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:819
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:781
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: system.cpp:754
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:82
bool IsSwitchChar(char c)
Definition: system.h:124
bool TruncateFile(FILE *file, unsigned int length)
Definition: system.cpp:1137
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:1345
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:758
bool FileCommit(FILE *file)
Ensure file contents are fully committed to disk, using a platform-specific feature analogous to fsyn...
Definition: system.cpp:1095
std::string ShellEscape(const std::string &arg)
Definition: system.cpp:1235
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49