Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin developers
3 : // Copyright (c) 2014-2015 The Dash developers
4 : // Copyright (c) 2015-2022 The PIVX Core developers
5 : // Distributed under the MIT software license, see the accompanying
6 : // file COPYING or https://www.opensource.org/licenses/mit-license.php.
7 :
8 : /**
9 : * Server/client environment: argument handling, config file parsing,
10 : * thread wrappers
11 : */
12 : #ifndef PIVX_UTIL_SYSTEM_H
13 : #define PIVX_UTIL_SYSTEM_H
14 :
15 : #if defined(HAVE_CONFIG_H)
16 : #include "config/pivx-config.h"
17 : #endif
18 :
19 : #include "fs.h"
20 : #include "logging.h"
21 : #include "compat.h"
22 : #include "optional.h"
23 : #include "sync.h"
24 : #include "tinyformat.h"
25 : #include "utiltime.h"
26 : #include "util/threadnames.h"
27 :
28 : #include <atomic>
29 : #include <exception>
30 : #include <map>
31 : #include <memory>
32 : #include <set>
33 : #include <stdint.h>
34 : #include <string>
35 : #include <unordered_set>
36 : #include <utility>
37 : #include <vector>
38 :
39 : #include <boost/signals2/signal.hpp>
40 : #include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
41 :
42 : /** Signals for translation. */
43 : class CTranslationInterface
44 : {
45 : public:
46 : /** Translate a message to the native language of the user. */
47 : boost::signals2::signal<std::string (const char* psz)> Translate;
48 : };
49 :
50 : extern const char * const PIVX_CONF_FILENAME;
51 : extern const char * const PIVX_PID_FILENAME;
52 : extern const char * const PIVX_MASTERNODE_CONF_FILENAME;
53 : extern const char * const DEFAULT_DEBUGLOGFILE;
54 :
55 : //PIVX only features
56 :
57 : extern std::atomic<bool> fMasterNode;
58 :
59 : extern CTranslationInterface translationInterface;
60 :
61 : /**
62 : * Translation function: Call Translate signal on UI interface, which returns a Optional result.
63 : * If no translation slot is registered, nothing is returned, and simply return the input.
64 : */
65 309169 : inline std::string _(const char* psz)
66 : {
67 : // todo: this Optional is needed for now. Will get removed moving forward
68 309169 : Optional<std::string> rv = translationInterface.Translate(psz);
69 309169 : return rv ? (*rv) : psz;
70 : }
71 :
72 :
73 : void SetupEnvironment();
74 : bool SetupNetworking();
75 :
76 : template<typename... Args>
77 26989 : bool error(const char* fmt, const Args&... args)
78 : {
79 26989 : LogPrintf("ERROR: %s\n", tfm::format(fmt, args...));
80 26989 : return false;
81 : }
82 :
83 : void PrintExceptionContinue(const std::exception* pex, const char* pszThread);
84 : bool FileCommit(FILE* file);
85 : bool TruncateFile(FILE* file, unsigned int length);
86 : int RaiseFileDescriptorLimit(int nMinFD);
87 : void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length);
88 : bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
89 : bool RenameOver(fs::path src, fs::path dest);
90 : bool LockDirectory(const fs::path& directory, const std::string& lockfile_name, bool probe_only=false);
91 : bool DirIsWritable(const fs::path& directory);
92 :
93 : /** Release all directory locks. This is used for unit testing only, at runtime
94 : * the global destructor will take care of the locks.
95 : */
96 : void ReleaseDirectoryLocks();
97 :
98 : bool TryCreateDirectories(const fs::path& p);
99 : fs::path GetDefaultDataDir();
100 : // The blocks directory is always net specific.
101 : const fs::path &GetBlocksDir();
102 : const fs::path &GetDataDir(bool fNetSpecific = true);
103 : // Return true if -datadir option points to a valid directory or is not specified.
104 : bool CheckDataDirOption();
105 : // Sapling network dir
106 : const fs::path &ZC_GetParamsDir();
107 : // Init sapling library
108 : void initZKSNARKS();
109 : void ClearDatadirCache();
110 : fs::path GetConfigFile(const std::string& confPath);
111 : fs::path GetMasternodeConfigFile();
112 : #ifdef WIN32
113 : fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
114 : #endif
115 :
116 : void runCommand(std::string strCommand);
117 :
118 3682 : inline bool IsSwitchChar(char c)
119 : {
120 : #ifdef WIN32
121 : return c == '-' || c == '/';
122 : #else
123 3682 : return c == '-';
124 : #endif
125 : }
126 :
127 : class ArgsManager
128 : {
129 : protected:
130 : friend class ArgsManagerHelper;
131 :
132 : mutable RecursiveMutex cs_args;
133 : std::map<std::string, std::vector<std::string>> m_override_args;
134 : std::map<std::string, std::vector<std::string>> m_config_args;
135 : std::string m_network;
136 : std::set<std::string> m_network_only_args;
137 :
138 : void ReadConfigStream(std::istream& stream);
139 :
140 : public:
141 : ArgsManager();
142 :
143 : /**
144 : * Select the network in use
145 : */
146 : void SelectConfigNetwork(const std::string& network);
147 :
148 : void ParseParameters(int argc, const char* const argv[]);
149 : void ReadConfigFile(const std::string& confPath);
150 :
151 : /**
152 : * Log warnings for options in m_section_only_args when
153 : * they are specified in the default section but not overridden
154 : * on the command line or in a network-specific section in the
155 : * config file.
156 : */
157 : void WarnForSectionOnlyArgs();
158 :
159 : /**
160 : * Return a vector of strings of the given argument
161 : *
162 : * @param strArg Argument to get (e.g. "-foo")
163 : * @return command-line arguments
164 : */
165 : std::vector<std::string> GetArgs(const std::string& strArg) const;
166 :
167 : /**
168 : * Return true if the given argument has been manually set
169 : *
170 : * @param strArg Argument to get (e.g. "-foo")
171 : * @return true if the argument has been set
172 : */
173 : bool IsArgSet(const std::string& strArg) const;
174 :
175 : /**
176 : * Return true if the argument was originally passed as a negated option,
177 : * i.e. -nofoo.
178 : *
179 : * @param strArg Argument to get (e.g. "-foo")
180 : * @return true if the argument was passed negated
181 : */
182 : bool IsArgNegated(const std::string& strArg) const;
183 :
184 : /**
185 : * Return string argument or default value
186 : *
187 : * @param strArg Argument to get (e.g. "-foo")
188 : * @param default (e.g. "1")
189 : * @return command-line argument or default value
190 : */
191 : std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
192 :
193 : /**
194 : * Return integer argument or default value
195 : *
196 : * @param strArg Argument to get (e.g. "-foo")
197 : * @param default (e.g. 1)
198 : * @return command-line argument (0 if invalid number) or default value
199 : */
200 : int64_t GetArg(const std::string& strArg, int64_t nDefault) const;
201 :
202 : /**
203 : * Return boolean argument or default value
204 : *
205 : * @param strArg Argument to get (e.g. "-foo")
206 : * @param default (true or false)
207 : * @return command-line argument or default value
208 : */
209 : bool GetBoolArg(const std::string& strArg, bool fDefault) const;
210 :
211 : /**
212 : * Set an argument if it doesn't already have a value
213 : *
214 : * @param strArg Argument to set (e.g. "-foo")
215 : * @param strValue Value (e.g. "1")
216 : * @return true if argument gets set, false if it already had a value
217 : */
218 : bool SoftSetArg(const std::string& strArg, const std::string& strValue);
219 :
220 : /**
221 : * Set a boolean argument if it doesn't already have a value
222 : *
223 : * @param strArg Argument to set (e.g. "-foo")
224 : * @param fValue Value (e.g. false)
225 : * @return true if argument gets set, false if it already had a value
226 : */
227 : bool SoftSetBoolArg(const std::string& strArg, bool fValue);
228 :
229 : // Forces a arg setting, used only in testing
230 : void ForceSetArg(const std::string& strArg, const std::string& strValue);
231 :
232 : /**
233 : * Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
234 : * @return CBaseChainParams::MAIN by default; raises runtime error if an invalid combination is given.
235 : */
236 : std::string GetChainName() const;
237 : };
238 :
239 : extern ArgsManager gArgs;
240 :
241 : /**
242 : * Format a string to be used as group of options in help messages
243 : *
244 : * @param message Group name (e.g. "RPC server options:")
245 : * @return the formatted string
246 : */
247 : std::string HelpMessageGroup(const std::string& message);
248 :
249 : /**
250 : * Format a string to be used as option description in help messages
251 : *
252 : * @param option Option message (e.g. "-rpcuser=<user>")
253 : * @param message Option description (e.g. "Username for JSON-RPC connections")
254 : * @return the formatted string
255 : */
256 : std::string HelpMessageOpt(const std::string& option, const std::string& message);
257 :
258 : /**
259 : * Return the number of cores available on the current system.
260 : * @note This does count virtual cores, such as those provided by HyperThreading.
261 : */
262 : int GetNumCores();
263 :
264 : void SetThreadPriority(int nPriority);
265 :
266 : /**
267 : * .. and a wrapper that just calls func once
268 : */
269 : template <typename Callable>
270 3374 : void TraceThread(const std::string name, Callable func)
271 : {
272 3374 : std::string s = "pivx-" + name;
273 3374 : util::ThreadRename(s.c_str());
274 : try {
275 3374 : LogPrintf("%s thread start\n", name);
276 3374 : func();
277 3374 : LogPrintf("%s thread exit\n", name);
278 0 : } catch (boost::thread_interrupted) {
279 0 : LogPrintf("%s thread interrupt\n", name);
280 0 : throw;
281 0 : } catch (std::exception& e) {
282 0 : PrintExceptionContinue(&e, name.c_str());
283 0 : throw;
284 0 : } catch (...) {
285 0 : PrintExceptionContinue(nullptr, name.c_str());
286 0 : throw;
287 : }
288 3374 : }
289 :
290 : fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific = true);
291 :
292 : /**
293 : * On platforms that support it, tell the kernel the calling thread is
294 : * CPU-intensive and non-interactive. See SCHED_BATCH in sched(7) for details.
295 : *
296 : * @return The return value of sched_setschedule(), or 1 on systems without
297 : * sched_setchedule().
298 : */
299 : int ScheduleBatchPriority(void);
300 :
301 : namespace util {
302 :
303 : #ifdef WIN32
304 : class WinCmdLineArgs
305 : {
306 : public:
307 : WinCmdLineArgs();
308 : ~WinCmdLineArgs();
309 : std::pair<int, char**> get();
310 :
311 : private:
312 : int argc;
313 : char** argv;
314 : std::vector<std::string> args;
315 : };
316 : #endif
317 :
318 : } // namespace util
319 :
320 : #endif // PIVX_UTIL_SYSTEM_H
|