src/corosio/src/host_name.cpp

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