src/corosio/src/host_name.cpp

60.0% Lines (18/30) 100.0% List of functions (1/1) 50.0% Branches (13/26)
host_name.cpp
f(x) Functions (1)
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
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 #include <boost/corosio/host_name.hpp>
11 #include <boost/corosio/detail/platform.hpp>
12
13 #include <string>
14 #include <system_error>
15
16 #if BOOST_COROSIO_POSIX
17 #include <cerrno>
18 #include <cstring>
19 #include <unistd.h>
20 #elif BOOST_COROSIO_HAS_IOCP
21 #include <windows.h>
22 #endif
23
24 namespace boost::corosio {
25
26 #if BOOST_COROSIO_POSIX
27
28 capy::io_result<std::string>
29 host_name()
30 {
31 // 256 exceeds POSIX's _POSIX_HOST_NAME_MAX floor of 255 and
32 // every mainstream OS's actual cap (Linux 64, macOS/BSD 255).
33 char buf[256];
34 if (::gethostname(buf, sizeof(buf)) != 0)
35 return {std::error_code(errno, std::system_category()), {}};
36
37 // POSIX does not guarantee NUL termination on truncation.
38 if (std::memchr(buf, '\0', sizeof(buf)) == nullptr)
39 return {make_error_code(std::errc::value_too_large), {}};
40
41 return {std::error_code{}, std::string(buf)};
42 }
43
44 #elif BOOST_COROSIO_HAS_IOCP
45
46 capy::io_result<std::string>
47 6x host_name()
48 {
49 // Size query: returns ERROR_MORE_DATA and writes the required
50 // wide-char count (including the trailing NUL) into `size`.
51 6x DWORD size = 0;
52
1/1
✓ Branch 2 → 3 taken 6 times.
6x BOOL ok = ::GetComputerNameExW(
53 ComputerNameDnsHostname, nullptr, &size);
54
1/1
✓ Branch 3 → 4 taken 6 times.
6x DWORD err = ::GetLastError();
55
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 10 taken 6 times.
6x if (ok)
56 {
57 // Can't-happen guard: a zero-length size query succeeding
58 // would leave `size` meaningless.
59 return {make_error_code(std::errc::protocol_error), {}};
60 }
61
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 16 taken 6 times.
6x if (err != ERROR_MORE_DATA)
62 return {
63 std::error_code(static_cast<int>(err), std::system_category()),
64 {}};
65
66 // On success, GetComputerNameExW rewrites `size` to the count
67 // without the NUL, so resize(size) below trims to the hostname.
68
1/1
✓ Branch 18 → 19 taken 6 times.
6x std::wstring wide(size, L'\0');
69
2/3
✓ Branch 21 → 22 taken 6 times.
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 29 taken 6 times.
6x if (!::GetComputerNameExW(
70 ComputerNameDnsHostname, wide.data(), &size))
71 return {
72 std::error_code(
73 static_cast<int>(::GetLastError()), std::system_category()),
74 {}};
75
1/1
✓ Branch 29 → 30 taken 6 times.
6x wide.resize(size);
76
77
1/1
✓ Branch 32 → 33 taken 6 times.
6x int needed = ::WideCharToMultiByte(
78 6x CP_UTF8, 0, wide.data(), static_cast<int>(wide.size()),
79 nullptr, 0, nullptr, nullptr);
80
1/2
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 40 taken 6 times.
6x if (needed <= 0)
81 return {
82 std::error_code(
83 static_cast<int>(::GetLastError()), std::system_category()),
84 {}};
85
86
1/1
✓ Branch 42 → 43 taken 6 times.
6x std::string out(static_cast<std::size_t>(needed), '\0');
87
1/1
✓ Branch 47 → 48 taken 6 times.
12x int written = ::WideCharToMultiByte(
88 6x CP_UTF8, 0, wide.data(), static_cast<int>(wide.size()),
89 out.data(), needed, nullptr, nullptr);
90
1/2
✗ Branch 48 → 49 not taken.
✓ Branch 48 → 55 taken 6 times.
6x if (written != needed)
91 return {
92 std::error_code(
93 static_cast<int>(::GetLastError()), std::system_category()),
94 {}};
95 6x return {std::error_code{}, std::move(out)};
96 6x }
97
98 #endif
99
100 } // namespace boost::corosio
101