Coverage Report

Created: 2026-08-14 20:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/common/system.cpp
Line
Count
Source
1
// Copyright (c) 2009-2010 Satoshi Nakamoto
2
// Copyright (c) 2009-present 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
#include <bitcoin-build-config.h> // IWYU pragma: keep
7
8
#include <common/system.h>
9
10
#include <util/log.h>
11
#include <util/string.h>
12
#include <util/time.h>
13
14
#ifdef WIN32
15
#include <compat/compat.h>
16
#include <util/check.h>
17
#include <windows.h>
18
#else
19
#include <sys/stat.h>
20
#include <sys/types.h>
21
#include <unistd.h>
22
#endif
23
24
#ifdef HAVE_MALLOPT_ARENA_MAX
25
#include <malloc.h>
26
#endif
27
28
#include <cstdint>
29
#include <cstdlib>
30
#include <locale>
31
#include <optional>
32
#include <stdexcept>
33
#include <string>
34
#include <thread>
35
36
using util::ReplaceAll;
37
38
#ifndef WIN32
39
std::string ShellEscape(const std::string& arg)
40
26
{
41
26
    std::string escaped = arg;
42
26
    ReplaceAll(escaped, "'", "'\"'\"'");
43
26
    return "'" + escaped + "'";
44
26
}
45
#endif
46
47
#if HAVE_SYSTEM
48
void runCommand(const std::string& strCommand)
49
143
{
50
143
    if (strCommand.empty()) return;
51
143
    int nErr = ::system(strCommand.c_str());
52
143
    if (nErr) {
53
0
        LogWarning("runCommand error: system(%s) returned %d", strCommand, nErr);
54
0
    }
55
143
}
56
#endif
57
58
void SetupEnvironment()
59
3.19k
{
60
3.19k
#ifdef HAVE_MALLOPT_ARENA_MAX
61
    // glibc-specific: On 32-bit systems set the number of arenas to 1.
62
    // By default, since glibc 2.10, the C library will create up to two heap
63
    // arenas per core. This is known to cause excessive virtual address space
64
    // usage in our usage. Work around it by setting the maximum number of
65
    // arenas to 1.
66
3.19k
    if (sizeof(void*) == 4) {
67
0
        mallopt(M_ARENA_MAX, 1);
68
0
    }
69
3.19k
#endif
70
    // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale
71
    // may be invalid, in which case the "C.UTF-8" locale is used as fallback.
72
3.19k
#if !defined(WIN32) && !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
73
3.19k
    try {
74
3.19k
        std::locale(""); // Raises a runtime error if current locale is invalid
75
3.19k
    } catch (const std::runtime_error&) {
76
0
        setenv("LC_ALL", "C.UTF-8", 1);
77
0
    }
78
#elif defined(WIN32)
79
    assert(GetACP() == CP_UTF8);
80
    // Set the default input/output charset is utf-8
81
    SetConsoleCP(CP_UTF8);
82
    SetConsoleOutputCP(CP_UTF8);
83
#endif
84
85
3.19k
#ifndef WIN32
86
3.19k
    constexpr mode_t private_umask = 0077;
87
3.19k
    umask(private_umask);
88
3.19k
#endif
89
3.19k
}
90
91
bool SetupNetworking()
92
2.44k
{
93
#ifdef WIN32
94
    // Initialize Windows Sockets
95
    WSADATA wsadata;
96
    int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
97
    if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
98
        return false;
99
#endif
100
2.44k
    return true;
101
2.44k
}
102
103
int GetNumCores()
104
742
{
105
742
    return std::thread::hardware_concurrency();
106
742
}
107
108
std::optional<uint64_t> TryGetTotalRam()
109
5.30k
{
110
5.30k
    static const auto total_ram{[]() -> std::optional<uint64_t> {
111
#ifdef WIN32
112
        if (MEMORYSTATUSEX m{}; (m.dwLength = sizeof(m), GlobalMemoryStatusEx(&m))) return m.ullTotalPhys;
113
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__illumos__) || defined(__linux__)
114
1.34k
        if (long p{sysconf(_SC_PHYS_PAGES)}, s{sysconf(_SC_PAGESIZE)}; p > 0 && s > 0) return 1ULL * p * s;
115
0
#endif
116
0
        return std::nullopt;
117
1.34k
    }()};
118
5.30k
    return total_ram;
119
5.30k
}
120
121
namespace {
122
    const auto g_startup_time{SteadyClock::now()};
123
} // namespace
124
125
2
SteadyClock::duration GetUptime() { return SteadyClock::now() - g_startup_time; }