1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Distributed under the MIT/X11 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
10 #ifndef BITCOIN_UTIL_H
11 #define BITCOIN_UTIL_H
13 #if defined(HAVE_CONFIG_H)
14 #include "config/bitcoin-config.h"
18 #include "tinyformat.h"
27 #include <boost/filesystem/path.hpp>
28 #include <boost/thread/exceptions.hpp>
30 extern std::map<std::string, std::string> mapArgs;
31 extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
33 extern bool fPrintToConsole;
34 extern bool fPrintToDebugLog;
36 extern std::string strMiscWarning;
37 extern bool fLogTimestamps;
39 extern volatile bool fReopenDebugLog;
41 void SetupEnvironment();
43 /* Return true if log accepts specified category */
44 bool LogAcceptCategory(const char* category);
45 /* Send a string to the log output */
46 int LogPrintStr(const std::string &str);
48 #define LogPrintf(...) LogPrint(NULL, __VA_ARGS__)
50 /* When we switch to C++11, this can be switched to variadic templates instead
51 * of this macro-based construction (see tinyformat.h).
53 #define MAKE_ERROR_AND_LOG_FUNC(n) \
54 /* Print to debug.log if -debug=category switch is given OR category is NULL. */ \
55 template<TINYFORMAT_ARGTYPES(n)> \
56 static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \
58 if(!LogAcceptCategory(category)) return 0; \
59 return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \
61 /* Log error and return false */ \
62 template<TINYFORMAT_ARGTYPES(n)> \
63 static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \
65 LogPrintStr("ERROR: " + tfm::format(format, TINYFORMAT_PASSARGS(n)) + "\n"); \
69 TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC)
71 /* Zero-arg versions of logging and error, these are not covered by
72 * TINYFORMAT_FOREACH_ARGNUM
74 static inline int LogPrint(const char* category, const char* format)
76 if(!LogAcceptCategory(category)) return 0;
77 return LogPrintStr(format);
79 static inline bool error(const char* format)
81 LogPrintStr(std::string("ERROR: ") + format + "\n");
85 void PrintExceptionContinue(std::exception* pex, const char* pszThread);
86 void ParseParameters(int argc, const char*const argv[]);
87 void FileCommit(FILE *fileout);
88 bool TruncateFile(FILE *file, unsigned int length);
89 int RaiseFileDescriptorLimit(int nMinFD);
90 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
91 bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
92 bool TryCreateDirectory(const boost::filesystem::path& p);
93 boost::filesystem::path GetDefaultDataDir();
94 const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
95 boost::filesystem::path GetConfigFile();
96 boost::filesystem::path GetPidFile();
98 void CreatePidFile(const boost::filesystem::path &path, pid_t pid);
100 void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
102 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
104 boost::filesystem::path GetTempPath();
105 void ShrinkDebugFile();
106 void runCommand(std::string strCommand);
108 inline bool IsSwitchChar(char c)
111 return c == '-' || c == '/';
118 * Return string argument or default value
120 * @param strArg Argument to get (e.g. "-foo")
121 * @param default (e.g. "1")
122 * @return command-line argument or default value
124 std::string GetArg(const std::string& strArg, const std::string& strDefault);
127 * Return integer argument or default value
129 * @param strArg Argument to get (e.g. "-foo")
130 * @param default (e.g. 1)
131 * @return command-line argument (0 if invalid number) or default value
133 int64_t GetArg(const std::string& strArg, int64_t nDefault);
136 * Return boolean argument or default value
138 * @param strArg Argument to get (e.g. "-foo")
139 * @param default (true or false)
140 * @return command-line argument or default value
142 bool GetBoolArg(const std::string& strArg, bool fDefault);
145 * Set an argument if it doesn't already have a value
147 * @param strArg Argument to set (e.g. "-foo")
148 * @param strValue Value (e.g. "1")
149 * @return true if argument gets set, false if it already had a value
151 bool SoftSetArg(const std::string& strArg, const std::string& strValue);
154 * Set a boolean argument if it doesn't already have a value
156 * @param strArg Argument to set (e.g. "-foo")
157 * @param fValue Value (e.g. false)
158 * @return true if argument gets set, false if it already had a value
160 bool SoftSetBoolArg(const std::string& strArg, bool fValue);
162 void SetThreadPriority(int nPriority);
163 void RenameThread(const char* name);
165 // Standard wrapper for do-something-forever thread functions.
166 // "Forever" really means until the thread is interrupted.
168 // new boost::thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, 900000));
170 // boost::function<void()> f = boost::bind(&FunctionWithArg, argument);
171 // threadGroup.create_thread(boost::bind(&LoopForever<boost::function<void()> >, "nothing", f, milliseconds));
172 template <typename Callable> void LoopForever(const char* name, Callable func, int64_t msecs)
174 std::string s = strprintf("bitcoin-%s", name);
175 RenameThread(s.c_str());
176 LogPrintf("%s thread start\n", name);
185 catch (boost::thread_interrupted)
187 LogPrintf("%s thread stop\n", name);
190 catch (std::exception& e) {
191 PrintExceptionContinue(&e, name);
195 PrintExceptionContinue(NULL, name);
199 // .. and a wrapper that just calls func once
200 template <typename Callable> void TraceThread(const char* name, Callable func)
202 std::string s = strprintf("bitcoin-%s", name);
203 RenameThread(s.c_str());
206 LogPrintf("%s thread start\n", name);
208 LogPrintf("%s thread exit\n", name);
210 catch (boost::thread_interrupted)
212 LogPrintf("%s thread interrupt\n", name);
215 catch (std::exception& e) {
216 PrintExceptionContinue(&e, name);
220 PrintExceptionContinue(NULL, name);
225 #endif // BITCOIN_UTIL_H