Dogecoin Core  1.14.2
P2P Digital Currency
util.cpp
Go to the documentation of this file.
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.
5 
6 #if defined(HAVE_CONFIG_H)
7 #include "config/bitcoin-config.h"
8 #endif
9 
10 #include "util.h"
11 
12 #include "chainparamsbase.h"
13 #include "random.h"
14 #include "serialize.h"
15 #include "sync.h"
16 #include "utilstrencodings.h"
17 #include "utiltime.h"
18 
19 #include <stdarg.h>
20 
21 #if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
22 #include <pthread.h>
23 #include <pthread_np.h>
24 #endif
25 
26 #ifndef WIN32
27 // for posix_fallocate
28 #ifdef __linux__
29 
30 #ifdef _POSIX_C_SOURCE
31 #undef _POSIX_C_SOURCE
32 #endif
33 
34 #define _POSIX_C_SOURCE 200112L
35 
36 #endif // __linux__
37 
38 #include <algorithm>
39 #include <fcntl.h>
40 #include <sys/resource.h>
41 #include <sys/stat.h>
42 
43 #else
44 
45 #ifdef _MSC_VER
46 #pragma warning(disable:4786)
47 #pragma warning(disable:4804)
48 #pragma warning(disable:4805)
49 #pragma warning(disable:4717)
50 #endif
51 
52 #ifdef _WIN32_WINNT
53 #undef _WIN32_WINNT
54 #endif
55 #define _WIN32_WINNT 0x0501
56 
57 #ifdef _WIN32_IE
58 #undef _WIN32_IE
59 #endif
60 #define _WIN32_IE 0x0501
61 
62 #define WIN32_LEAN_AND_MEAN 1
63 #ifndef NOMINMAX
64 #define NOMINMAX
65 #endif
66 
67 #include <io.h> /* for _commit */
68 #include <shlobj.h>
69 #endif
70 
71 #ifdef HAVE_SYS_PRCTL_H
72 #include <sys/prctl.h>
73 #endif
74 
75 #ifdef HAVE_MALLOPT_ARENA_MAX
76 #include <malloc.h>
77 #endif
78 
79 #include <boost/algorithm/string/case_conv.hpp> // for to_lower()
80 #include <boost/algorithm/string/join.hpp>
81 #include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
82 #include <boost/filesystem.hpp>
83 #include <boost/filesystem/fstream.hpp>
84 #include <boost/foreach.hpp>
85 #include <boost/program_options/detail/config_file.hpp>
86 #include <boost/program_options/parsers.hpp>
87 #include <boost/thread.hpp>
88 #include <openssl/crypto.h>
89 #include <openssl/rand.h>
90 #include <openssl/conf.h>
91 
92 // Work around clang compilation problem in Boost 1.46:
93 // /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup
94 // See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options
95 // http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION
96 namespace boost {
97 
98  namespace program_options {
99  std::string to_internal(const std::string&);
100  }
101 
102 } // namespace boost
103 
104 using namespace std;
105 
106 const char * const BITCOIN_CONF_FILENAME = "dogecoin.conf";
107 const char * const BITCOIN_PID_FILENAME = "dogecoind.pid";
108 
110 map<string, string> mapArgs;
111 static map<string, vector<string> > _mapMultiArgs;
112 const map<string, vector<string> >& mapMultiArgs = _mapMultiArgs;
113 bool fDebug = false;
114 bool fPrintToConsole = false;
115 bool fPrintToDebugLog = true;
116 
117 bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS;
118 bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS;
119 bool fLogIPs = DEFAULT_LOGIPS;
120 std::atomic<bool> fReopenDebugLog(false);
122 
124 static CCriticalSection** ppmutexOpenSSL;
125 void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS
126 {
127  if (mode & CRYPTO_LOCK) {
128  ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
129  } else {
130  LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
131  }
132 }
133 
134 // Init
135 class CInit
136 {
137 public:
139  {
140  // Init OpenSSL library multithreading support
141  ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*));
142  for (int i = 0; i < CRYPTO_num_locks(); i++)
143  ppmutexOpenSSL[i] = new CCriticalSection();
144  CRYPTO_set_locking_callback(locking_callback);
145 
146  // OpenSSL can optionally load a config file which lists optional loadable modules and engines.
147  // We don't use them so we don't require the config. However some of our libs may call functions
148  // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing
149  // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be
150  // that the config appears to have been loaded and there are no modules/engines available.
151  OPENSSL_no_config();
152 
153 #ifdef WIN32
154  // Seed OpenSSL PRNG with current contents of the screen
155  RAND_screen();
156 #endif
157 
158  // Seed OpenSSL PRNG with performance counter
159  RandAddSeed();
160  }
162  {
163  // Securely erase the memory used by the PRNG
164  RAND_cleanup();
165  // Shutdown OpenSSL library multithreading support
166  CRYPTO_set_locking_callback(NULL);
167  for (int i = 0; i < CRYPTO_num_locks(); i++)
168  delete ppmutexOpenSSL[i];
169  OPENSSL_free(ppmutexOpenSSL);
170  }
171 }
173 
185 static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
186 
196 static FILE* fileout = NULL;
197 static boost::mutex* mutexDebugLog = NULL;
198 static list<string> *vMsgsBeforeOpenLog;
199 
200 static int FileWriteStr(const std::string &str, FILE *fp)
201 {
202  return fwrite(str.data(), 1, str.size(), fp);
203 }
204 
205 static void DebugPrintInit()
206 {
207  assert(mutexDebugLog == NULL);
208  mutexDebugLog = new boost::mutex();
209  vMsgsBeforeOpenLog = new list<string>;
210 }
211 
213 {
214  boost::call_once(&DebugPrintInit, debugPrintInitFlag);
215  boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
216 
217  assert(fileout == NULL);
218  assert(vMsgsBeforeOpenLog);
219  boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
220  fileout = fopen(pathDebug.string().c_str(), "a");
221  if (fileout) {
222  setbuf(fileout, NULL); // unbuffered
223  // dump buffered messages from before we opened the log
224  while (!vMsgsBeforeOpenLog->empty()) {
225  FileWriteStr(vMsgsBeforeOpenLog->front(), fileout);
226  vMsgsBeforeOpenLog->pop_front();
227  }
228  }
229 
230  delete vMsgsBeforeOpenLog;
231  vMsgsBeforeOpenLog = NULL;
232 }
233 
234 bool LogAcceptCategory(const char* category)
235 {
236  if (category != NULL)
237  {
238  if (!fDebug)
239  return false;
240 
241  // Give each thread quick access to -debug settings.
242  // This helps prevent issues debugging global destructors,
243  // where mapMultiArgs might be deleted before another
244  // global destructor calls LogPrint()
245  static boost::thread_specific_ptr<set<string> > ptrCategory;
246  if (ptrCategory.get() == NULL)
247  {
248  if (mapMultiArgs.count("-debug")) {
249  const vector<string>& categories = mapMultiArgs.at("-debug");
250  ptrCategory.reset(new set<string>(categories.begin(), categories.end()));
251  // thread_specific_ptr automatically deletes the set when the thread ends.
252  } else
253  ptrCategory.reset(new set<string>());
254  }
255  const set<string>& setCategories = *ptrCategory.get();
256 
257  // if not debugging everything and not debugging specific category, LogPrint does nothing.
258  if (setCategories.count(string("")) == 0 &&
259  setCategories.count(string("1")) == 0 &&
260  setCategories.count(string(category)) == 0)
261  return false;
262  }
263  return true;
264 }
265 
271 static std::string LogTimestampStr(const std::string &str, std::atomic_bool *fStartedNewLine)
272 {
273  string strStamped;
274 
275  if (!fLogTimestamps)
276  return str;
277 
278  if (*fStartedNewLine) {
279  int64_t nTimeMicros = GetLogTimeMicros();
280  strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTimeMicros/1000000);
281  if (fLogTimeMicros)
282  strStamped += strprintf(".%06d", nTimeMicros%1000000);
283  strStamped += ' ' + str;
284  } else
285  strStamped = str;
286 
287  if (!str.empty() && str[str.size()-1] == '\n')
288  *fStartedNewLine = true;
289  else
290  *fStartedNewLine = false;
291 
292  return strStamped;
293 }
294 
295 int LogPrintStr(const std::string &str)
296 {
297  int ret = 0; // Returns total number of characters written
298  static std::atomic_bool fStartedNewLine(true);
299 
300  string strTimestamped = LogTimestampStr(str, &fStartedNewLine);
301 
302  if (fPrintToConsole)
303  {
304  // print to console
305  ret = fwrite(strTimestamped.data(), 1, strTimestamped.size(), stdout);
306  fflush(stdout);
307  }
308  else if (fPrintToDebugLog)
309  {
310  boost::call_once(&DebugPrintInit, debugPrintInitFlag);
311  boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
312 
313  // buffer if we haven't opened the log yet
314  if (fileout == NULL) {
315  assert(vMsgsBeforeOpenLog);
316  ret = strTimestamped.length();
317  vMsgsBeforeOpenLog->push_back(strTimestamped);
318  }
319  else
320  {
321  // reopen the log file, if requested
322  if (fReopenDebugLog) {
323  fReopenDebugLog = false;
324  boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
325  if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
326  setbuf(fileout, NULL); // unbuffered
327  }
328 
329  ret = FileWriteStr(strTimestamped, fileout);
330  }
331  }
332  return ret;
333 }
334 
336 static bool InterpretBool(const std::string& strValue)
337 {
338  if (strValue.empty())
339  return true;
340  return (atoi(strValue) != 0);
341 }
342 
344 static void InterpretNegativeSetting(std::string& strKey, std::string& strValue)
345 {
346  if (strKey.length()>3 && strKey[0]=='-' && strKey[1]=='n' && strKey[2]=='o')
347  {
348  strKey = "-" + strKey.substr(3);
349  strValue = InterpretBool(strValue) ? "0" : "1";
350  }
351 }
352 
353 void ParseParameters(int argc, const char* const argv[])
354 {
355  LOCK(cs_args);
356  mapArgs.clear();
357  _mapMultiArgs.clear();
358 
359  for (int i = 1; i < argc; i++)
360  {
361  std::string str(argv[i]);
362  std::string strValue;
363  size_t is_index = str.find('=');
364  if (is_index != std::string::npos)
365  {
366  strValue = str.substr(is_index+1);
367  str = str.substr(0, is_index);
368  }
369 #ifdef WIN32
370  boost::to_lower(str);
371  if (boost::algorithm::starts_with(str, "/"))
372  str = "-" + str.substr(1);
373 #endif
374 
375  if (str[0] != '-')
376  break;
377 
378  // Interpret --foo as -foo.
379  // If both --foo and -foo are set, the last takes effect.
380  if (str.length() > 1 && str[1] == '-')
381  str = str.substr(1);
382  InterpretNegativeSetting(str, strValue);
383 
384  mapArgs[str] = strValue;
385  _mapMultiArgs[str].push_back(strValue);
386  }
387 }
388 
389 bool IsArgSet(const std::string& strArg)
390 {
391  LOCK(cs_args);
392  return mapArgs.count(strArg);
393 }
394 
395 std::string GetArg(const std::string& strArg, const std::string& strDefault)
396 {
397  LOCK(cs_args);
398  if (mapArgs.count(strArg))
399  return mapArgs[strArg];
400  return strDefault;
401 }
402 
403 int64_t GetArg(const std::string& strArg, int64_t nDefault)
404 {
405  LOCK(cs_args);
406  if (mapArgs.count(strArg))
407  return atoi64(mapArgs[strArg]);
408  return nDefault;
409 }
410 
411 bool GetBoolArg(const std::string& strArg, bool fDefault)
412 {
413  LOCK(cs_args);
414  if (mapArgs.count(strArg))
415  return InterpretBool(mapArgs[strArg]);
416  return fDefault;
417 }
418 
419 bool SoftSetArg(const std::string& strArg, const std::string& strValue)
420 {
421  LOCK(cs_args);
422  if (mapArgs.count(strArg))
423  return false;
424  mapArgs[strArg] = strValue;
425  return true;
426 }
427 
428 bool SoftSetBoolArg(const std::string& strArg, bool fValue)
429 {
430  if (fValue)
431  return SoftSetArg(strArg, std::string("1"));
432  else
433  return SoftSetArg(strArg, std::string("0"));
434 }
435 
436 void ForceSetArg(const std::string& strArg, const std::string& strValue)
437 {
438  LOCK(cs_args);
439  mapArgs[strArg] = strValue;
440 }
441 
442 
443 
444 static const int screenWidth = 79;
445 static const int optIndent = 2;
446 static const int msgIndent = 7;
447 
448 std::string HelpMessageGroup(const std::string &message) {
449  return std::string(message) + std::string("\n\n");
450 }
451 
452 std::string HelpMessageOpt(const std::string &option, const std::string &message) {
453  return std::string(optIndent,' ') + std::string(option) +
454  std::string("\n") + std::string(msgIndent,' ') +
455  FormatParagraph(message, screenWidth - msgIndent, msgIndent) +
456  std::string("\n\n");
457 }
458 
459 static std::string FormatException(const std::exception* pex, const char* pszThread)
460 {
461 #ifdef WIN32
462  char pszModule[MAX_PATH] = "";
463  GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
464 #else
465  const char* pszModule = "dogecoin";
466 #endif
467  if (pex)
468  return strprintf(
469  "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
470  else
471  return strprintf(
472  "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
473 }
474 
475 void PrintExceptionContinue(const std::exception* pex, const char* pszThread)
476 {
477  std::string message = FormatException(pex, pszThread);
478  LogPrintf("\n\n************************\n%s\n", message);
479  fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
480 }
481 
482 boost::filesystem::path GetDefaultDataDir()
483 {
484  namespace fs = boost::filesystem;
485  // Windows < Vista: C:\Documents and Settings\Username\Application Data\Bitcoin
486  // Windows >= Vista: C:\Users\Username\AppData\Roaming\Bitcoin
487  // Mac: ~/Library/Application Support/Bitcoin
488  // Unix: ~/.bitcoin
489 #ifdef WIN32
490  // Windows
491  return GetSpecialFolderPath(CSIDL_APPDATA) / "Dogecoin";
492 #else
493  fs::path pathRet;
494  char* pszHome = getenv("HOME");
495  if (pszHome == NULL || strlen(pszHome) == 0)
496  pathRet = fs::path("/");
497  else
498  pathRet = fs::path(pszHome);
499 #ifdef MAC_OSX
500  // Mac
501  return pathRet / "Library/Application Support/Dogecoin";
502 #else
503  // Unix
504  return pathRet / ".dogecoin";
505 #endif
506 #endif
507 }
508 
509 static boost::filesystem::path pathCached;
510 static boost::filesystem::path pathCachedNetSpecific;
511 static CCriticalSection csPathCached;
512 
513 const boost::filesystem::path &GetDataDir(bool fNetSpecific)
514 {
515  namespace fs = boost::filesystem;
516 
517  LOCK(csPathCached);
518 
519  fs::path &path = fNetSpecific ? pathCachedNetSpecific : pathCached;
520 
521  // This can be called during exceptions by LogPrintf(), so we cache the
522  // value so we don't have to do memory allocations after that.
523  if (!path.empty())
524  return path;
525 
526  if (IsArgSet("-datadir")) {
527  path = fs::system_complete(GetArg("-datadir", ""));
528  if (!fs::is_directory(path)) {
529  path = "";
530  return path;
531  }
532  } else {
533  path = GetDefaultDataDir();
534  }
535  if (fNetSpecific)
536  path /= BaseParams().DataDir();
537 
538  fs::create_directories(path);
539 
540  return path;
541 }
542 
544 {
545  LOCK(csPathCached);
546 
547  pathCached = boost::filesystem::path();
548  pathCachedNetSpecific = boost::filesystem::path();
549 }
550 
551 boost::filesystem::path GetConfigFile(const std::string& confPath)
552 {
553  boost::filesystem::path pathConfigFile(confPath);
554  if (!pathConfigFile.is_complete())
555  pathConfigFile = GetDataDir(false) / pathConfigFile;
556 
557  return pathConfigFile;
558 }
559 
560 void ReadConfigFile(const std::string& confPath)
561 {
562  boost::filesystem::ifstream streamConfig(GetConfigFile(confPath));
563  if (!streamConfig.good())
564  return; // No bitcoin.conf file is OK
565 
566  {
567  LOCK(cs_args);
568  set<string> setOptions;
569  setOptions.insert("*");
570 
571  for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
572  {
573  // Don't overwrite existing settings so command line settings override bitcoin.conf
574  string strKey = string("-") + it->string_key;
575  string strValue = it->value[0];
576  InterpretNegativeSetting(strKey, strValue);
577  if (mapArgs.count(strKey) == 0)
578  mapArgs[strKey] = strValue;
579  _mapMultiArgs[strKey].push_back(strValue);
580  }
581  }
582  // If datadir is changed in .conf file:
584 }
585 
586 #ifndef WIN32
587 boost::filesystem::path GetPidFile()
588 {
589  boost::filesystem::path pathPidFile(GetArg("-pid", BITCOIN_PID_FILENAME));
590  if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile;
591  return pathPidFile;
592 }
593 
594 void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
595 {
596  FILE* file = fopen(path.string().c_str(), "w");
597  if (file)
598  {
599  fprintf(file, "%d\n", pid);
600  fclose(file);
601  }
602 }
603 #endif
604 
605 bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
606 {
607 #ifdef WIN32
608  return MoveFileExA(src.string().c_str(), dest.string().c_str(),
609  MOVEFILE_REPLACE_EXISTING) != 0;
610 #else
611  int rc = std::rename(src.string().c_str(), dest.string().c_str());
612  return (rc == 0);
613 #endif /* WIN32 */
614 }
615 
621 bool TryCreateDirectory(const boost::filesystem::path& p)
622 {
623  try
624  {
625  return boost::filesystem::create_directory(p);
626  } catch (const boost::filesystem::filesystem_error&) {
627  if (!boost::filesystem::exists(p) || !boost::filesystem::is_directory(p))
628  throw;
629  }
630 
631  // create_directory didn't create the directory, it had to have existed already
632  return false;
633 }
634 
635 void FileCommit(FILE *file)
636 {
637  fflush(file); // harmless if redundantly called
638 #ifdef WIN32
639  HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
640  FlushFileBuffers(hFile);
641 #else
642  #if defined(__linux__) || defined(__NetBSD__)
643  fdatasync(fileno(file));
644  #elif defined(__APPLE__) && defined(F_FULLFSYNC)
645  fcntl(fileno(file), F_FULLFSYNC, 0);
646  #else
647  fsync(fileno(file));
648  #endif
649 #endif
650 }
651 
652 bool TruncateFile(FILE *file, unsigned int length) {
653 #if defined(WIN32)
654  return _chsize(_fileno(file), length) == 0;
655 #else
656  return ftruncate(fileno(file), length) == 0;
657 #endif
658 }
659 
664 int RaiseFileDescriptorLimit(int nMinFD) {
665 #if defined(WIN32)
666  return 2048;
667 #else
668  struct rlimit limitFD;
669  if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
670  if (limitFD.rlim_cur < (rlim_t)nMinFD) {
671  limitFD.rlim_cur = nMinFD;
672  if (limitFD.rlim_cur > limitFD.rlim_max)
673  limitFD.rlim_cur = limitFD.rlim_max;
674  setrlimit(RLIMIT_NOFILE, &limitFD);
675  getrlimit(RLIMIT_NOFILE, &limitFD);
676  }
677  return limitFD.rlim_cur;
678  }
679  return nMinFD; // getrlimit failed, assume it's fine
680 #endif
681 }
682 
687 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {
688 #if defined(WIN32)
689  // Windows-specific version
690  HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
691  LARGE_INTEGER nFileSize;
692  int64_t nEndPos = (int64_t)offset + length;
693  nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
694  nFileSize.u.HighPart = nEndPos >> 32;
695  SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
696  SetEndOfFile(hFile);
697 #elif defined(MAC_OSX)
698  // OSX specific version
699  fstore_t fst;
700  fst.fst_flags = F_ALLOCATECONTIG;
701  fst.fst_posmode = F_PEOFPOSMODE;
702  fst.fst_offset = 0;
703  fst.fst_length = (off_t)offset + length;
704  fst.fst_bytesalloc = 0;
705  if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
706  fst.fst_flags = F_ALLOCATEALL;
707  fcntl(fileno(file), F_PREALLOCATE, &fst);
708  }
709  ftruncate(fileno(file), fst.fst_length);
710 #elif defined(__linux__)
711  // Version using posix_fallocate
712  off_t nEndPos = (off_t)offset + length;
713  posix_fallocate(fileno(file), 0, nEndPos);
714 #else
715  // Fallback version
716  // TODO: just write one byte per block
717  static const char buf[65536] = {};
718  fseek(file, offset, SEEK_SET);
719  while (length > 0) {
720  unsigned int now = 65536;
721  if (length < now)
722  now = length;
723  fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
724  length -= now;
725  }
726 #endif
727 }
728 
730 {
731  // Amount of debug.log to save at end when shrinking (must fit in memory)
732  constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000;
733  // Scroll debug.log if it's getting too big
734  boost::filesystem::path pathLog = GetDataDir() / "debug.log";
735  FILE* file = fopen(pathLog.string().c_str(), "r");
736  // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE
737  // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes
738  if (file && boost::filesystem::file_size(pathLog) > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10))
739  {
740  // Restart the file with some of the end
741  std::vector<char> vch(RECENT_DEBUG_HISTORY_SIZE, 0);
742  fseek(file, -((long)vch.size()), SEEK_END);
743  int nBytes = fread(vch.data(), 1, vch.size(), file);
744  fclose(file);
745 
746  file = fopen(pathLog.string().c_str(), "w");
747  if (file)
748  {
749  fwrite(vch.data(), 1, nBytes, file);
750  fclose(file);
751  }
752  }
753  else if (file != NULL)
754  fclose(file);
755 }
756 
757 #ifdef WIN32
758 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
759 {
760  namespace fs = boost::filesystem;
761 
762  char pszPath[MAX_PATH] = "";
763 
764  if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
765  {
766  return fs::path(pszPath);
767  }
768 
769  LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
770  return fs::path("");
771 }
772 #endif
773 
774 void runCommand(const std::string& strCommand)
775 {
776  int nErr = ::system(strCommand.c_str());
777  if (nErr)
778  LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr);
779 }
780 
781 void RenameThread(const char* name)
782 {
783 #if defined(PR_SET_NAME)
784  // Only the first 15 characters are used (16 - NUL terminator)
785  ::prctl(PR_SET_NAME, name, 0, 0, 0);
786 #elif (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
787  pthread_set_name_np(pthread_self(), name);
788 
789 #elif defined(MAC_OSX)
790  pthread_setname_np(name);
791 #else
792  // Prevent warnings for unused parameters...
793  (void)name;
794 #endif
795 }
796 
798 {
799 #ifdef HAVE_MALLOPT_ARENA_MAX
800  // glibc-specific: On 32-bit systems set the number of arenas to 1.
801  // By default, since glibc 2.10, the C library will create up to two heap
802  // arenas per core. This is known to cause excessive virtual address space
803  // usage in our usage. Work around it by setting the maximum number of
804  // arenas to 1.
805  if (sizeof(void*) == 4) {
806  mallopt(M_ARENA_MAX, 1);
807  }
808 #endif
809  // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale
810  // may be invalid, in which case the "C" locale is used as fallback.
811 #if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
812  try {
813  std::locale(""); // Raises a runtime error if current locale is invalid
814  } catch (const std::runtime_error&) {
815  setenv("LC_ALL", "C", 1);
816  }
817 #endif
818  // The path locale is lazy initialized and to avoid deinitialization errors
819  // in multithreading environments, it is set explicitly by the main thread.
820  // A dummy locale is used to extract the internal default locale, used by
821  // boost::filesystem::path, which is then used to explicitly imbue the path.
822  std::locale loc = boost::filesystem::path::imbue(std::locale::classic());
823  boost::filesystem::path::imbue(loc);
824 }
825 
827 {
828 #ifdef WIN32
829  // Initialize Windows Sockets
830  WSADATA wsadata;
831  int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
832  if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
833  return false;
834 #endif
835  return true;
836 }
837 
839 {
840 #if BOOST_VERSION >= 105600
841  return boost::thread::physical_concurrency();
842 #else // Must fall back to hardware_concurrency, which unfortunately counts virtual cores
843  return boost::thread::hardware_concurrency();
844 #endif
845 }
846 
847 std::string CopyrightHolders(const std::string& strPrefix)
848 {
849  std::string strCopyrightHolders = strPrefix + strprintf(_(COPYRIGHT_HOLDERS), _(COPYRIGHT_HOLDERS_SUBSTITUTION));
850 
851  // Check for untranslated substitution to make sure Bitcoin Core copyright is not removed by accident
852  if (strprintf(COPYRIGHT_HOLDERS, COPYRIGHT_HOLDERS_SUBSTITUTION).find("Bitcoin Core") == std::string::npos) {
853  strCopyrightHolders += "\n" + strPrefix + "The Bitcoin Core developers";
854  }
855  return strCopyrightHolders;
856 }
const CBaseChainParams & BaseParams()
Return the currently selected parameters.
const std::string & DataDir() const
Wrapped boost mutex: supports recursive locking, but no waiting TODO: We should move away from using ...
Definition: sync.h:93
Definition: util.cpp:136
CInit()
Definition: util.cpp:138
~CInit()
Definition: util.cpp:161
Signals for translation.
Definition: util.h:38
#define MAX_PATH
Definition: compat.h:74
void RandAddSeed()
Definition: random.cpp:46
#define ENTER_CRITICAL_SECTION(cs)
Definition: sync.h:181
#define LEAVE_CRITICAL_SECTION(cs)
Definition: sync.h:187
#define LOCK(cs)
Definition: sync.h:177
#define NO_THREAD_SAFETY_ANALYSIS
Definition: threadsafety.h:52
#define strprintf
Definition: tinyformat.h:1047
map< string, string > mapArgs
Definition: util.cpp:110
CTranslationInterface translationInterface
Definition: util.cpp:121
void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
Definition: util.cpp:594
class CInit instance_of_cinit
void locking_callback(int mode, int i, const char *file, int line) NO_THREAD_SAFETY_ANALYSIS
Definition: util.cpp:125
boost::filesystem::path GetConfigFile(const std::string &confPath)
Definition: util.cpp:551
void OpenDebugLog()
Definition: util.cpp:212
bool fLogTimeMicros
Definition: util.cpp:118
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Definition: util.cpp:395
bool fDebug
Definition: util.cpp:113
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: util.cpp:436
bool LogAcceptCategory(const char *category)
Return true if log accepts specified category.
Definition: util.cpp:234
std::string CopyrightHolders(const std::string &strPrefix)
Definition: util.cpp:847
void ShrinkDebugFile()
Definition: util.cpp:729
bool TryCreateDirectory(const boost::filesystem::path &p)
Ignores exceptions thrown by Boost's create_directory if the requested directory exists.
Definition: util.cpp:621
void ParseParameters(int argc, const char *const argv[])
Definition: util.cpp:353
void ReadConfigFile(const std::string &confPath)
Definition: util.cpp:560
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
Definition: util.cpp:411
bool SetupNetworking()
Definition: util.cpp:826
int RaiseFileDescriptorLimit(int nMinFD)
this function tries to raise the file descriptor limit to the requested number.
Definition: util.cpp:664
void RenameThread(const char *name)
Definition: util.cpp:781
bool fLogIPs
Definition: util.cpp:119
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: util.cpp:687
boost::filesystem::path GetPidFile()
Definition: util.cpp:587
const char *const BITCOIN_PID_FILENAME
Definition: util.cpp:107
bool fPrintToConsole
Definition: util.cpp:114
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: util.cpp:419
void SetupEnvironment()
Definition: util.cpp:797
const map< string, vector< string > > & mapMultiArgs
Definition: util.cpp:112
bool fLogTimestamps
Definition: util.cpp:117
void runCommand(const std::string &strCommand)
Definition: util.cpp:774
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: util.cpp:475
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: util.cpp:448
boost::filesystem::path GetDefaultDataDir()
Definition: util.cpp:482
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:513
const char *const BITCOIN_CONF_FILENAME
Definition: util.cpp:106
void ClearDatadirCache()
Definition: util.cpp:543
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: util.cpp:428
bool TruncateFile(FILE *file, unsigned int length)
Definition: util.cpp:652
bool IsArgSet(const std::string &strArg)
Return true if the given argument has been manually set.
Definition: util.cpp:389
CCriticalSection cs_args
Definition: util.cpp:109
bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
Definition: util.cpp:605
bool fPrintToDebugLog
Definition: util.cpp:115
int GetNumCores()
Return the number of physical cores available on the current system.
Definition: util.cpp:838
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
Definition: util.cpp:452
std::atomic< bool > fReopenDebugLog(false)
void FileCommit(FILE *file)
Definition: util.cpp:635
int LogPrintStr(const std::string &str)
Send a string to the log output.
Definition: util.cpp:295
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
Definition: util.h:62
#define LogPrintf(...)
Definition: util.h:82
std::string FormatParagraph(const std::string &in, size_t width, size_t indent)
Format a paragraph of text to a fixed width, adding spaces for indentation to any added line.
int64_t atoi64(const char *psz)
int atoi(const std::string &str)
int64_t GetLogTimeMicros()
Return a time useful for the debug log.
Definition: utiltime.cpp:55
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
Definition: utiltime.cpp:80