Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 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 :
6 : /**
7 : * Server/client environment: argument handling, config file parsing,
8 : * logging, thread wrappers
9 : */
10 : #ifndef BITCOIN_UTIL_H
11 : #define BITCOIN_UTIL_H
12 :
13 : #if defined(HAVE_CONFIG_H)
14 : #include "config/bitcoin-config.h"
15 : #endif
16 :
17 : #include "compat.h"
18 : #include "tinyformat.h"
19 : #include "utiltime.h"
20 :
21 : #include <exception>
22 : #include <map>
23 : #include <stdint.h>
24 : #include <string>
25 : #include <vector>
26 :
27 : #include <boost/filesystem/path.hpp>
28 : #include <boost/signals2/signal.hpp>
29 : #include <boost/thread/exceptions.hpp>
30 :
31 : /** Signals for translation. */
32 812 : class CTranslationInterface
33 : {
34 : public:
35 : /** Translate a message to the native language of the user. */
36 : boost::signals2::signal<std::string (const char* psz)> Translate;
37 : };
38 :
39 : extern std::map<std::string, std::string> mapArgs;
40 : extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
41 : extern bool fDebug;
42 : extern bool fPrintToConsole;
43 : extern bool fPrintToDebugLog;
44 : extern bool fServer;
45 : extern std::string strMiscWarning;
46 : extern bool fLogTimestamps;
47 : extern bool fLogIPs;
48 : extern volatile bool fReopenDebugLog;
49 : extern CTranslationInterface translationInterface;
50 :
51 : /**
52 : * Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
53 : * If no translation slot is registered, nothing is returned, and simply return the input.
54 : */
55 15522 : inline std::string _(const char* psz)
56 : {
57 15522 : boost::optional<std::string> rv = translationInterface.Translate(psz);
58 46566 : return rv ? (*rv) : psz;
59 : }
60 :
61 : void SetupEnvironment();
62 : bool SetupNetworking();
63 :
64 : /** Return true if log accepts specified category */
65 : bool LogAcceptCategory(const char* category);
66 : /** Send a string to the log output */
67 : int LogPrintStr(const std::string &str);
68 :
69 : #define LogPrintf(...) LogPrint(NULL, __VA_ARGS__)
70 :
71 : /**
72 : * When we switch to C++11, this can be switched to variadic templates instead
73 : * of this macro-based construction (see tinyformat.h).
74 : */
75 : #define MAKE_ERROR_AND_LOG_FUNC(n) \
76 : /** Print to debug.log if -debug=category switch is given OR category is NULL. */ \
77 : template<TINYFORMAT_ARGTYPES(n)> \
78 : static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \
79 : { \
80 : if(!LogAcceptCategory(category)) return 0; \
81 : return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \
82 : } \
83 : /** Log error and return false */ \
84 : template<TINYFORMAT_ARGTYPES(n)> \
85 : static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \
86 : { \
87 : LogPrintStr("ERROR: " + tfm::format(format, TINYFORMAT_PASSARGS(n)) + "\n"); \
88 : return false; \
89 : }
90 :
91 312116 : TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC)
92 :
93 : /**
94 : * Zero-arg versions of logging and error, these are not covered by
95 : * TINYFORMAT_FOREACH_ARGNUM
96 : */
97 25199 : static inline int LogPrint(const char* category, const char* format)
98 : {
99 25199 : if(!LogAcceptCategory(category)) return 0;
100 5127 : return LogPrintStr(format);
101 : }
102 1380 : static inline bool error(const char* format)
103 : {
104 6900 : LogPrintStr(std::string("ERROR: ") + format + "\n");
105 1380 : return false;
106 : }
107 :
108 : void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
109 : void ParseParameters(int argc, const char*const argv[]);
110 : void FileCommit(FILE *fileout);
111 : bool TruncateFile(FILE *file, unsigned int length);
112 : int RaiseFileDescriptorLimit(int nMinFD);
113 : void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
114 : bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
115 : bool TryCreateDirectory(const boost::filesystem::path& p);
116 : boost::filesystem::path GetDefaultDataDir();
117 : const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
118 : void ClearDatadirCache();
119 : boost::filesystem::path GetConfigFile();
120 : #ifndef WIN32
121 : boost::filesystem::path GetPidFile();
122 : void CreatePidFile(const boost::filesystem::path &path, pid_t pid);
123 : #endif
124 : void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
125 : #ifdef WIN32
126 : boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
127 : #endif
128 : boost::filesystem::path GetTempPath();
129 : void OpenDebugLog();
130 : void ShrinkDebugFile();
131 : void runCommand(const std::string& strCommand);
132 :
133 : inline bool IsSwitchChar(char c)
134 : {
135 : #ifdef WIN32
136 : return c == '-' || c == '/';
137 : #else
138 : return c == '-';
139 : #endif
140 : }
141 :
142 : /**
143 : * Return string argument or default value
144 : *
145 : * @param strArg Argument to get (e.g. "-foo")
146 : * @param default (e.g. "1")
147 : * @return command-line argument or default value
148 : */
149 : std::string GetArg(const std::string& strArg, const std::string& strDefault);
150 :
151 : /**
152 : * Return integer argument or default value
153 : *
154 : * @param strArg Argument to get (e.g. "-foo")
155 : * @param default (e.g. 1)
156 : * @return command-line argument (0 if invalid number) or default value
157 : */
158 : int64_t GetArg(const std::string& strArg, int64_t nDefault);
159 :
160 : /**
161 : * Return boolean argument or default value
162 : *
163 : * @param strArg Argument to get (e.g. "-foo")
164 : * @param default (true or false)
165 : * @return command-line argument or default value
166 : */
167 : bool GetBoolArg(const std::string& strArg, bool fDefault);
168 :
169 : /**
170 : * Set an argument if it doesn't already have a value
171 : *
172 : * @param strArg Argument to set (e.g. "-foo")
173 : * @param strValue Value (e.g. "1")
174 : * @return true if argument gets set, false if it already had a value
175 : */
176 : bool SoftSetArg(const std::string& strArg, const std::string& strValue);
177 :
178 : /**
179 : * Set a boolean argument if it doesn't already have a value
180 : *
181 : * @param strArg Argument to set (e.g. "-foo")
182 : * @param fValue Value (e.g. false)
183 : * @return true if argument gets set, false if it already had a value
184 : */
185 : bool SoftSetBoolArg(const std::string& strArg, bool fValue);
186 :
187 : /**
188 : * Format a string to be used as group of options in help messages
189 : *
190 : * @param message Group name (e.g. "RPC server options:")
191 : * @return the formatted string
192 : */
193 : std::string HelpMessageGroup(const std::string& message);
194 :
195 : /**
196 : * Format a string to be used as option description in help messages
197 : *
198 : * @param option Option message (e.g. "-rpcuser=<user>")
199 : * @param message Option description (e.g. "Username for JSON-RPC connections")
200 : * @return the formatted string
201 : */
202 : std::string HelpMessageOpt(const std::string& option, const std::string& message);
203 :
204 : /**
205 : * Return the number of physical cores available on the current system.
206 : * @note This does not count virtual cores, such as those provided by HyperThreading
207 : * when boost is newer than 1.56.
208 : */
209 : int GetNumCores();
210 :
211 : void SetThreadPriority(int nPriority);
212 : void RenameThread(const char* name);
213 :
214 : /**
215 : * .. and a wrapper that just calls func once
216 : */
217 560 : template <typename Callable> void TraceThread(const char* name, Callable func)
218 : {
219 560 : std::string s = strprintf("bitcoin-%s", name);
220 560 : RenameThread(s.c_str());
221 : try
222 : {
223 560 : LogPrintf("%s thread start\n", name);
224 560 : func();
225 90 : LogPrintf("%s thread exit\n", name);
226 : }
227 940 : catch (const boost::thread_interrupted&)
228 : {
229 470 : LogPrintf("%s thread interrupt\n", name);
230 470 : throw;
231 : }
232 0 : catch (const std::exception& e) {
233 0 : PrintExceptionContinue(&e, name);
234 0 : throw;
235 : }
236 0 : catch (...) {
237 0 : PrintExceptionContinue(NULL, name);
238 0 : throw;
239 : }
240 90 : }
241 :
242 : #endif // BITCOIN_UTIL_H
|