0.00% Lines (0/0) 0.00% Functions (0/0)
TLA Baseline Branch
Line Hits Code Line Hits Code
1 - //  
2 - // Copyright (c) 2026 Michael Vandeberg  
3 - //  
4 - // Distributed under the Boost Software License, Version 1.0. (See accompanying  
5 - // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)  
6 - //  
7 - // Official repository: https://github.com/cppalliance/corosio  
8 - //  
9 -  
10 - #ifndef BOOST_COROSIO_TEST_TEMP_PATH_HPP  
11 - #define BOOST_COROSIO_TEST_TEMP_PATH_HPP  
12 -  
13 - #include <atomic>  
14 - #include <cstdint>  
15 - #include <cstdio>  
16 - #include <filesystem>  
17 - #include <random>  
18 - #include <stdexcept>  
19 - #include <string>  
20 - #include <system_error>  
21 -  
22 - namespace boost::corosio::test {  
23 -  
24 - /** RAII temp directory holding a path for a Unix-domain socket.  
25 -  
26 - Creates a unique empty directory under  
27 - `std::filesystem::temp_directory_path()` and exposes a path under  
28 - it suitable for binding `local_stream_socket` /  
29 - `local_datagram_socket`. The destructor removes the directory  
30 - (and the bound socket file inside it) recursively, so tests that  
31 - throw mid-execution still clean up.  
32 -  
33 - Naming entropy comes from a process-wide atomic counter mixed with  
34 - a one-time `random_device` seed; that's enough to avoid collisions  
35 - between parallel test runs without requiring cryptographic  
36 - randomness. The constructor retries on collision and throws if it  
37 - cannot create a directory in a reasonable number of attempts.  
38 -  
39 - Platform note: the helper exists so tests don't need to call  
40 - `mkdtemp` / `unlink` / `rmdir` directly. On Windows, the path is  
41 - a filesystem AF_UNIX path (Windows 10 1803+).  
42 - */  
43 - class temp_socket_dir  
44 - {  
45 - public:  
DCB 46 - 121 temp_socket_dir()  
DCB 47 - 121 {  
48 - namespace fs = std::filesystem;  
DCB 49 - 121 auto const base = fs::temp_directory_path();  
50 -  
51 - // 64 bits of mixed entropy: a random seed established once  
52 - // at static init, XORed with a monotonic counter.  
DCB 53 - 9 static std::uint64_t const seed = [] {  
DCB 54 - 9 std::random_device rd;  
DCB 55 - 9 return (static_cast<std::uint64_t>(rd()) << 32) |  
DCB 56 - 18 static_cast<std::uint64_t>(rd());  
DCB 57 - 130 }();  
58 - static std::atomic<std::uint64_t> counter{0};  
59 -  
DCB 60 - 121 std::error_code ec;  
DCB 61 - 121 for (int tries = 0; tries < 32; ++tries)  
62 - {  
DCB 63 - 121 auto const n = counter.fetch_add(1, std::memory_order_relaxed);  
DCB 64 - 121 auto const tag = seed ^ n;  
65 -  
66 - char buf[32];  
DCB 67 - 121 std::snprintf(  
68 - buf, sizeof(buf), "corosio_test_%016llx",  
69 - static_cast<unsigned long long>(tag));  
70 -  
DCB 71 - 121 auto candidate = base / buf;  
DCB 72 - 121 if (fs::create_directory(candidate, ec))  
73 - {  
DCB 74 - 121 dir_ = std::move(candidate);  
DCB 75 - 242 return;  
76 - }  
DCB 77 - 121 }  
78 - throw std::runtime_error(  
DUB 79 - "temp_socket_dir: could not create temp directory: " +  
DUB 80 - ec.message());  
DCB 81 - 121 }  
82 -  
DCB 83 - 121 ~temp_socket_dir() noexcept  
DCB 84 - 121 {  
DCB 85 - 121 if (dir_.empty())  
DUB 86 - return;  
87 -  
DCB 88 - 121 std::error_code ec;  
89 -  
90 - // Unlink the socket file with C's std::remove from <cstdio>  
91 - // (deletes by name, no open) before remove_all, whose  
92 - // symlink_status opens AF_UNIX socket files via CreateFileW and  
93 - // hangs on Windows.  
DCB 94 - 121 std::remove(path().c_str());  
DCB 95 - 121 std::filesystem::remove_all(dir_, ec);  
DCB 96 - 121 }  
97 -  
98 - temp_socket_dir(temp_socket_dir const&) = delete;  
99 - temp_socket_dir& operator=(temp_socket_dir const&) = delete;  
100 -  
101 - /// Path suitable for binding a local socket.  
DCB 102 - 260 std::string path() const  
103 - {  
DCB 104 - 260 return (dir_ / "sock").string();  
105 - }  
106 -  
107 - private:  
108 - std::filesystem::path dir_;  
109 - };  
110 -  
111 - } // namespace boost::corosio::test  
112 -  
113 - #endif // BOOST_COROSIO_TEST_TEMP_PATH_HPP