source: sources/src/ioNetworkConnection.cc @ 1464:3f6711617be1

Revision 1464:3f6711617be1, 10.3 KB checked in by niam, 22 months ago (diff)

{issue #58[resolved]} support for non-c++ exceptions

Line 
1/***************************************************************************
2 *            ioNetworkConnection.cc
3 *
4 *  Thu Sep 20 2005
5 *  Copyright  2005  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#include <sys/socket.h>
33#include <fcntl.h>
34#include <errno.h>
35#include <string.h>
36#include <unistd.h>
37
38#include <libdodo/ioNetworkConnection.h>
39#include <libdodo/ioNetworkConnectionEx.h>
40
41using namespace dodo::io::network;
42
43connection::connection() : lingerOpts(IONETWORKCONNECTION_SOCKET_LINGER_OPTION),
44                           lingerSeconds(IONETWORKCONNECTION_SOCKET_LINGER_PERIOD),
45                           inSocketTimeout(IONETWORKCONNECTION_SOCKET_RECEIVE_TIMEOUT),
46                           outSocketTimeout(IONETWORKCONNECTION_SOCKET_SEND_TIMEOUT),
47                           inSocketBufferSize(IONETWORKCONNECTION_SOCKETBUFFER_INSIZE),
48                           outSocketBufferSize(IONETWORKCONNECTION_SOCKETBUFFER_OUTSIZE),
49                           socket(-1),
50                           blocked(true)
51{
52}
53
54//-------------------------------------------------------------------
55
56connection::~connection()
57{
58}
59
60//-------------------------------------------------------------------
61
62bool
63connection::isBlocked() const
64{
65    return blocked;
66}
67
68//-------------------------------------------------------------------
69
70void
71connection::block(bool flag)
72{
73    if (socket == -1)
74        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_BLOCK, exception::ERRNO_LIBDODO, CONNECTIONEX_NOSOCKETCREATED, IONETWORKCONNECTIONEX_NOSOCKETCREATED_STR, __LINE__, __FILE__);
75
76    int block = fcntl(socket, F_GETFL);
77    if (block == -1)
78        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_BLOCK, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
79
80    if (flag)
81        block &= ~O_NONBLOCK;
82    else
83        block |= O_NONBLOCK;
84
85    if (fcntl(socket, F_SETFL, block) == 1)
86        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_BLOCK, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
87
88    blocked = flag;
89}
90
91//-------------------------------------------------------------------
92
93void
94connection::setInBufferSize(unsigned long bytes)
95{
96    if (socket == -1)
97        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETINBUFFERSIZE, exception::ERRNO_LIBDODO, CONNECTIONEX_NOSOCKETCREATED, IONETWORKCONNECTIONEX_NOSOCKETCREATED_STR, __LINE__, __FILE__);
98
99    inSocketBufferSize = bytes;
100
101    if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &inSocketBufferSize, sizeof(long)) == 1)
102        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETINBUFFERSIZE, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
103}
104
105//-------------------------------------------------------------------
106
107unsigned long
108connection::inBufferSize() const
109{
110    return inSocketBufferSize;
111}
112
113//-------------------------------------------------------------------
114
115void
116connection::setOutBufferSize(unsigned long bytes)
117{
118    if (socket == -1)
119        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETOUTBUFFERSIZE, exception::ERRNO_LIBDODO, CONNECTIONEX_NOSOCKETCREATED, IONETWORKCONNECTIONEX_NOSOCKETCREATED_STR, __LINE__, __FILE__);
120
121    outSocketBufferSize = bytes;
122
123    if (setsockopt(socket, SOL_SOCKET, SO_SNDBUF, &outSocketBufferSize, sizeof(long)) == 1)
124        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETOUTBUFFERSIZE, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
125}
126
127//-------------------------------------------------------------------
128
129unsigned long
130connection::outBufferSize() const
131{
132    return outSocketBufferSize;
133}
134
135//-------------------------------------------------------------------
136
137void
138connection::setInTimeout(unsigned long microseconds)
139{
140    if (socket == -1)
141        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETINTIMEOUT, exception::ERRNO_LIBDODO, CONNECTIONEX_NOSOCKETCREATED, IONETWORKCONNECTIONEX_NOSOCKETCREATED_STR, __LINE__, __FILE__);
142
143    inSocketTimeout = microseconds;
144
145    timeval val;
146    val.tv_sec = inSocketTimeout / 100;
147    val.tv_usec = inSocketTimeout % 100;
148
149    if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &val, sizeof(val)) == 1)
150        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETINTIMEOUT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
151}
152
153//-------------------------------------------------------------------
154
155unsigned long
156connection::inTimeout() const
157{
158    return inSocketTimeout;
159}
160
161//-------------------------------------------------------------------
162
163void
164connection::setOutTimeout(unsigned long microseconds)
165{
166    if (socket == -1)
167        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETOUTTIMEOUT, exception::ERRNO_LIBDODO, CONNECTIONEX_NOSOCKETCREATED, IONETWORKCONNECTIONEX_NOSOCKETCREATED_STR, __LINE__, __FILE__);
168
169    outSocketTimeout = microseconds;
170
171    timeval val;
172    val.tv_sec = outSocketTimeout / 100;
173    val.tv_usec = outSocketTimeout % 100;
174
175    if (setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &val, sizeof(val)) == 1)
176        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETOUTTIMEOUT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
177}
178
179//-------------------------------------------------------------------
180
181unsigned long
182connection::outTimeout() const
183{
184    return outSocketTimeout;
185}
186
187//-------------------------------------------------------------------
188
189bool
190connection::isSetOption(int option) const
191{
192    if  ((option & socketOpts) == option)
193        return true;
194
195    return false;
196}
197
198//-------------------------------------------------------------------
199
200void
201connection::setOption(short option,
202                      bool  flag)
203{
204    if (socket == -1)
205        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETSOCKOPT, exception::ERRNO_LIBDODO, CONNECTIONEX_NOSOCKETCREATED, IONETWORKCONNECTIONEX_NOSOCKETCREATED_STR, __LINE__, __FILE__);
206
207    int sockFlag(1);
208
209    if (!flag)
210        sockFlag = 0;
211
212    int real_option(0);
213
214    switch (option) {
215        case OPTION_KEEP_ALIVE:
216
217            real_option = SO_KEEPALIVE;
218
219            break;
220
221        case OPTION_REUSE_ADDRESS:
222
223            real_option = SO_REUSEADDR;
224
225            break;
226
227        case OPTION_DONOT_USE_GATEWAY:
228
229            real_option = SO_DONTROUTE;
230
231            break;
232
233        case OPTION_BROADCAST:
234
235            real_option = SO_BROADCAST;
236
237            break;
238
239        case OPTION_OOB_INLINE:
240
241            real_option = SO_OOBINLINE;
242
243            break;
244
245        default:
246
247            dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETSOCKOPT, exception::ERRNO_LIBDODO, CONNECTIONEX_WRONGPARAMETER, IONETWORKCONNECTIONEX_WRONGPARAMETER_STR, __LINE__, __FILE__);
248    }
249
250    if (setsockopt(socket, SOL_SOCKET, real_option, &sockFlag, sizeof(int)) == 1)
251        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETSOCKOPT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
252
253    if (!flag)
254        removeFlag(socketOpts, 1 << option);
255    else
256        addFlag(socketOpts, 1 << option);
257}
258
259//-------------------------------------------------------------------
260
261void
262connection::setLingerOption(short option,
263                            int   seconds)
264{
265    if (socket == -1)
266        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETLINGERSOCKOPT, exception::ERRNO_LIBDODO, CONNECTIONEX_NOSOCKETCREATED, IONETWORKCONNECTIONEX_NOSOCKETCREATED_STR, __LINE__, __FILE__);
267
268    linger lin;
269
270    switch (option) {
271        case LINGER_OPTION_GRACEFUL_CLOSE:
272
273            lin.l_onoff = 0;
274
275            break;
276
277        case LINGER_OPTION_HARD_CLOSE:
278
279            lin.l_onoff = 1;
280            lin.l_linger = 0;
281
282            break;
283
284        case LINGER_OPTION_WAIT_CLOSE:
285
286            lin.l_onoff = 1;
287            lin.l_linger = seconds;
288
289            break;
290
291        default:
292
293            dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETLINGERSOCKOPT, exception::ERRNO_LIBDODO, CONNECTIONEX_WRONGPARAMETER, IONETWORKCONNECTIONEX_WRONGPARAMETER_STR, __LINE__, __FILE__);
294    }
295
296    if (setsockopt(socket, SOL_SOCKET, SO_LINGER, &lin, sizeof(linger)) == 1)
297        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX_SETLINGERSOCKOPT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
298
299    lingerOpts = option;
300    lingerSeconds = seconds;
301}
302
303//-------------------------------------------------------------------
304
305short
306connection::lingerOption() const
307{
308    return lingerOpts;
309}
310
311//-------------------------------------------------------------------
312
313int
314connection::lingerPeriod() const
315{
316    return lingerSeconds;
317}
318
319//-------------------------------------------------------------------
320
321void
322connection::_close(int socket)
323{
324    if (::shutdown(socket, SHUT_RDWR) == -1)
325        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX__CLOSE, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
326
327    if (::close(socket) == -1)
328        dodo_throw exception::basic(exception::MODULE_IONETWORKCONNECTION, CONNECTIONEX__CLOSE, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
329}
330
331//-------------------------------------------------------------------
332
Note: See TracBrowser for help on using the repository browser.