Coverage Report

Created: 2025-12-08 07:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/log4cplus/src/socket.cxx
Line
Count
Source
1
// Module:  Log4CPLUS
2
// File:    socket.cxx
3
// Created: 4/2003
4
// Author:  Tad E. Smith
5
//
6
//
7
// Copyright 2003-2017 Tad E. Smith
8
//
9
// Licensed under the Apache License, Version 2.0 (the "License");
10
// you may not use this file except in compliance with the License.
11
// You may obtain a copy of the License at
12
//
13
//     http://www.apache.org/licenses/LICENSE-2.0
14
//
15
// Unless required by applicable law or agreed to in writing, software
16
// distributed under the License is distributed on an "AS IS" BASIS,
17
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
// See the License for the specific language governing permissions and
19
// limitations under the License.
20
21
#include <log4cplus/helpers/loglog.h>
22
#include <log4cplus/internal/socket.h>
23
#include <log4cplus/internal/internal.h>
24
25
#if defined (LOG4CPLUS_WITH_UNIT_TESTS)
26
#include <catch.hpp>
27
#endif
28
29
namespace log4cplus { namespace helpers {
30
31
32
extern LOG4CPLUS_EXPORT SOCKET_TYPE const INVALID_SOCKET_VALUE
33
#if defined(_WIN32)
34
    = static_cast<SOCKET_TYPE>(INVALID_SOCKET);
35
#else
36
    = static_cast<SOCKET_TYPE>(-1);
37
#endif
38
39
40
//////////////////////////////////////////////////////////////////////////////
41
// AbstractSocket ctors and dtor
42
//////////////////////////////////////////////////////////////////////////////
43
44
AbstractSocket::AbstractSocket()
45
0
    : sock(INVALID_SOCKET_VALUE),
46
0
      state(not_opened),
47
0
      err(0)
48
0
{
49
0
}
50
51
52
53
AbstractSocket::AbstractSocket(SOCKET_TYPE sock_, SocketState state_, int err_)
54
0
    : sock(sock_),
55
0
      state(state_),
56
0
      err(err_)
57
0
{
58
0
}
59
60
61
62
AbstractSocket::AbstractSocket(AbstractSocket && rhs) LOG4CPLUS_NOEXCEPT
63
0
    : AbstractSocket ()
64
0
{
65
0
    swap (rhs);
66
0
}
67
68
69
AbstractSocket::~AbstractSocket()
70
0
{
71
0
    close();
72
0
}
73
74
75
76
//////////////////////////////////////////////////////////////////////////////
77
// AbstractSocket methods
78
//////////////////////////////////////////////////////////////////////////////
79
80
void
81
AbstractSocket::close()
82
0
{
83
0
    if (sock != INVALID_SOCKET_VALUE)
84
0
    {
85
0
        closeSocket(sock);
86
0
        sock = INVALID_SOCKET_VALUE;
87
0
        state = not_opened;
88
0
    }
89
0
}
90
91
92
void
93
AbstractSocket::shutdown()
94
0
{
95
0
    if (sock != INVALID_SOCKET_VALUE)
96
0
        shutdownSocket(sock);
97
0
}
98
99
100
bool
101
AbstractSocket::isOpen() const
102
0
{
103
0
    return sock != INVALID_SOCKET_VALUE;
104
0
}
105
106
107
AbstractSocket &
108
AbstractSocket::operator = (AbstractSocket && rhs) LOG4CPLUS_NOEXCEPT
109
0
{
110
0
    swap (rhs);
111
0
    return *this;
112
0
}
113
114
115
void
116
AbstractSocket::swap (AbstractSocket & rhs)
117
0
{
118
0
    using std::swap;
119
120
0
    swap (sock, rhs.sock);
121
0
    swap (state, rhs.state);
122
0
    swap (err, rhs.err);
123
0
}
124
125
126
//////////////////////////////////////////////////////////////////////////////
127
// Socket ctors and dtor
128
//////////////////////////////////////////////////////////////////////////////
129
130
Socket::Socket()
131
0
    : AbstractSocket()
132
0
{ }
133
134
135
Socket::Socket(const tstring& address, unsigned short port,
136
    bool udp /*= false*/, bool ipv6 /*= false */)
137
0
    : AbstractSocket()
138
0
{
139
0
    sock = connectSocket(address, port, udp, ipv6, state);
140
0
    if (sock == INVALID_SOCKET_VALUE)
141
0
        goto error;
142
143
0
    if (! udp && setTCPNoDelay (sock, true) != 0)
144
0
        goto error;
145
146
0
    return;
147
148
0
error:
149
0
    err = get_last_socket_error ();
150
0
}
151
152
153
Socket::Socket(SOCKET_TYPE sock_, SocketState state_, int err_)
154
0
    : AbstractSocket(sock_, state_, err_)
155
0
{ }
156
157
158
Socket::Socket (Socket && other) LOG4CPLUS_NOEXCEPT
159
0
    : AbstractSocket (std::move (other))
160
0
{ }
161
162
163
Socket::~Socket()
164
{ }
165
166
167
Socket &
168
Socket::operator = (Socket && other) LOG4CPLUS_NOEXCEPT
169
0
{
170
0
    swap (other);
171
0
    return *this;
172
0
}
173
174
175
//////////////////////////////////////////////////////////////////////////////
176
// Socket methods
177
//////////////////////////////////////////////////////////////////////////////
178
179
bool
180
Socket::read(SocketBuffer& buffer)
181
0
{
182
0
    long retval = helpers::read(sock, buffer);
183
0
    if(retval <= 0) {
184
0
        close();
185
0
    }
186
0
    else {
187
0
        buffer.setSize(retval);
188
0
    }
189
190
0
    return (retval > 0);
191
0
}
192
193
194
195
bool
196
Socket::write(const SocketBuffer& buffer)
197
0
{
198
0
    long retval = helpers::write(sock, buffer);
199
0
    if(retval <= 0) {
200
0
        close();
201
0
    }
202
203
0
    return (retval > 0);
204
0
}
205
206
207
bool
208
Socket::write(std::size_t bufferCount, SocketBuffer const * const * buffers)
209
0
{
210
0
    long retval = helpers::write(sock, bufferCount, buffers);
211
0
    if (retval <= 0)
212
0
        close ();
213
214
0
    return retval > 0;
215
0
}
216
217
218
bool
219
Socket::write(const std::string & buffer)
220
0
{
221
0
    long retval = helpers::write (sock, buffer);
222
0
    if (retval <= 0)
223
0
        close();
224
225
0
    return retval > 0;
226
0
}
227
228
229
//
230
//
231
//
232
233
ServerSocket::ServerSocket (ServerSocket && other) LOG4CPLUS_NOEXCEPT
234
0
    : AbstractSocket (std::move (other))
235
0
{
236
0
    interruptHandles[0] = -1;
237
0
    interruptHandles[1] = -1;
238
0
    interruptHandles.swap (other.interruptHandles);
239
0
}
240
241
242
ServerSocket &
243
ServerSocket::operator = (ServerSocket && other) LOG4CPLUS_NOEXCEPT
244
0
{
245
0
    swap (other);
246
0
    return *this;
247
0
}
248
249
250
void
251
ServerSocket::swap (ServerSocket & other)
252
0
{
253
0
    AbstractSocket::swap (other);
254
0
    interruptHandles.swap (other.interruptHandles);
255
0
}
256
257
258
//
259
//
260
//
261
262
SOCKET_TYPE
263
openSocket(unsigned short port, bool udp, bool ipv6, SocketState& state)
264
0
{
265
0
    return openSocket(log4cplus::internal::empty_str, port, udp, ipv6, state);
266
0
}
267
268
269
#if defined (LOG4CPLUS_WITH_UNIT_TESTS)
270
CATCH_TEST_CASE ("Socket", "[sockets]")
271
{
272
    CATCH_SECTION ("hostname resolution")
273
    {
274
        CATCH_SECTION ("FQDN")
275
        {
276
            auto result = getHostname(true);
277
            CATCH_REQUIRE (result != LOG4CPLUS_C_STR_TO_TSTRING ("-"));
278
279
        }
280
281
        CATCH_SECTION ("non-FQDN")
282
        {
283
            auto result = getHostname(false);
284
            CATCH_REQUIRE (result != LOG4CPLUS_C_STR_TO_TSTRING ("-"));
285
        }
286
    }
287
}
288
#endif // LOG4CPLUS_WITH_UNIT_TESTS
289
290
291
} } // namespace log4cplus { namespace helpers {