1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
7 * Server/client environment: argument handling, config file parsing,
8 * logging, thread wrappers, startup time
10 #ifndef BITCOIN_UTIL_H
11 #define BITCOIN_UTIL_H
13 #if defined(HAVE_CONFIG_H)
14 #include <config/bitcoin-config.h>
20 #include <tinyformat.h>
30 #include <boost/signals2/signal.hpp>
31 #include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
33 // Application startup time (used for uptime calculation)
34 int64_t GetStartupTime();
36 static const bool DEFAULT_LOGTIMEMICROS
= false;
37 static const bool DEFAULT_LOGIPS
= false;
38 static const bool DEFAULT_LOGTIMESTAMPS
= true;
39 extern const char * const DEFAULT_DEBUGLOGFILE
;
41 /** Signals for translation. */
42 class CTranslationInterface
45 /** Translate a message to the native language of the user. */
46 boost::signals2::signal
<std::string (const char* psz
)> Translate
;
49 extern bool fPrintToConsole
;
50 extern bool fPrintToDebugLog
;
52 extern bool fLogTimestamps
;
53 extern bool fLogTimeMicros
;
55 extern std::atomic
<bool> fReopenDebugLog
;
56 extern CTranslationInterface translationInterface
;
58 extern const char * const BITCOIN_CONF_FILENAME
;
59 extern const char * const BITCOIN_PID_FILENAME
;
61 extern std::atomic
<uint32_t> logCategories
;
64 * Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
65 * If no translation slot is registered, nothing is returned, and simply return the input.
67 inline std::string
_(const char* psz
)
69 boost::optional
<std::string
> rv
= translationInterface
.Translate(psz
);
70 return rv
? (*rv
) : psz
;
73 void SetupEnvironment();
74 bool SetupNetworking();
76 struct CLogCategoryActive
83 enum LogFlags
: uint32_t {
93 ESTIMATEFEE
= (1 << 8),
95 SELECTCOINS
= (1 << 10),
97 CMPCTBLOCK
= (1 << 12),
101 MEMPOOLREJ
= (1 << 16),
102 LIBEVENT
= (1 << 17),
109 /** Return true if log accepts specified category */
110 static inline bool LogAcceptCategory(uint32_t category
)
112 return (logCategories
.load(std::memory_order_relaxed
) & category
) != 0;
115 /** Returns a string with the log categories. */
116 std::string
ListLogCategories();
118 /** Returns a vector of the active log categories. */
119 std::vector
<CLogCategoryActive
> ListActiveLogCategories();
121 /** Return true if str parses as a log category and set the flags in f */
122 bool GetLogCategory(uint32_t *f
, const std::string
*str
);
124 /** Send a string to the log output */
125 int LogPrintStr(const std::string
&str
);
127 /** Get format string from VA_ARGS for error reporting */
128 template<typename
... Args
> std::string
FormatStringFromLogArgs(const char *fmt
, const Args
&... args
) { return fmt
; }
130 static inline void MarkUsed() {}
131 template<typename T
, typename
... Args
> static inline void MarkUsed(const T
& t
, const Args
&... args
)
138 #define LogPrintf(...) do { MarkUsed(__VA_ARGS__); } while(0)
139 #define LogPrint(category, ...) do { MarkUsed(__VA_ARGS__); } while(0)
141 #define LogPrintf(...) do { \
142 std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \
144 _log_msg_ = tfm::format(__VA_ARGS__); \
145 } catch (tinyformat::format_error &fmterr) { \
146 /* Original format string will have newline so don't add one here */ \
147 _log_msg_ = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + FormatStringFromLogArgs(__VA_ARGS__); \
149 LogPrintStr(_log_msg_); \
152 #define LogPrint(category, ...) do { \
153 if (LogAcceptCategory((category))) { \
154 LogPrintf(__VA_ARGS__); \
159 template<typename
... Args
>
160 bool error(const char* fmt
, const Args
&... args
)
162 LogPrintStr("ERROR: " + tfm::format(fmt
, args
...) + "\n");
166 void PrintExceptionContinue(const std::exception
*pex
, const char* pszThread
);
167 void FileCommit(FILE *file
);
168 bool TruncateFile(FILE *file
, unsigned int length
);
169 int RaiseFileDescriptorLimit(int nMinFD
);
170 void AllocateFileRange(FILE *file
, unsigned int offset
, unsigned int length
);
171 bool RenameOver(fs::path src
, fs::path dest
);
172 bool TryCreateDirectories(const fs::path
& p
);
173 fs::path
GetDefaultDataDir();
174 const fs::path
&GetDataDir(bool fNetSpecific
= true);
175 void ClearDatadirCache();
176 fs::path
GetConfigFile(const std::string
& confPath
);
178 fs::path
GetPidFile();
179 void CreatePidFile(const fs::path
&path
, pid_t pid
);
182 fs::path
GetSpecialFolderPath(int nFolder
, bool fCreate
= true);
184 fs::path
GetDebugLogPath();
186 void ShrinkDebugFile();
187 void runCommand(const std::string
& strCommand
);
189 inline bool IsSwitchChar(char c
)
192 return c
== '-' || c
== '/';
201 mutable CCriticalSection cs_args
;
202 std::map
<std::string
, std::string
> mapArgs
;
203 std::map
<std::string
, std::vector
<std::string
>> mapMultiArgs
;
205 void ParseParameters(int argc
, const char*const argv
[]);
206 void ReadConfigFile(const std::string
& confPath
);
209 * Return a vector of strings of the given argument
211 * @param strArg Argument to get (e.g. "-foo")
212 * @return command-line arguments
214 std::vector
<std::string
> GetArgs(const std::string
& strArg
) const;
217 * Return true if the given argument has been manually set
219 * @param strArg Argument to get (e.g. "-foo")
220 * @return true if the argument has been set
222 bool IsArgSet(const std::string
& strArg
) const;
225 * Return string argument or default value
227 * @param strArg Argument to get (e.g. "-foo")
228 * @param strDefault (e.g. "1")
229 * @return command-line argument or default value
231 std::string
GetArg(const std::string
& strArg
, const std::string
& strDefault
) const;
234 * Return integer argument or default value
236 * @param strArg Argument to get (e.g. "-foo")
237 * @param nDefault (e.g. 1)
238 * @return command-line argument (0 if invalid number) or default value
240 int64_t GetArg(const std::string
& strArg
, int64_t nDefault
) const;
243 * Return boolean argument or default value
245 * @param strArg Argument to get (e.g. "-foo")
246 * @param fDefault (true or false)
247 * @return command-line argument or default value
249 bool GetBoolArg(const std::string
& strArg
, bool fDefault
) const;
252 * Set an argument if it doesn't already have a value
254 * @param strArg Argument to set (e.g. "-foo")
255 * @param strValue Value (e.g. "1")
256 * @return true if argument gets set, false if it already had a value
258 bool SoftSetArg(const std::string
& strArg
, const std::string
& strValue
);
261 * Set a boolean argument if it doesn't already have a value
263 * @param strArg Argument to set (e.g. "-foo")
264 * @param fValue Value (e.g. false)
265 * @return true if argument gets set, false if it already had a value
267 bool SoftSetBoolArg(const std::string
& strArg
, bool fValue
);
269 // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
270 // been set. Also called directly in testing.
271 void ForceSetArg(const std::string
& strArg
, const std::string
& strValue
);
274 extern ArgsManager gArgs
;
277 * Format a string to be used as group of options in help messages
279 * @param message Group name (e.g. "RPC server options:")
280 * @return the formatted string
282 std::string
HelpMessageGroup(const std::string
& message
);
285 * Format a string to be used as option description in help messages
287 * @param option Option message (e.g. "-rpcuser=<user>")
288 * @param message Option description (e.g. "Username for JSON-RPC connections")
289 * @return the formatted string
291 std::string
HelpMessageOpt(const std::string
& option
, const std::string
& message
);
294 * Return the number of physical cores available on the current system.
295 * @note This does not count virtual cores, such as those provided by HyperThreading
296 * when boost is newer than 1.56.
300 void RenameThread(const char* name
);
303 * .. and a wrapper that just calls func once
305 template <typename Callable
> void TraceThread(const char* name
, Callable func
)
307 std::string s
= strprintf("bitcoin-%s", name
);
308 RenameThread(s
.c_str());
311 LogPrintf("%s thread start\n", name
);
313 LogPrintf("%s thread exit\n", name
);
315 catch (const boost::thread_interrupted
&)
317 LogPrintf("%s thread interrupt\n", name
);
320 catch (const std::exception
& e
) {
321 PrintExceptionContinue(&e
, name
);
325 PrintExceptionContinue(nullptr, name
);
330 std::string
CopyrightHolders(const std::string
& strPrefix
);
332 //! Substitute for C++14 std::make_unique.
333 template <typename T
, typename
... Args
>
334 std::unique_ptr
<T
> MakeUnique(Args
&&... args
)
336 return std::unique_ptr
<T
>(new T(std::forward
<Args
>(args
)...));
339 #endif // BITCOIN_UTIL_H