• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jbaldwin / libcoro / 17091078498

20 Aug 2025 07:01AM UTC coverage: 88.109%. First build
17091078498

Pull #374

github

web-flow
Merge 32f694da8 into 1d472a8e9
Pull Request #374: Properly setup socket on linux

2 of 4 new or added lines in 1 file covered. (50.0%)

1645 of 1867 relevant lines covered (88.11%)

14093416.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.7
/src/net/socket.cpp
1
#include "coro/net/socket.hpp"
2
#include <sys/socket.h>
3

4
namespace coro::net
5
{
6
auto socket::type_to_os(type_t type) -> int
322✔
7
{
8
    switch (type)
322✔
9
    {
10
        case type_t::udp:
4✔
11
            return SOCK_DGRAM;
4✔
12
        case type_t::tcp:
318✔
13
            return SOCK_STREAM;
318✔
14
        default:
×
15
            throw std::runtime_error{"Unknown socket::type_t."};
×
16
    }
17
}
18

19
auto socket::operator=(const socket& other) noexcept -> socket&
×
20
{
21
    this->close();
×
22
    this->m_fd = dup(other.m_fd);
×
23
    return *this;
×
24
}
25

26
auto socket::operator=(socket&& other) noexcept -> socket&
×
27
{
28
    if (std::addressof(other) != this)
×
29
    {
30
        m_fd = std::exchange(other.m_fd, -1);
×
31
    }
32

33
    return *this;
×
34
}
35

36
auto socket::blocking(blocking_t block) -> bool
625✔
37
{
38
    if (m_fd < 0)
625✔
39
    {
40
        return false;
×
41
    }
42

43
    int flags = fcntl(m_fd, F_GETFL, 0);
625✔
44
    if (flags == -1)
625✔
45
    {
46
        return false;
×
47
    }
48

49
    // Add or subtract non-blocking flag.
50
    flags = (block == blocking_t::yes) ? flags & ~O_NONBLOCK : (flags | O_NONBLOCK);
625✔
51

52
    return (fcntl(m_fd, F_SETFL, flags) == 0);
625✔
53
}
54

55
auto socket::shutdown(poll_op how) -> bool
×
56
{
57
    if (m_fd != -1)
×
58
    {
59
        int h{0};
×
60
        switch (how)
×
61
        {
62
            case poll_op::read:
×
63
                h = SHUT_RD;
×
64
                break;
×
65
            case poll_op::write:
×
66
                h = SHUT_WR;
×
67
                break;
×
68
            case poll_op::read_write:
×
69
                h = SHUT_RDWR;
×
70
                break;
×
71
        }
72

73
        return (::shutdown(m_fd, h) == 0);
×
74
    }
75
    return false;
×
76
}
77

78
auto socket::close() -> void
2,440✔
79
{
80
    if (m_fd != -1)
2,440✔
81
    {
82
        ::close(m_fd);
626✔
83
        m_fd = -1;
626✔
84
    }
85
}
2,440✔
86

87
auto make_socket(const socket::options& opts) -> socket
322✔
88
{
89
    socket s{::socket(static_cast<int>(opts.domain), socket::type_to_os(opts.type), 0)};
322✔
90
    if (s.native_handle() < 0)
322✔
91
    {
92
        throw std::runtime_error{"Failed to create socket."};
×
93
    }
94

95
    if (opts.blocking == socket::blocking_t::no)
322✔
96
    {
97
        if (s.blocking(socket::blocking_t::no) == false)
322✔
98
        {
99
            throw std::runtime_error{"Failed to set socket to non-blocking mode."};
×
100
        }
101
    }
102

103
    return s;
322✔
104
}
×
105

106
auto make_accept_socket(const socket::options& opts, const net::ip_address& address, uint16_t port, int32_t backlog)
18✔
107
    -> socket
108
{
109
    socket s = make_socket(opts);
18✔
110

111
    int sock_opt{1};
18✔
112

113
#if defined(__linux__)
114
    // On Linux the address and port should be marked for reuse.
115
    if (setsockopt(s.native_handle(), SOL_SOCKET, SO_REUSEADDR, &sock_opt, sizeof(sock_opt)) < 0)
18✔
116
    {
NEW
117
        throw std::runtime_error{"Failed to setsockopt(SO_REUSEADDR)"};
×
118
    }
119
#endif
120

121
    if (setsockopt(s.native_handle(), SOL_SOCKET, SO_REUSEPORT, &sock_opt, sizeof(sock_opt)) < 0)
18✔
122
    {
NEW
123
        throw std::runtime_error{"Failed to setsockopt(SO_REUSEPORT)"};
×
124
    }
125

126
    sockaddr_in server{};
18✔
127
    server.sin_family = static_cast<int>(opts.domain);
18✔
128
    server.sin_port   = htons(port);
18✔
129
    server.sin_addr   = *reinterpret_cast<const in_addr*>(address.data().data());
18✔
130

131
    if (bind(s.native_handle(), reinterpret_cast<sockaddr*>(&server), sizeof(server)) < 0)
18✔
132
    {
133
        throw std::runtime_error{"Failed to bind."};
×
134
    }
135

136
    if (opts.type == socket::type_t::tcp)
18✔
137
    {
138
        if (listen(s.native_handle(), backlog) < 0)
15✔
139
        {
140
            throw std::runtime_error{"Failed to listen."};
×
141
        }
142
    }
143

144
    return s;
36✔
145
}
×
146

147
} // namespace coro::net
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc