Commit 17329d17ef2f640c5f03e36351f1e19f43acf108 lint: Add exclusions for libmultiprocess subtree
looks suboptimal because it adds exceptions for the entire src/ipc/libmultiprocess/
subtree for a whole class of issues. Because there are a few specific issues currently. Even if they are ok, it means new issues will sneak in src/ipc/libmultiprocess/
unnoticed.
It would be better to either resolve the issues and not exclude src/ipc/libmultiprocess/
from linters or add exceptions for the particular issues mentioned in the commit message, so that newly added issues in the future will be detected.
Here is a patch to resolve the locale-dependent issues:
0diff --git i/src/ipc/libmultiprocess/example/calculator.cpp w/src/ipc/libmultiprocess/example/calculator.cpp
1index 4290d68733..6926fb8b57 100644
2--- i/src/ipc/libmultiprocess/example/calculator.cpp
3+++ w/src/ipc/libmultiprocess/example/calculator.cpp
4@@ -1,11 +1,12 @@
5 // Copyright (c) 2021 The Bitcoin Core developers
6 // Distributed under the MIT software license, see the accompanying
7 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
8
9 #include <calculator.h>
10+#include <charconv>
11 #include <fstream>
12 #include <init.capnp.h>
13 #include <init.capnp.proxy.h> // NOLINT(misc-include-cleaner)
14 #include <init.h>
15 #include <iostream>
16 #include <memory>
17@@ -41,13 +42,17 @@ static void LogPrint(bool raise, const std::string& message)
18 int main(int argc, char** argv)
19 {
20 if (argc != 2) {
21 std::cout << "Usage: mpcalculator <fd>\n";
22 return 1;
23 }
24+ int fd;
25+ if (std::from_chars(argv[1], argv[1] + strlen(argv[1]), fd).ec != std::errc{}) {
26+ std::cout << argv[1] << " is not a number or is larger than an int\n";
27+ return 1;
28+ }
29 mp::EventLoop loop("mpcalculator", LogPrint);
30- const int fd = std::stoi(argv[1]);
31 std::unique_ptr<Init> init = std::make_unique<InitImpl>();
32 mp::ServeStream<InitInterface>(loop, fd, *init);
33 loop.loop();
34 return 0;
35 }
36diff --git i/src/ipc/libmultiprocess/example/example.cpp w/src/ipc/libmultiprocess/example/example.cpp
37index a4f84c55a7..d0e9458f5c 100644
38--- i/src/ipc/libmultiprocess/example/example.cpp
39+++ w/src/ipc/libmultiprocess/example/example.cpp
40@@ -22,13 +22,13 @@ static auto Spawn(mp::EventLoop& loop, const std::string& process_argv0, const s
41 {
42 int pid;
43 const int fd = mp::SpawnProcess(pid, [&](int fd) -> std::vector<std::string> {
44 fs::path path = process_argv0;
45 path.remove_filename();
46 path.append(new_exe_name);
47- return {path.string(), std::to_string(fd)};
48+ return {path.string(), std::format("{:d}", fd)};
49 });
50 return std::make_tuple(mp::ConnectStream<InitInterface>(loop, fd), pid);
51 }
52
53 static void LogPrint(bool raise, const std::string& message)
54 {
55diff --git i/src/ipc/libmultiprocess/example/printer.cpp w/src/ipc/libmultiprocess/example/printer.cpp
56index ccaed6890c..924c651784 100644
57--- i/src/ipc/libmultiprocess/example/printer.cpp
58+++ w/src/ipc/libmultiprocess/example/printer.cpp
59@@ -1,11 +1,12 @@
60 // Copyright (c) 2021 The Bitcoin Core developers
61 // Distributed under the MIT software license, see the accompanying
62 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
63
64 #include <fstream>
65+#include <charconv>
66 #include <init.capnp.h>
67 #include <init.capnp.proxy.h> // NOLINT(misc-include-cleaner)
68 #include <init.h>
69 #include <iostream>
70 #include <memory>
71 #include <mp/proxy-io.h>
72@@ -34,13 +35,17 @@ static void LogPrint(bool raise, const std::string& message)
73 int main(int argc, char** argv)
74 {
75 if (argc != 2) {
76 std::cout << "Usage: mpprinter <fd>\n";
77 return 1;
78 }
79+ int fd;
80+ if (std::from_chars(argv[1], argv[1] + strlen(argv[1]), fd).ec != std::errc{}) {
81+ std::cout << argv[1] << " is not a number or is larger than an int\n";
82+ return 1;
83+ }
84 mp::EventLoop loop("mpprinter", LogPrint);
85- const int fd = std::stoi(argv[1]);
86 std::unique_ptr<Init> init = std::make_unique<InitImpl>();
87 mp::ServeStream<InitInterface>(loop, fd, *init);
88 loop.loop();
89 return 0;
90 }
91diff --git i/src/ipc/libmultiprocess/src/mp/gen.cpp w/src/ipc/libmultiprocess/src/mp/gen.cpp
92index c4d9a51675..267c2837a6 100644
93--- i/src/ipc/libmultiprocess/src/mp/gen.cpp
94+++ w/src/ipc/libmultiprocess/src/mp/gen.cpp
95@@ -10,12 +10,13 @@
96 #include <cstdint>
97 #include <cstdio>
98 #include <cstdlib>
99 #include <errno.h>
100 #include <fstream>
101 #include <functional>
102+#include <iostream>
103 #include <kj/array.h>
104 #include <kj/common.h>
105 #include <kj/filesystem.h>
106 #include <kj/memory.h>
107 #include <kj/string.h>
108 #include <map>
109@@ -634,13 +635,13 @@ static void Generate(kj::StringPtr src_prefix,
110 h << "#endif\n";
111 }
112
113 int main(int argc, char** argv)
114 {
115 if (argc < 3) {
116- fprintf(stderr, "Usage: " PROXY_BIN " SRC_PREFIX INCLUDE_PREFIX SRC_FILE [IMPORT_PATH...]\n");
117+ std::cerr << "Usage: " << PROXY_BIN << " SRC_PREFIX INCLUDE_PREFIX SRC_FILE [IMPORT_PATH...]\n";
118 exit(1);
119 }
120 std::vector<kj::StringPtr> import_paths;
121 std::vector<kj::Own<const kj::ReadableDirectory>> import_dirs;
122 auto fs = kj::newDiskFilesystem();
123 auto cwd = fs->getCurrentPath();
124diff --git i/src/ipc/libmultiprocess/src/mp/util.cpp w/src/ipc/libmultiprocess/src/mp/util.cpp
125index 691ae0b34b..15c40b3373 100644
126--- i/src/ipc/libmultiprocess/src/mp/util.cpp
127+++ w/src/ipc/libmultiprocess/src/mp/util.cpp
128@@ -3,12 +3,13 @@
129 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
130
131 #include <mp/config.h>
132 #include <mp/util.h>
133
134 #include <errno.h>
135+#include <format>
136 #include <kj/common.h>
137 #include <kj/string-tree.h>
138 #include <pthread.h>
139 #include <sstream>
140 #include <stdio.h>
141 #include <string>
142@@ -82,15 +83,13 @@ std::string LogEscape(const kj::StringTree& string)
143 string.visit([&](const kj::ArrayPtr<const char>& piece) {
144 if (result.size() > MAX_SIZE) return;
145 for (const char c : piece) {
146 if (c == '\\') {
147 result.append("\\\\");
148 } else if (c < 0x20 || c > 0x7e) {
149- char escape[4];
150- snprintf(escape, 4, "\\%02x", c);
151- result.append(escape);
152+ result.append(std::format("\\{:02x}", c));
153 } else {
154 result.push_back(c);
155 }
156 if (result.size() > MAX_SIZE) {
157 result += "...";
158 break;
159diff --git i/src/ipc/libmultiprocess/test/mp/test/test.cpp w/src/ipc/libmultiprocess/test/mp/test/test.cpp
160index 7721d41ff6..7fc64f6741 100644
161--- i/src/ipc/libmultiprocess/test/mp/test/test.cpp
162+++ w/src/ipc/libmultiprocess/test/mp/test/test.cpp
163@@ -8,12 +8,13 @@
164 #include <mp/test/foo.h>
165
166 #include <capnp/capability.h>
167 #include <cstdio>
168 #include <future>
169 #include <functional>
170+#include <iostream>
171 #include <memory>
172 #include <kj/common.h>
173 #include <kj/memory.h>
174 #include <kj/test.h>
175 #include <string>
176 #include <thread>
177@@ -24,13 +25,15 @@ namespace test {
178
179 KJ_TEST("Call FooInterface methods")
180 {
181 std::promise<std::unique_ptr<ProxyClient<messages::FooInterface>>> foo_promise;
182 std::function<void()> disconnect_client;
183 std::thread thread([&]() {
184- EventLoop loop("mptest", [](bool raise, const std::string& log) { printf("LOG%i: %s\n", raise, log.c_str()); });
185+ EventLoop loop("mptest", [](bool raise, const std::string& log) {
186+ std::cout << "LOG" << raise << ": " << log << "\n";
187+ });
188 auto pipe = loop.m_io_context.provider->newTwoWayPipe();
189
190 auto connection_client = std::make_unique<Connection>(loop, kj::mv(pipe.ends[0]));
191 auto foo_client = std::make_unique<ProxyClient<messages::FooInterface>>(
192 connection_client->m_rpc_system->bootstrap(ServerVatId().vat_id).castAs<messages::FooInterface>(),
193 connection_client.get(), /* destroy_connection= */ false);
194diff --git i/test/lint/lint-locale-dependence.py w/test/lint/lint-locale-dependence.py
195index 1b1aeffdcb..d84e458bb1 100755
196--- i/test/lint/lint-locale-dependence.py
197+++ w/test/lint/lint-locale-dependence.py
198@@ -48,13 +48,12 @@ KNOWN_VIOLATIONS = [
199 "src/wallet/bdb.cpp:.*DbEnv::strerror", # False positive
200 "src/util/syserror.cpp:.*strerror", # Outside this function use `SysErrorString`
201 ]
202
203 REGEXP_EXTERNAL_DEPENDENCIES_EXCLUSIONS = [
204 "src/crypto/ctaes/",
205- "src/ipc/libmultiprocess/",
206 "src/leveldb/",
207 "src/secp256k1/",
208 "src/minisketch/",
209 "src/tinyformat.h",
210 ]
211
And also another one to still run test_runner
on src/ipc/libmultiprocess/
but only skip std::filesystem
check for example.cpp
and the include guard test for the entire src/ipc/libmultiprocess/
:
0diff --git i/test/lint/lint-include-guards.py w/test/lint/lint-include-guards.py
1index 77af05c1c2..ed10deaa90 100755
2--- i/test/lint/lint-include-guards.py
3+++ w/test/lint/lint-include-guards.py
4@@ -17,12 +17,13 @@ from lint_ignore_dirs import SHARED_EXCLUDED_SUBTREES
5
6 HEADER_ID_PREFIX = 'BITCOIN_'
7 HEADER_ID_SUFFIX = '_H'
8
9 EXCLUDE_FILES_WITH_PREFIX = ['contrib/devtools/bitcoin-tidy',
10 'src/crypto/ctaes',
11+ 'src/ipc/libmultiprocess',
12 'src/tinyformat.h',
13 'src/bench/nanobench.h',
14 'src/test/fuzz/FuzzedDataProvider.h'] + SHARED_EXCLUDED_SUBTREES
15
16
17 def _get_header_file_lst() -> list[str]:
18diff --git i/test/lint/lint_ignore_dirs.py w/test/lint/lint_ignore_dirs.py
19index 7525eac341..af9ee7ef6b 100644
20--- i/test/lint/lint_ignore_dirs.py
21+++ w/test/lint/lint_ignore_dirs.py
22@@ -1,6 +1,5 @@
23 SHARED_EXCLUDED_SUBTREES = ["src/leveldb/",
24 "src/crc32c/",
25 "src/secp256k1/",
26 "src/minisketch/",
27- "src/ipc/libmultiprocess/",
28 ]
29diff --git i/test/lint/test_runner/src/main.rs w/test/lint/test_runner/src/main.rs
30index fe77a98c29..a633f5d43d 100644
31--- i/test/lint/test_runner/src/main.rs
32+++ w/test/lint/test_runner/src/main.rs
33@@ -284,13 +284,13 @@ fn lint_std_filesystem() -> LintResult {
34 .args([
35 "grep",
36 "--line-number",
37 "std::filesystem",
38 "--",
39 "./src/",
40- ":(exclude)src/ipc/libmultiprocess/",
41+ ":(exclude)src/ipc/libmultiprocess/example/example.cpp",
42 ":(exclude)src/util/fs.h",
43 ])
44 .status()
45 .expect("command error")
46 .success();
47 if found {