]> git.saurik.com Git - wxWidgets.git/blame - src/unix/gsocket.cpp
add very simple (but already exposing many problems) wxIPC benchmark
[wxWidgets.git] / src / unix / gsocket.cpp
CommitLineData
97e6ee04 1/* -------------------------------------------------------------------------
99d80019
JS
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Authors: David Elliott (C++ conversion, maintainer)
7 * Guilhem Lavaux,
8 * Guillermo Rodriguez Garcia <guille@iies.es>
9 * Purpose: GSocket main Unix and OS/2 file
10 * Licence: The wxWindows licence
11 * CVSID: $Id$
97e6ee04
DE
12 * -------------------------------------------------------------------------
13 */
14
7e1e6965
WS
15#if defined(__WATCOMC__)
16#include "wx/wxprec.h"
17#include <errno.h>
18#include <nerrno.h>
19#endif
20
ba2a81d7 21#ifndef __GSOCKET_STANDALONE__
0beb8735 22#include "wx/defs.h"
5e1eac14 23#include "wx/private/gsocketiohandler.h"
ba2a81d7 24#endif
97e6ee04
DE
25
26#if defined(__VISAGECPP__)
1aa7b427 27#define BSD_SELECT /* use Berkeley Sockets select */
97e6ee04
DE
28#endif
29
30#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
31
32#include <assert.h>
33#include <sys/types.h>
34#ifdef __VISAGECPP__
35#include <string.h>
36#include <sys/time.h>
37#include <types.h>
38#include <netinet/in.h>
39#endif
40#include <netdb.h>
41#include <sys/ioctl.h>
42
bc023abb
MW
43#ifdef HAVE_SYS_SELECT_H
44# include <sys/select.h>
45#endif
46
97e6ee04
DE
47#ifdef __VMS__
48#include <socket.h>
49struct sockaddr_un
50{
51 u_char sun_len; /* sockaddr len including null */
52 u_char sun_family; /* AF_UNIX */
53 char sun_path[108]; /* path name (gag) */
54};
55#else
56#include <sys/socket.h>
57#include <sys/un.h>
58#endif
59
60#ifndef __VISAGECPP__
61#include <sys/time.h>
62#include <netinet/in.h>
63#include <arpa/inet.h>
64#include <errno.h>
65#include <string.h>
66#include <unistd.h>
67#else
68#include <nerrno.h>
69# if __IBMCPP__ < 400
70#include <machine/endian.h>
71#include <socket.h>
72#include <ioctl.h>
73#include <select.h>
74#include <unistd.h>
75
76#define EBADF SOCEBADF
77
78# ifdef min
79# undef min
80# endif
81# else
82#include <sys/socket.h>
83#include <sys/ioctl.h>
84#include <sys/select.h>
85
86#define close(a) soclose(a)
87#define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
88int _System bsdselect(int,
89 struct fd_set *,
90 struct fd_set *,
91 struct fd_set *,
92 struct timeval *);
93int _System soclose(int);
94# endif
95#endif
ebdab982
SN
96#ifdef __EMX__
97#include <sys/select.h>
98#endif
99
97e6ee04
DE
100#include <stdio.h>
101#include <stdlib.h>
102#include <stddef.h>
103#include <ctype.h>
104#ifdef sun
105# include <sys/filio.h>
106#endif
107#ifdef sgi
108# include <bstring.h>
109#endif
d1f8e97b
SN
110#ifdef _AIX
111# include <strings.h>
112#endif
97e6ee04
DE
113#include <signal.h>
114
9e03e02d 115#ifndef WX_SOCKLEN_T
97e6ee04
DE
116
117#ifdef VMS
9e03e02d 118# define WX_SOCKLEN_T unsigned int
97e6ee04
DE
119#else
120# ifdef __GLIBC__
121# if __GLIBC__ == 2
9e03e02d 122# define WX_SOCKLEN_T socklen_t
97e6ee04 123# endif
fcbd7e5a 124# elif defined(__WXMAC__)
9e03e02d 125# define WX_SOCKLEN_T socklen_t
97e6ee04 126# else
9e03e02d 127# define WX_SOCKLEN_T int
97e6ee04
DE
128# endif
129#endif
130
131#endif /* SOCKLEN_T */
132
ddc1a35f 133#ifndef SOCKOPTLEN_T
9e03e02d 134#define SOCKOPTLEN_T WX_SOCKLEN_T
ddc1a35f
DE
135#endif
136
97e6ee04
DE
137/*
138 * MSW defines this, Unices don't.
139 */
140#ifndef INVALID_SOCKET
141#define INVALID_SOCKET -1
142#endif
143
144/* UnixWare reportedly needs this for FIONBIO definition */
145#ifdef __UNIXWARE__
146#include <sys/filio.h>
147#endif
148
149/*
150 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
151 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
152 */
153#ifndef INADDR_NONE
154#define INADDR_NONE INADDR_BROADCAST
155#endif
156
7e1e6965 157#if defined(__VISAGECPP__) || defined(__WATCOMC__)
97e6ee04 158
7e1e6965
WS
159 #define MASK_SIGNAL() {
160 #define UNMASK_SIGNAL() }
161
162#else
defbeca1 163 extern "C" { typedef void (*wxSigHandler)(int); }
7e1e6965
WS
164
165 #define MASK_SIGNAL() \
166 { \
defbeca1 167 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
7e1e6965
WS
168
169 #define UNMASK_SIGNAL() \
170 signal(SIGPIPE, old_handler); \
171 }
172
173#endif
97e6ee04 174
e400d27d
KH
175/* If a SIGPIPE is issued by a socket call on a remotely closed socket,
176 the program will "crash" unless it explicitly handles the SIGPIPE.
177 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
178 use SO_NOSIGPIPE (if available), the BSD equivalent. */
bb154f79
KH
179#ifdef MSG_NOSIGNAL
180# define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
181#else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
182# define GSOCKET_MSG_NOSIGNAL 0
183#endif /* MSG_NOSIGNAL */
97e6ee04
DE
184
185#ifndef __GSOCKET_STANDALONE__
186# include "wx/unix/gsockunx.h"
17a1ebd1 187# include "wx/unix/private.h"
97e6ee04 188# include "wx/gsocket.h"
71b4a9b8
SN
189#if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
190# include "wx/thread.h"
191#endif
97e6ee04
DE
192#else
193# include "gsockunx.h"
194# include "gsocket.h"
5fb9aa56
WS
195# ifndef WXUNUSED
196# define WXUNUSED(x)
197# endif
97e6ee04
DE
198#endif /* __GSOCKET_STANDALONE__ */
199
71b4a9b8
SN
200#if defined(HAVE_GETHOSTBYNAME)
201static struct hostent * deepCopyHostent(struct hostent *h,
202 const struct hostent *he,
203 char *buffer, int size, int *err)
204{
2887cb4e 205 /* copy old structure */
71b4a9b8 206 memcpy(h, he, sizeof(struct hostent));
2887cb4e
SN
207
208 /* copy name */
71b4a9b8
SN
209 int len = strlen(h->h_name);
210 if (len > size)
2887cb4e
SN
211 {
212 *err = ENOMEM;
213 return NULL;
214 }
71b4a9b8
SN
215 memcpy(buffer, h->h_name, len);
216 buffer[len] = '\0';
217 h->h_name = buffer;
2887cb4e
SN
218
219 /* track position in the buffer */
220 int pos = len + 1;
221
222 /* reuse len to store address length */
71b4a9b8 223 len = h->h_length;
2887cb4e
SN
224
225 /* ensure pointer alignment */
226 unsigned int misalign = sizeof(char *) - pos%sizeof(char *);
227 if(misalign < sizeof(char *))
228 pos += misalign;
229
230 /* leave space for pointer list */
231 char **p = h->h_addr_list, **q;
232 char **h_addr_list = (char **)(buffer + pos);
233 while(*(p++) != 0)
234 pos += sizeof(char *);
235
236 /* copy addresses and fill new pointer list */
237 for (p = h->h_addr_list, q = h_addr_list; *p != 0; p++, q++)
238 {
239 if (size < pos + len)
240 {
71b4a9b8
SN
241 *err = ENOMEM;
242 return NULL;
243 }
2887cb4e
SN
244 memcpy(buffer + pos, *p, len); /* copy content */
245 *q = buffer + pos; /* set copied pointer to copied content */
246 pos += len;
71b4a9b8 247 }
2887cb4e
SN
248 *++q = 0; /* null terminate the pointer list */
249 h->h_addr_list = h_addr_list; /* copy pointer to pointers */
250
251 /* ensure word alignment of pointers */
252 misalign = sizeof(char *) - pos%sizeof(char *);
253 if(misalign < sizeof(char *))
254 pos += misalign;
01ba4b67 255
2887cb4e
SN
256 /* leave space for pointer list */
257 p = h->h_aliases;
258 char **h_aliases = (char **)(buffer + pos);
259 while(*(p++) != 0)
260 pos += sizeof(char *);
01ba4b67 261
2887cb4e
SN
262 /* copy aliases and fill new pointer list */
263 for (p = h->h_aliases, q = h_aliases; *p != 0; p++, q++)
264 {
265 len = strlen(*p);
266 if (size <= pos + len)
267 {
268 *err = ENOMEM;
269 return NULL;
270 }
271 memcpy(buffer + pos, *p, len); /* copy content */
272 buffer[pos + len] = '\0';
273 *q = buffer + pos; /* set copied pointer to copied content */
274 pos += len + 1;
71b4a9b8 275 }
2887cb4e
SN
276 *++q = 0; /* null terminate the pointer list */
277 h->h_aliases = h_aliases; /* copy pointer to pointers */
278
71b4a9b8
SN
279 return h;
280}
281#endif
282
2887cb4e
SN
283#if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
284static wxMutex nameLock;
285#endif
71b4a9b8
SN
286struct hostent * wxGethostbyname_r(const char *hostname, struct hostent *h,
287 void *buffer, int size, int *err)
288
289{
539ae551 290 struct hostent *he = NULL;
71b4a9b8
SN
291 *err = 0;
292#if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
293 if (gethostbyname_r(hostname, h, (char*)buffer, size, &he, err))
294 he = NULL;
295#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
296 he = gethostbyname_r(hostname, h, (char*)buffer, size, err);
297#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
298 if (gethostbyname_r(hostname, h, (struct hostent_data*) buffer))
299 {
300 he = NULL;
301 *err = h_errno;
302 }
303 else
304 he = h;
305#elif defined(HAVE_GETHOSTBYNAME)
306#if wxUSE_THREADS
71b4a9b8
SN
307 wxMutexLocker locker(nameLock);
308#endif
309 he = gethostbyname(hostname);
310 if (!he)
311 *err = h_errno;
312 else
313 he = deepCopyHostent(h, he, (char*)buffer, size, err);
314#endif
315 return he;
316}
317
2887cb4e
SN
318#if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
319static wxMutex addrLock;
320#endif
71b4a9b8
SN
321struct hostent * wxGethostbyaddr_r(const char *addr_buf, int buf_size,
322 int proto, struct hostent *h,
323 void *buffer, int size, int *err)
324{
539ae551 325 struct hostent *he = NULL;
71b4a9b8
SN
326 *err = 0;
327#if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
328 if (gethostbyaddr_r(addr_buf, buf_size, proto, h,
329 (char*)buffer, size, &he, err))
330 he = NULL;
331#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
332 he = gethostbyaddr_r(addr_buf, buf_size, proto, h, (char*)buffer, size, err);
333#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
334 if (gethostbyaddr_r(addr_buf, buf_size, proto, h,
335 (struct hostent_data*) buffer))
336 {
337 he = NULL;
338 *err = h_errno;
339 }
340 else
341 he = h;
342#elif defined(HAVE_GETHOSTBYNAME)
343#if wxUSE_THREADS
71b4a9b8
SN
344 wxMutexLocker locker(addrLock);
345#endif
346 he = gethostbyaddr(addr_buf, buf_size, proto);
347 if (!he)
348 *err = h_errno;
349 else
350 he = deepCopyHostent(h, he, (char*)buffer, size, err);
351#endif
352 return he;
353}
354
f0b805fa 355#if defined(HAVE_GETSERVBYNAME)
71b4a9b8
SN
356static struct servent * deepCopyServent(struct servent *s,
357 const struct servent *se,
358 char *buffer, int size)
359{
2887cb4e 360 /* copy plain old structure */
71b4a9b8 361 memcpy(s, se, sizeof(struct servent));
2887cb4e
SN
362
363 /* copy name */
71b4a9b8 364 int len = strlen(s->s_name);
2887cb4e
SN
365 if (len >= size)
366 {
367 return NULL;
368 }
71b4a9b8
SN
369 memcpy(buffer, s->s_name, len);
370 buffer[len] = '\0';
371 s->s_name = buffer;
2887cb4e
SN
372
373 /* track position in the buffer */
374 int pos = len + 1;
375
376 /* copy protocol */
71b4a9b8 377 len = strlen(s->s_proto);
2887cb4e
SN
378 if (pos + len >= size)
379 {
380 return NULL;
71b4a9b8 381 }
2887cb4e
SN
382 memcpy(buffer + pos, s->s_proto, len);
383 buffer[pos + len] = '\0';
384 s->s_proto = buffer + pos;
385
386 /* track position in the buffer */
387 pos += len + 1;
388
389 /* ensure pointer alignment */
390 unsigned int misalign = sizeof(char *) - pos%sizeof(char *);
391 if(misalign < sizeof(char *))
392 pos += misalign;
01ba4b67 393
2887cb4e
SN
394 /* leave space for pointer list */
395 char **p = s->s_aliases, **q;
396 char **s_aliases = (char **)(buffer + pos);
397 while(*(p++) != 0)
398 pos += sizeof(char *);
01ba4b67 399
2887cb4e
SN
400 /* copy addresses and fill new pointer list */
401 for (p = s->s_aliases, q = s_aliases; *p != 0; p++, q++){
402 len = strlen(*p);
403 if (size <= pos + len)
404 {
405 return NULL;
406 }
407 memcpy(buffer + pos, *p, len); /* copy content */
408 buffer[pos + len] = '\0';
409 *q = buffer + pos; /* set copied pointer to copied content */
410 pos += len + 1;
411 }
412 *++q = 0; /* null terminate the pointer list */
413 s->s_aliases = s_aliases; /* copy pointer to pointers */
71b4a9b8
SN
414 return s;
415}
416#endif
417
2887cb4e
SN
418#if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
419static wxMutex servLock;
420#endif
71b4a9b8
SN
421struct servent *wxGetservbyname_r(const char *port, const char *protocol,
422 struct servent *serv, void *buffer, int size)
423{
539ae551 424 struct servent *se = NULL;
71b4a9b8
SN
425#if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
426 if (getservbyname_r(port, protocol, serv, (char*)buffer, size, &se))
427 se = NULL;
428#elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
429 se = getservbyname_r(port, protocol, serv, (char*)buffer, size);
430#elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
431 if (getservbyname_r(port, protocol, serv, (struct servent_data*) buffer))
432 se = NULL;
433 else
434 se = serv;
435#elif defined(HAVE_GETSERVBYNAME)
436#if wxUSE_THREADS
71b4a9b8
SN
437 wxMutexLocker locker(servLock);
438#endif
439 se = getservbyname(port, protocol);
440 if (se)
441 se = deepCopyServent(serv, se, (char*)buffer, size);
442#endif
443 return se;
444}
445
97e6ee04
DE
446/* debugging helpers */
447#ifdef __GSOCKET_DEBUG__
448# define GSocket_Debug(args) printf args
449#else
450# define GSocket_Debug(args)
451#endif /* __GSOCKET_DEBUG__ */
452
8575ff50
VZ
453#if wxUSE_IPV6
454typedef struct sockaddr_storage wxSockAddr;
455#else
456typedef struct sockaddr wxSockAddr;
457#endif
458
ba2a81d7
DE
459/* Table of GUI-related functions. We must call them indirectly because
460 * of wxBase and GUI separation: */
444cb1fd 461
2804f77d 462bool GSocket_Init()
985acf87 463{
2804f77d
VZ
464 GSocketManager * const manager = GSocketManager::Get();
465 return manager && manager->OnInit();
97e6ee04
DE
466}
467
2804f77d 468void GSocket_Cleanup()
97e6ee04 469{
2804f77d
VZ
470 GSocketManager * const manager = GSocketManager::Get();
471 if ( manager )
472 manager->OnExit();
97e6ee04
DE
473}
474
ba2a81d7
DE
475/* Constructors / Destructors for GSocket */
476
477GSocket::GSocket()
97e6ee04 478{
09e6e5ec 479 int i;
97e6ee04 480
09e6e5ec 481 m_fd = INVALID_SOCKET;
5e1eac14
VZ
482 m_handler = NULL;
483
97e6ee04
DE
484 for (i=0;i<GSOCK_MAX_EVENT;i++)
485 {
09e6e5ec 486 m_cbacks[i] = NULL;
97e6ee04 487 }
09e6e5ec
DE
488 m_detected = 0;
489 m_local = NULL;
490 m_peer = NULL;
491 m_error = GSOCK_NOERROR;
948c96ef
DE
492 m_server = false;
493 m_stream = true;
09e6e5ec 494 m_gui_dependent = NULL;
948c96ef 495 m_non_blocking = false;
1eef64d8 496 m_reusable = false;
60edcf45
VZ
497 m_broadcast = false;
498 m_dobind = true;
09e6e5ec 499 m_timeout = 10*60*1000;
97e6ee04 500 /* 10 minutes * 60 sec * 1000 millisec */
948c96ef 501 m_establishing = false;
2804f77d 502 m_use_events = false;
8c029a5b
VZ
503 m_initialRecvBufferSize = -1;
504 m_initialSendBufferSize = -1;
97e6ee04 505
2804f77d 506 m_ok = GSocketManager::Get()->Init_Socket(this);
97e6ee04
DE
507}
508
ba2a81d7 509void GSocket::Close()
97e6ee04 510{
2804f77d
VZ
511 if (m_use_events)
512 DisableEvents();
dd6c8be6
DE
513
514 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
515 will close the socket during Disable_Events. However, it will only do this
516 if it is being used. That is, it won't do it in a console program. To
517 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
518 if it has closed the socket which indicates to us (at runtime, instead of
519 at compile time as this had been before) that the socket has already
520 been closed.
521 */
522 if(m_fd != INVALID_SOCKET)
523 close(m_fd);
09e6e5ec 524 m_fd = INVALID_SOCKET;
97e6ee04
DE
525}
526
ba2a81d7 527GSocket::~GSocket()
97e6ee04 528{
ba2a81d7
DE
529 assert(this);
530
531 /* Check that the socket is really shutdowned */
532 if (m_fd != INVALID_SOCKET)
533 Shutdown();
534
2804f77d 535 GSocketManager::Get()->Destroy_Socket(this);
ba2a81d7 536
5e1eac14
VZ
537 delete m_handler;
538
97e6ee04 539 /* Destroy private addresses */
09e6e5ec
DE
540 if (m_local)
541 GAddress_destroy(m_local);
97e6ee04 542
09e6e5ec
DE
543 if (m_peer)
544 GAddress_destroy(m_peer);
2804f77d 545
97e6ee04
DE
546}
547
548/* GSocket_Shutdown:
549 * Disallow further read/write operations on this socket, close
550 * the fd and disable all callbacks.
551 */
ba2a81d7 552void GSocket::Shutdown()
97e6ee04
DE
553{
554 int evt;
555
09e6e5ec 556 assert(this);
97e6ee04 557
c3b501e1 558 /* Don't allow events to fire after socket has been closed */
2804f77d
VZ
559 if (m_use_events)
560 DisableEvents();
c3b501e1 561
97e6ee04 562 /* If socket has been created, shutdown it */
09e6e5ec 563 if (m_fd != INVALID_SOCKET)
97e6ee04 564 {
cd632a86 565 shutdown(m_fd, 1);
09e6e5ec 566 Close();
97e6ee04
DE
567 }
568
569 /* Disable GUI callbacks */
570 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
09e6e5ec 571 m_cbacks[evt] = NULL;
97e6ee04 572
09e6e5ec 573 m_detected = GSOCK_LOST_FLAG;
97e6ee04
DE
574}
575
576/* Address handling */
577
578/* GSocket_SetLocal:
579 * GSocket_GetLocal:
580 * GSocket_SetPeer:
581 * GSocket_GetPeer:
582 * Set or get the local or peer address for this socket. The 'set'
583 * functions return GSOCK_NOERROR on success, an error code otherwise.
584 * The 'get' functions return a pointer to a GAddress object on success,
585 * or NULL otherwise, in which case they set the error code of the
586 * corresponding GSocket.
587 *
588 * Error codes:
589 * GSOCK_INVSOCK - the socket is not valid.
590 * GSOCK_INVADDR - the address is not valid.
591 */
ba2a81d7 592GSocketError GSocket::SetLocal(GAddress *address)
97e6ee04 593{
09e6e5ec 594 assert(this);
97e6ee04
DE
595
596 /* the socket must be initialized, or it must be a server */
09e6e5ec 597 if ((m_fd != INVALID_SOCKET && !m_server))
97e6ee04 598 {
09e6e5ec 599 m_error = GSOCK_INVSOCK;
97e6ee04
DE
600 return GSOCK_INVSOCK;
601 }
602
603 /* check address */
604 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
605 {
09e6e5ec 606 m_error = GSOCK_INVADDR;
97e6ee04
DE
607 return GSOCK_INVADDR;
608 }
609
09e6e5ec
DE
610 if (m_local)
611 GAddress_destroy(m_local);
97e6ee04 612
09e6e5ec 613 m_local = GAddress_copy(address);
97e6ee04
DE
614
615 return GSOCK_NOERROR;
616}
617
ba2a81d7 618GSocketError GSocket::SetPeer(GAddress *address)
97e6ee04 619{
09e6e5ec 620 assert(this);
97e6ee04
DE
621
622 /* check address */
623 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
624 {
09e6e5ec 625 m_error = GSOCK_INVADDR;
97e6ee04
DE
626 return GSOCK_INVADDR;
627 }
628
09e6e5ec
DE
629 if (m_peer)
630 GAddress_destroy(m_peer);
97e6ee04 631
09e6e5ec 632 m_peer = GAddress_copy(address);
97e6ee04
DE
633
634 return GSOCK_NOERROR;
635}
636
ba2a81d7 637GAddress *GSocket::GetLocal()
97e6ee04
DE
638{
639 GAddress *address;
8575ff50 640 wxSockAddr addr;
9e03e02d 641 WX_SOCKLEN_T size = sizeof(addr);
97e6ee04
DE
642 GSocketError err;
643
09e6e5ec 644 assert(this);
97e6ee04
DE
645
646 /* try to get it from the m_local var first */
09e6e5ec
DE
647 if (m_local)
648 return GAddress_copy(m_local);
97e6ee04
DE
649
650 /* else, if the socket is initialized, try getsockname */
09e6e5ec 651 if (m_fd == INVALID_SOCKET)
97e6ee04 652 {
09e6e5ec 653 m_error = GSOCK_INVSOCK;
97e6ee04
DE
654 return NULL;
655 }
656
8575ff50 657 if (getsockname(m_fd, (sockaddr*)&addr, (WX_SOCKLEN_T *) &size) < 0)
97e6ee04 658 {
09e6e5ec 659 m_error = GSOCK_IOERR;
97e6ee04
DE
660 return NULL;
661 }
662
663 /* got a valid address from getsockname, create a GAddress object */
664 address = GAddress_new();
665 if (address == NULL)
666 {
09e6e5ec 667 m_error = GSOCK_MEMERR;
97e6ee04
DE
668 return NULL;
669 }
670
8575ff50 671 err = _GAddress_translate_from(address, (sockaddr*)&addr, size);
97e6ee04
DE
672 if (err != GSOCK_NOERROR)
673 {
674 GAddress_destroy(address);
09e6e5ec 675 m_error = err;
97e6ee04
DE
676 return NULL;
677 }
678
679 return address;
680}
681
ba2a81d7 682GAddress *GSocket::GetPeer()
97e6ee04 683{
09e6e5ec 684 assert(this);
97e6ee04
DE
685
686 /* try to get it from the m_peer var */
09e6e5ec
DE
687 if (m_peer)
688 return GAddress_copy(m_peer);
97e6ee04
DE
689
690 return NULL;
691}
692
693/* Server specific parts */
694
695/* GSocket_SetServer:
696 * Sets up this socket as a server. The local address must have been
697 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
698 * Returns GSOCK_NOERROR on success, one of the following otherwise:
b082b524 699 *
97e6ee04
DE
700 * Error codes:
701 * GSOCK_INVSOCK - the socket is in use.
702 * GSOCK_INVADDR - the local address has not been set.
b082b524 703 * GSOCK_IOERR - low-level error.
97e6ee04 704 */
ba2a81d7 705GSocketError GSocket::SetServer()
97e6ee04
DE
706{
707 int arg = 1;
708
09e6e5ec 709 assert(this);
97e6ee04
DE
710
711 /* must not be in use */
09e6e5ec 712 if (m_fd != INVALID_SOCKET)
97e6ee04 713 {
09e6e5ec 714 m_error = GSOCK_INVSOCK;
97e6ee04
DE
715 return GSOCK_INVSOCK;
716 }
717
718 /* the local addr must have been set */
09e6e5ec 719 if (!m_local)
97e6ee04 720 {
09e6e5ec 721 m_error = GSOCK_INVADDR;
97e6ee04
DE
722 return GSOCK_INVADDR;
723 }
724
725 /* Initialize all fields */
948c96ef
DE
726 m_stream = true;
727 m_server = true;
97e6ee04
DE
728
729 /* Create the socket */
09e6e5ec 730 m_fd = socket(m_local->m_realfamily, SOCK_STREAM, 0);
97e6ee04 731
09e6e5ec 732 if (m_fd == INVALID_SOCKET)
97e6ee04 733 {
09e6e5ec 734 m_error = GSOCK_IOERR;
97e6ee04
DE
735 return GSOCK_IOERR;
736 }
bb154f79
KH
737
738 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
739#ifdef SO_NOSIGPIPE
01ba4b67 740 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
bb154f79
KH
741#endif
742
09e6e5ec 743 ioctl(m_fd, FIONBIO, &arg);
2804f77d
VZ
744 if (m_use_events)
745 EnableEvents();
97e6ee04
DE
746
747 /* allow a socket to re-bind if the socket is in the TIME_WAIT
748 state after being previously closed.
749 */
ba2a81d7 750 if (m_reusable)
c232b3cd 751 {
01ba4b67 752 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
c232b3cd 753#ifdef SO_REUSEPORT
01ba4b67 754 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
c232b3cd
KH
755#endif
756 }
97e6ee04
DE
757
758 /* Bind to the local address,
759 * retrieve the actual address bound,
760 * and listen up to 5 connections.
761 */
09e6e5ec
DE
762 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
763 (getsockname(m_fd,
764 m_local->m_addr,
9e03e02d 765 (WX_SOCKLEN_T *) &m_local->m_len) != 0) ||
09e6e5ec 766 (listen(m_fd, 5) != 0))
97e6ee04 767 {
09e6e5ec
DE
768 Close();
769 m_error = GSOCK_IOERR;
97e6ee04
DE
770 return GSOCK_IOERR;
771 }
772
773 return GSOCK_NOERROR;
774}
775
776/* GSocket_WaitConnection:
777 * Waits for an incoming client connection. Returns a pointer to
778 * a GSocket object, or NULL if there was an error, in which case
779 * the last error field will be updated for the calling GSocket.
780 *
781 * Error codes (set in the calling GSocket)
782 * GSOCK_INVSOCK - the socket is not valid or not a server.
783 * GSOCK_TIMEDOUT - timeout, no incoming connections.
784 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
785 * GSOCK_MEMERR - couldn't allocate memory.
b082b524 786 * GSOCK_IOERR - low-level error.
97e6ee04 787 */
ba2a81d7 788GSocket *GSocket::WaitConnection()
97e6ee04 789{
8575ff50 790 wxSockAddr from;
9e03e02d 791 WX_SOCKLEN_T fromlen = sizeof(from);
97e6ee04
DE
792 GSocket *connection;
793 GSocketError err;
794 int arg = 1;
795
09e6e5ec 796 assert(this);
97e6ee04 797
97e6ee04 798 /* If the socket has already been created, we exit immediately */
09e6e5ec 799 if (m_fd == INVALID_SOCKET || !m_server)
97e6ee04 800 {
09e6e5ec 801 m_error = GSOCK_INVSOCK;
97e6ee04
DE
802 return NULL;
803 }
804
805 /* Create a GSocket object for the new connection */
444cb1fd 806 connection = GSocket_new();
97e6ee04 807
444cb1fd 808 if (!connection)
97e6ee04 809 {
09e6e5ec 810 m_error = GSOCK_MEMERR;
97e6ee04
DE
811 return NULL;
812 }
813
814 /* Wait for a connection (with timeout) */
09e6e5ec 815 if (Input_Timeout() == GSOCK_TIMEDOUT)
97e6ee04 816 {
85431efa 817 delete connection;
09e6e5ec 818 /* m_error set by _GSocket_Input_Timeout */
97e6ee04
DE
819 return NULL;
820 }
821
8575ff50 822 connection->m_fd = accept(m_fd, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
97e6ee04 823
bb154f79
KH
824 /* Reenable CONNECTION events */
825 Enable(GSOCK_CONNECTION);
bb154f79 826
97e6ee04
DE
827 if (connection->m_fd == INVALID_SOCKET)
828 {
829 if (errno == EWOULDBLOCK)
09e6e5ec 830 m_error = GSOCK_WOULDBLOCK;
97e6ee04 831 else
09e6e5ec 832 m_error = GSOCK_IOERR;
97e6ee04 833
85431efa 834 delete connection;
97e6ee04
DE
835 return NULL;
836 }
837
838 /* Initialize all fields */
948c96ef
DE
839 connection->m_server = false;
840 connection->m_stream = true;
97e6ee04
DE
841
842 /* Setup the peer address field */
843 connection->m_peer = GAddress_new();
844 if (!connection->m_peer)
845 {
85431efa 846 delete connection;
09e6e5ec 847 m_error = GSOCK_MEMERR;
97e6ee04
DE
848 return NULL;
849 }
1aa7b427 850
8575ff50 851 err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
97e6ee04
DE
852 if (err != GSOCK_NOERROR)
853 {
85431efa 854 delete connection;
09e6e5ec 855 m_error = err;
97e6ee04
DE
856 return NULL;
857 }
1aa7b427 858
97e6ee04
DE
859#if defined(__EMX__) || defined(__VISAGECPP__)
860 ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
861#else
862 ioctl(connection->m_fd, FIONBIO, &arg);
863#endif
2804f77d
VZ
864 if (m_use_events)
865 connection->Notify(true);
97e6ee04
DE
866
867 return connection;
868}
869
2804f77d
VZ
870void GSocket::Notify(bool flag)
871{
872 if (flag == m_use_events)
873 return;
2804f77d
VZ
874 m_use_events = flag;
875 EnableEvents(flag);
876}
877
878void GSocket::EnableEvents(bool flag)
879{
880 if (flag)
881 GSocketManager::Get()->Enable_Events(this);
882 else
883 GSocketManager::Get()->Disable_Events(this);
884}
885
948c96ef 886bool GSocket::SetReusable()
b082b524
DE
887{
888 /* socket must not be null, and must not be in use/already bound */
1aa7b427
DS
889 if (this && m_fd == INVALID_SOCKET)
890 {
948c96ef 891 m_reusable = true;
1aa7b427 892
948c96ef 893 return true;
b082b524 894 }
1aa7b427 895
948c96ef 896 return false;
b082b524
DE
897}
898
60edcf45
VZ
899bool GSocket::SetBroadcast()
900{
901 /* socket must not be in use/already bound */
902 if (m_fd == INVALID_SOCKET) {
903 m_broadcast = true;
904 return true;
905 }
906 return false;
907}
908
909bool GSocket::DontDoBind()
910{
911 /* socket must not be in use/already bound */
912 if (m_fd == INVALID_SOCKET) {
913 m_dobind = false;
914 return true;
915 }
916 return false;
917}
918
97e6ee04
DE
919/* Client specific parts */
920
921/* GSocket_Connect:
922 * For stream (connection oriented) sockets, GSocket_Connect() tries
923 * to establish a client connection to a server using the peer address
924 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
d6922577 925 * connection has been successfully established, or one of the error
97e6ee04
DE
926 * codes listed below. Note that for nonblocking sockets, a return
927 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
928 * request can be completed later; you should use GSocket_Select()
929 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
930 * corresponding asynchronous events.
931 *
932 * For datagram (non connection oriented) sockets, GSocket_Connect()
933 * just sets the peer address established with GSocket_SetPeer() as
934 * default destination.
935 *
936 * Error codes:
937 * GSOCK_INVSOCK - the socket is in use or not valid.
938 * GSOCK_INVADDR - the peer address has not been established.
939 * GSOCK_TIMEDOUT - timeout, the connection failed.
940 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
941 * GSOCK_MEMERR - couldn't allocate memory.
b082b524 942 * GSOCK_IOERR - low-level error.
97e6ee04 943 */
ba2a81d7 944GSocketError GSocket::Connect(GSocketStream stream)
97e6ee04
DE
945{
946 int err, ret;
947 int arg = 1;
948
09e6e5ec 949 assert(this);
97e6ee04
DE
950
951 /* Enable CONNECTION events (needed for nonblocking connections) */
09e6e5ec 952 Enable(GSOCK_CONNECTION);
97e6ee04 953
09e6e5ec 954 if (m_fd != INVALID_SOCKET)
97e6ee04 955 {
09e6e5ec 956 m_error = GSOCK_INVSOCK;
97e6ee04
DE
957 return GSOCK_INVSOCK;
958 }
959
09e6e5ec 960 if (!m_peer)
97e6ee04 961 {
09e6e5ec 962 m_error = GSOCK_INVADDR;
97e6ee04
DE
963 return GSOCK_INVADDR;
964 }
965
966 /* Streamed or dgram socket? */
09e6e5ec 967 m_stream = (stream == GSOCK_STREAMED);
948c96ef
DE
968 m_server = false;
969 m_establishing = false;
97e6ee04
DE
970
971 /* Create the socket */
09e6e5ec
DE
972 m_fd = socket(m_peer->m_realfamily,
973 m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
97e6ee04 974
09e6e5ec 975 if (m_fd == INVALID_SOCKET)
97e6ee04 976 {
09e6e5ec 977 m_error = GSOCK_IOERR;
97e6ee04
DE
978 return GSOCK_IOERR;
979 }
bb154f79
KH
980
981 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
982#ifdef SO_NOSIGPIPE
01ba4b67 983 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
bb154f79
KH
984#endif
985
97e6ee04 986#if defined(__EMX__) || defined(__VISAGECPP__)
09e6e5ec 987 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
97e6ee04 988#else
09e6e5ec 989 ioctl(m_fd, FIONBIO, &arg);
97e6ee04 990#endif
97e6ee04 991
c232b3cd
KH
992 // If the reuse flag is set, use the applicable socket reuse flags(s)
993 if (m_reusable)
994 {
01ba4b67 995 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
c232b3cd 996#ifdef SO_REUSEPORT
01ba4b67 997 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
c232b3cd
KH
998#endif
999 }
1000
8c029a5b
VZ
1001 if (m_initialRecvBufferSize >= 0)
1002 setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&m_initialRecvBufferSize, sizeof(m_initialRecvBufferSize));
1003 if (m_initialSendBufferSize >= 0)
1004 setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&m_initialSendBufferSize, sizeof(m_initialSendBufferSize));
1005
c232b3cd
KH
1006 // If a local address has been set, then we need to bind to it before calling connect
1007 if (m_local && m_local->m_addr)
1008 {
1009 bind(m_fd, m_local->m_addr, m_local->m_len);
1010 }
1011
97e6ee04 1012 /* Connect it to the peer address, with a timeout (see below) */
09e6e5ec 1013 ret = connect(m_fd, m_peer->m_addr, m_peer->m_len);
97e6ee04 1014
0d34c30e
KH
1015 /* We only call Enable_Events if we know we aren't shutting down the socket.
1016 * NB: Enable_Events needs to be called whether the socket is blocking or
1017 * non-blocking, it just shouldn't be called prior to knowing there is a
1018 * connection _if_ blocking sockets are being used.
1019 * If connect above returns 0, we are already connected and need to make the
17a1ebd1 1020 * call to Enable_Events now.
a3687636 1021 */
17a1ebd1 1022
2804f77d
VZ
1023 if (m_use_events && (m_non_blocking || ret == 0))
1024 EnableEvents();
bb154f79 1025
97e6ee04
DE
1026 if (ret == -1)
1027 {
1028 err = errno;
1029
1030 /* If connect failed with EINPROGRESS and the GSocket object
1031 * is in blocking mode, we select() for the specified timeout
1032 * checking for writability to see if the connection request
1033 * completes.
1034 */
09e6e5ec 1035 if ((err == EINPROGRESS) && (!m_non_blocking))
97e6ee04 1036 {
09e6e5ec 1037 if (Output_Timeout() == GSOCK_TIMEDOUT)
97e6ee04 1038 {
09e6e5ec
DE
1039 Close();
1040 /* m_error is set in _GSocket_Output_Timeout */
97e6ee04
DE
1041 return GSOCK_TIMEDOUT;
1042 }
1043 else
1044 {
1045 int error;
ddc1a35f 1046 SOCKOPTLEN_T len = sizeof(error);
97e6ee04 1047
f71bb8ef 1048 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
2804f77d
VZ
1049 if (m_use_events)
1050 EnableEvents();
bb154f79 1051
97e6ee04
DE
1052 if (!error)
1053 return GSOCK_NOERROR;
1054 }
1055 }
1056
1057 /* If connect failed with EINPROGRESS and the GSocket object
1058 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1059 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1060 * this way if the connection completes, a GSOCK_CONNECTION
1061 * event will be generated, if enabled.
1062 */
09e6e5ec 1063 if ((err == EINPROGRESS) && (m_non_blocking))
97e6ee04 1064 {
948c96ef 1065 m_establishing = true;
09e6e5ec 1066 m_error = GSOCK_WOULDBLOCK;
97e6ee04
DE
1067 return GSOCK_WOULDBLOCK;
1068 }
1069
1070 /* If connect failed with an error other than EINPROGRESS,
1071 * then the call to GSocket_Connect has failed.
1072 */
09e6e5ec
DE
1073 Close();
1074 m_error = GSOCK_IOERR;
1aa7b427 1075
97e6ee04
DE
1076 return GSOCK_IOERR;
1077 }
1078
1079 return GSOCK_NOERROR;
1080}
1081
1082/* Datagram sockets */
1083
1084/* GSocket_SetNonOriented:
1085 * Sets up this socket as a non-connection oriented (datagram) socket.
1086 * Before using this function, the local address must have been set
1087 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1088 * on success, or one of the following otherwise.
1089 *
1090 * Error codes:
1091 * GSOCK_INVSOCK - the socket is in use.
1092 * GSOCK_INVADDR - the local address has not been set.
1093 * GSOCK_IOERR - low-level error.
1094 */
ba2a81d7 1095GSocketError GSocket::SetNonOriented()
97e6ee04
DE
1096{
1097 int arg = 1;
1098
09e6e5ec 1099 assert(this);
97e6ee04 1100
09e6e5ec 1101 if (m_fd != INVALID_SOCKET)
97e6ee04 1102 {
09e6e5ec 1103 m_error = GSOCK_INVSOCK;
97e6ee04
DE
1104 return GSOCK_INVSOCK;
1105 }
1106
09e6e5ec 1107 if (!m_local)
97e6ee04 1108 {
09e6e5ec 1109 m_error = GSOCK_INVADDR;
97e6ee04
DE
1110 return GSOCK_INVADDR;
1111 }
1112
1113 /* Initialize all fields */
948c96ef
DE
1114 m_stream = false;
1115 m_server = false;
97e6ee04
DE
1116
1117 /* Create the socket */
09e6e5ec 1118 m_fd = socket(m_local->m_realfamily, SOCK_DGRAM, 0);
97e6ee04 1119
09e6e5ec 1120 if (m_fd == INVALID_SOCKET)
97e6ee04 1121 {
09e6e5ec 1122 m_error = GSOCK_IOERR;
97e6ee04
DE
1123 return GSOCK_IOERR;
1124 }
1125#if defined(__EMX__) || defined(__VISAGECPP__)
09e6e5ec 1126 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
97e6ee04 1127#else
09e6e5ec 1128 ioctl(m_fd, FIONBIO, &arg);
97e6ee04 1129#endif
2804f77d
VZ
1130 if (m_use_events)
1131 EnableEvents();
97e6ee04 1132
01ba4b67
VZ
1133 if (m_reusable)
1134 {
1135 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
1136#ifdef SO_REUSEPORT
1137 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
1138#endif
1139 }
1140
60edcf45 1141 if (m_broadcast)
97e6ee04 1142 {
60edcf45
VZ
1143 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST, (const char*)&arg, sizeof(arg));
1144 }
1145 if (m_dobind)
1146 {
1147 /* Bind to the local address,
1148 * and retrieve the actual address bound.
1149 */
1150 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
1151 (getsockname(m_fd,
1152 m_local->m_addr,
1153 (WX_SOCKLEN_T *) &m_local->m_len) != 0))
1154 {
1155 Close();
1156 m_error = GSOCK_IOERR;
1157 return GSOCK_IOERR;
1158 }
97e6ee04 1159 }
97e6ee04
DE
1160 return GSOCK_NOERROR;
1161}
1162
1163/* Generic IO */
1164
1165/* Like recv(), send(), ... */
ba2a81d7 1166int GSocket::Read(char *buffer, int size)
97e6ee04
DE
1167{
1168 int ret;
1169
09e6e5ec 1170 assert(this);
97e6ee04 1171
09e6e5ec 1172 if (m_fd == INVALID_SOCKET || m_server)
97e6ee04 1173 {
09e6e5ec 1174 m_error = GSOCK_INVSOCK;
97e6ee04
DE
1175 return -1;
1176 }
1177
9d715960
DE
1178 /* Disable events during query of socket status */
1179 Disable(GSOCK_INPUT);
b082b524 1180
97e6ee04 1181 /* If the socket is blocking, wait for data (with a timeout) */
976abb72
VZ
1182 if (Input_Timeout() == GSOCK_TIMEDOUT) {
1183 m_error = GSOCK_TIMEDOUT;
1184 /* Don't return here immediately, otherwise socket events would not be
1185 * re-enabled! */
9d715960 1186 ret = -1;
976abb72 1187 }
1aa7b427
DS
1188 else
1189 {
9d715960
DE
1190 /* Read the data */
1191 if (m_stream)
1192 ret = Recv_Stream(buffer, size);
1193 else
1194 ret = Recv_Dgram(buffer, size);
b082b524 1195
01c03554
VZ
1196 /*
1197 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1198 * socket and empty datagrams are possible), then the connection has been
1199 * gracefully closed.
1200 *
1201 * Otherwise, recv has returned an error (-1), in which case we have lost
1202 * the socket only if errno does _not_ indicate that there may be more data
1203 * to read.
9b67181b 1204 */
01c03554 1205 if ((ret == 0) && m_stream)
98e7a7f9 1206 {
f4854380 1207 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
2804f77d
VZ
1208 if (m_use_events)
1209 {
1210 m_detected = GSOCK_LOST_FLAG;
1211 Detected_Read();
1212 return 0;
1213 }
98e7a7f9 1214 }
1aa7b427
DS
1215 else if (ret == -1)
1216 {
976abb72
VZ
1217 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
1218 m_error = GSOCK_WOULDBLOCK;
1219 else
1220 m_error = GSOCK_IOERR;
1221 }
97e6ee04 1222 }
b082b524 1223
9d715960 1224 /* Enable events again now that we are done processing */
09e6e5ec 1225 Enable(GSOCK_INPUT);
97e6ee04
DE
1226
1227 return ret;
1228}
1229
ba2a81d7 1230int GSocket::Write(const char *buffer, int size)
b082b524 1231{
97e6ee04
DE
1232 int ret;
1233
09e6e5ec 1234 assert(this);
b082b524 1235
97e6ee04
DE
1236 GSocket_Debug(( "GSocket_Write #1, size %d\n", size ));
1237
09e6e5ec 1238 if (m_fd == INVALID_SOCKET || m_server)
97e6ee04 1239 {
09e6e5ec 1240 m_error = GSOCK_INVSOCK;
97e6ee04
DE
1241 return -1;
1242 }
1243
1244 GSocket_Debug(( "GSocket_Write #2, size %d\n", size ));
1245
1246 /* If the socket is blocking, wait for writability (with a timeout) */
09e6e5ec 1247 if (Output_Timeout() == GSOCK_TIMEDOUT)
97e6ee04
DE
1248 return -1;
1249
1250 GSocket_Debug(( "GSocket_Write #3, size %d\n", size ));
1251
1252 /* Write the data */
09e6e5ec
DE
1253 if (m_stream)
1254 ret = Send_Stream(buffer, size);
97e6ee04 1255 else
09e6e5ec 1256 ret = Send_Dgram(buffer, size);
b082b524 1257
97e6ee04
DE
1258 GSocket_Debug(( "GSocket_Write #4, size %d\n", size ));
1259
1260 if (ret == -1)
1261 {
7e1e6965 1262 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
97e6ee04 1263 {
09e6e5ec 1264 m_error = GSOCK_WOULDBLOCK;
97e6ee04
DE
1265 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1266 }
1267 else
1268 {
09e6e5ec 1269 m_error = GSOCK_IOERR;
97e6ee04
DE
1270 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1271 }
1272
1273 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1274 * in MSW). Once the first OUTPUT event is received, users can assume
1275 * that the socket is writable until a read operation fails. Only then
1276 * will further OUTPUT events be posted.
1277 */
09e6e5ec 1278 Enable(GSOCK_OUTPUT);
1aa7b427 1279
97e6ee04
DE
1280 return -1;
1281 }
b082b524 1282
97e6ee04
DE
1283 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret ));
1284
1285 return ret;
1286}
1287
1288/* GSocket_Select:
1289 * Polls the socket to determine its status. This function will
1290 * check for the events specified in the 'flags' parameter, and
1291 * it will return a mask indicating which operations can be
1292 * performed. This function won't block, regardless of the
1293 * mode (blocking | nonblocking) of the socket.
1294 */
ba2a81d7 1295GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
97e6ee04 1296{
2804f77d 1297 assert(this);
97e6ee04 1298
cf86dc50
VZ
1299 GSocketEventFlags result = 0;
1300 fd_set readfds;
1301 fd_set writefds;
1302 fd_set exceptfds;
1303 struct timeval tv;
1304
1305 if (m_fd == -1)
1306 return (GSOCK_LOST_FLAG & flags);
1307
1308 /* Do not use a static struct, Linux can garble it */
1309 tv.tv_sec = 0;
1310 tv.tv_usec = 0;
1311
1312 wxFD_ZERO(&readfds);
1313 wxFD_ZERO(&writefds);
1314 wxFD_ZERO(&exceptfds);
1315 wxFD_SET(m_fd, &readfds);
1316 if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
1317 wxFD_SET(m_fd, &writefds);
1318 wxFD_SET(m_fd, &exceptfds);
1319
1320 /* Check 'sticky' CONNECTION flag first */
1321 result |= GSOCK_CONNECTION_FLAG & m_detected;
1322
1323 /* If we have already detected a LOST event, then don't try
1324 * to do any further processing.
1325 */
1326 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1327 {
1328 m_establishing = false;
1329 return (GSOCK_LOST_FLAG & flags);
1330 }
1331
1332 /* Try select now */
1333 if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0)
1334 {
1335 /* What to do here? */
1336 return (result & flags);
1337 }
1338
1339 /* Check for exceptions and errors */
1340 if (wxFD_ISSET(m_fd, &exceptfds))
1341 {
1342 m_establishing = false;
1343 m_detected = GSOCK_LOST_FLAG;
1344
1345 /* LOST event: Abort any further processing */
1346 return (GSOCK_LOST_FLAG & flags);
1347 }
1348
1349 /* Check for readability */
1350 if (wxFD_ISSET(m_fd, &readfds))
1351 {
1352 result |= GSOCK_INPUT_FLAG;
1353
1354 if (m_server && m_stream)
1355 {
1356 /* This is a TCP server socket that detected a connection.
1357 While the INPUT_FLAG is also set, it doesn't matter on
1358 this kind of sockets, as we can only Accept() from them. */
1359 m_detected |= GSOCK_CONNECTION_FLAG;
1360 }
1361 }
1362
1363 /* Check for writability */
1364 if (wxFD_ISSET(m_fd, &writefds))
1365 {
1366 if (m_establishing && !m_server)
1367 {
1368 int error;
1369 SOCKOPTLEN_T len = sizeof(error);
1370 m_establishing = false;
1371 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1372
1373 if (error)
1374 {
1375 m_detected = GSOCK_LOST_FLAG;
1376
1377 /* LOST event: Abort any further processing */
1378 return (GSOCK_LOST_FLAG & flags);
1379 }
1380 else
1381 {
1382 m_detected |= GSOCK_CONNECTION_FLAG;
1383 }
1384 }
1385 else
1386 {
1387 result |= GSOCK_OUTPUT_FLAG;
1388 }
1389 }
1390
1391 return (result | m_detected) & flags;
97e6ee04
DE
1392}
1393
1394/* Flags */
1395
1396/* GSocket_SetNonBlocking:
1397 * Sets the socket to non-blocking mode. All IO calls will return
1398 * immediately.
1399 */
948c96ef 1400void GSocket::SetNonBlocking(bool non_block)
97e6ee04 1401{
09e6e5ec 1402 assert(this);
97e6ee04
DE
1403
1404 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
1405
09e6e5ec 1406 m_non_blocking = non_block;
97e6ee04
DE
1407}
1408
1409/* GSocket_SetTimeout:
1410 * Sets the timeout for blocking calls. Time is expressed in
1411 * milliseconds.
1412 */
ba2a81d7 1413void GSocket::SetTimeout(unsigned long millisec)
97e6ee04 1414{
09e6e5ec 1415 assert(this);
97e6ee04 1416
09e6e5ec 1417 m_timeout = millisec;
97e6ee04
DE
1418}
1419
1420/* GSocket_GetError:
d6922577 1421 * Returns the last error occurred for this socket. Note that successful
97e6ee04
DE
1422 * operations do not clear this back to GSOCK_NOERROR, so use it only
1423 * after an error.
1424 */
ba2a81d7 1425GSocketError WXDLLIMPEXP_NET GSocket::GetError()
97e6ee04 1426{
09e6e5ec 1427 assert(this);
97e6ee04 1428
09e6e5ec 1429 return m_error;
97e6ee04
DE
1430}
1431
1432/* Callbacks */
1433
1434/* GSOCK_INPUT:
1435 * There is data to be read in the input buffer. If, after a read
1436 * operation, there is still data available, the callback function will
1437 * be called again.
1438 * GSOCK_OUTPUT:
b082b524 1439 * The socket is available for writing. That is, the next write call
97e6ee04
DE
1440 * won't block. This event is generated only once, when the connection is
1441 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1442 * when the output buffer empties again. This means that the app should
1443 * assume that it can write since the first OUTPUT event, and no more
1444 * OUTPUT events will be generated unless an error occurs.
1445 * GSOCK_CONNECTION:
d6922577 1446 * Connection successfully established, for client sockets, or incoming
97e6ee04
DE
1447 * client connection, for server sockets. Wait for this event (also watch
1448 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1449 * GSOCK_LOST:
1450 * The connection is lost (or a connection request failed); this could
1451 * be due to a failure, or due to the peer closing it gracefully.
1452 */
1453
1454/* GSocket_SetCallback:
1455 * Enables the callbacks specified by 'flags'. Note that 'flags'
1456 * may be a combination of flags OR'ed toghether, so the same
1457 * callback function can be made to accept different events.
1458 * The callback function must have the following prototype:
1459 *
1460 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1461 */
ba2a81d7 1462void GSocket::SetCallback(GSocketEventFlags flags,
97e6ee04
DE
1463 GSocketCallback callback, char *cdata)
1464{
1465 int count;
1466
09e6e5ec 1467 assert(this);
97e6ee04
DE
1468
1469 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1470 {
1471 if ((flags & (1 << count)) != 0)
1472 {
09e6e5ec
DE
1473 m_cbacks[count] = callback;
1474 m_data[count] = cdata;
97e6ee04
DE
1475 }
1476 }
1477}
1478
1479/* GSocket_UnsetCallback:
1480 * Disables all callbacks specified by 'flags', which may be a
1481 * combination of flags OR'ed toghether.
1482 */
ba2a81d7 1483void GSocket::UnsetCallback(GSocketEventFlags flags)
97e6ee04
DE
1484{
1485 int count;
1486
09e6e5ec 1487 assert(this);
97e6ee04
DE
1488
1489 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1490 {
1491 if ((flags & (1 << count)) != 0)
1492 {
09e6e5ec
DE
1493 m_cbacks[count] = NULL;
1494 m_data[count] = NULL;
97e6ee04
DE
1495 }
1496 }
1497}
1498
ba2a81d7 1499GSocketError GSocket::GetSockOpt(int level, int optname,
b082b524
DE
1500 void *optval, int *optlen)
1501{
ddc1a35f 1502 if (getsockopt(m_fd, level, optname, (char*)optval, (SOCKOPTLEN_T*)optlen) == 0)
b082b524 1503 return GSOCK_NOERROR;
1aa7b427 1504
b082b524
DE
1505 return GSOCK_OPTERR;
1506}
1507
ba2a81d7 1508GSocketError GSocket::SetSockOpt(int level, int optname,
b082b524
DE
1509 const void *optval, int optlen)
1510{
f71bb8ef 1511 if (setsockopt(m_fd, level, optname, (const char*)optval, optlen) == 0)
b082b524 1512 return GSOCK_NOERROR;
1aa7b427 1513
b082b524
DE
1514 return GSOCK_OPTERR;
1515}
1516
ba2a81d7 1517#define CALL_CALLBACK(socket, event) { \
9a7e4a56 1518 socket->Disable(event); \
ba2a81d7
DE
1519 if (socket->m_cbacks[event]) \
1520 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
97e6ee04
DE
1521}
1522
1523
ba2a81d7 1524void GSocket::Enable(GSocketEvent event)
97e6ee04 1525{
2804f77d
VZ
1526 if (m_use_events)
1527 {
1528 m_detected &= ~(1 << event);
1529 GSocketManager::Get()->Install_Callback(this, event);
1530 }
97e6ee04
DE
1531}
1532
ba2a81d7 1533void GSocket::Disable(GSocketEvent event)
97e6ee04 1534{
2804f77d
VZ
1535 if (m_use_events)
1536 {
1537 m_detected |= (1 << event);
1538 GSocketManager::Get()->Uninstall_Callback(this, event);
1539 }
97e6ee04
DE
1540}
1541
1542/* _GSocket_Input_Timeout:
1543 * For blocking sockets, wait until data is available or
1544 * until timeout ellapses.
1545 */
ba2a81d7 1546GSocketError GSocket::Input_Timeout()
97e6ee04
DE
1547{
1548 struct timeval tv;
1549 fd_set readfds;
1550 int ret;
1551
1552 /* Linux select() will overwrite the struct on return */
09e6e5ec
DE
1553 tv.tv_sec = (m_timeout / 1000);
1554 tv.tv_usec = (m_timeout % 1000) * 1000;
97e6ee04 1555
09e6e5ec 1556 if (!m_non_blocking)
97e6ee04 1557 {
17a1ebd1
VZ
1558 wxFD_ZERO(&readfds);
1559 wxFD_SET(m_fd, &readfds);
09e6e5ec 1560 ret = select(m_fd + 1, &readfds, NULL, NULL, &tv);
97e6ee04
DE
1561 if (ret == 0)
1562 {
1563 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
09e6e5ec 1564 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1565 return GSOCK_TIMEDOUT;
1566 }
1aa7b427 1567
97e6ee04
DE
1568 if (ret == -1)
1569 {
1570 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1571 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1572 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1573 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1574 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
09e6e5ec 1575 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1576 return GSOCK_TIMEDOUT;
1577 }
1578 }
1aa7b427 1579
97e6ee04
DE
1580 return GSOCK_NOERROR;
1581}
1582
1583/* _GSocket_Output_Timeout:
1584 * For blocking sockets, wait until data can be sent without
1585 * blocking or until timeout ellapses.
1586 */
ba2a81d7 1587GSocketError GSocket::Output_Timeout()
97e6ee04
DE
1588{
1589 struct timeval tv;
1590 fd_set writefds;
1591 int ret;
1592
1593 /* Linux select() will overwrite the struct on return */
09e6e5ec
DE
1594 tv.tv_sec = (m_timeout / 1000);
1595 tv.tv_usec = (m_timeout % 1000) * 1000;
97e6ee04 1596
09e6e5ec 1597 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking) );
97e6ee04 1598
09e6e5ec 1599 if (!m_non_blocking)
97e6ee04 1600 {
17a1ebd1
VZ
1601 wxFD_ZERO(&writefds);
1602 wxFD_SET(m_fd, &writefds);
09e6e5ec 1603 ret = select(m_fd + 1, NULL, &writefds, NULL, &tv);
97e6ee04
DE
1604 if (ret == 0)
1605 {
1606 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
09e6e5ec 1607 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1608 return GSOCK_TIMEDOUT;
1609 }
1aa7b427 1610
97e6ee04
DE
1611 if (ret == -1)
1612 {
1613 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1614 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1615 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1616 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1617 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
09e6e5ec 1618 m_error = GSOCK_TIMEDOUT;
97e6ee04
DE
1619 return GSOCK_TIMEDOUT;
1620 }
1aa7b427
DS
1621
1622 if ( ! wxFD_ISSET(m_fd, &writefds) )
1623 {
97e6ee04
DE
1624 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1625 }
1aa7b427
DS
1626 else
1627 {
97e6ee04
DE
1628 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1629 }
1630 }
1631 else
1632 {
1633 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1634 }
1635
1636 return GSOCK_NOERROR;
1637}
1638
ba2a81d7 1639int GSocket::Recv_Stream(char *buffer, int size)
97e6ee04 1640{
bb154f79 1641 int ret;
7e1e6965 1642 do
bb154f79
KH
1643 {
1644 ret = recv(m_fd, buffer, size, GSOCKET_MSG_NOSIGNAL);
1aa7b427
DS
1645 }
1646 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1647
bb154f79 1648 return ret;
97e6ee04
DE
1649}
1650
ba2a81d7 1651int GSocket::Recv_Dgram(char *buffer, int size)
97e6ee04 1652{
8575ff50 1653 wxSockAddr from;
9e03e02d 1654 WX_SOCKLEN_T fromlen = sizeof(from);
97e6ee04
DE
1655 int ret;
1656 GSocketError err;
1657
1658 fromlen = sizeof(from);
1659
7e1e6965 1660 do
bb154f79 1661 {
8575ff50 1662 ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
1aa7b427
DS
1663 }
1664 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
97e6ee04
DE
1665
1666 if (ret == -1)
1667 return -1;
1668
1669 /* Translate a system address into a GSocket address */
09e6e5ec 1670 if (!m_peer)
97e6ee04 1671 {
09e6e5ec
DE
1672 m_peer = GAddress_new();
1673 if (!m_peer)
97e6ee04 1674 {
09e6e5ec 1675 m_error = GSOCK_MEMERR;
97e6ee04
DE
1676 return -1;
1677 }
1678 }
1aa7b427 1679
8575ff50 1680 err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
97e6ee04
DE
1681 if (err != GSOCK_NOERROR)
1682 {
09e6e5ec
DE
1683 GAddress_destroy(m_peer);
1684 m_peer = NULL;
1685 m_error = err;
97e6ee04
DE
1686 return -1;
1687 }
1688
1689 return ret;
1690}
1691
ba2a81d7 1692int GSocket::Send_Stream(const char *buffer, int size)
97e6ee04
DE
1693{
1694 int ret;
1695
7e1e6965
WS
1696 MASK_SIGNAL();
1697
1698 do
bb154f79
KH
1699 {
1700 ret = send(m_fd, (char *)buffer, size, GSOCKET_MSG_NOSIGNAL);
1aa7b427
DS
1701 }
1702 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
7e1e6965 1703
97e6ee04 1704 UNMASK_SIGNAL();
97e6ee04
DE
1705
1706 return ret;
1707}
1708
ba2a81d7 1709int GSocket::Send_Dgram(const char *buffer, int size)
97e6ee04
DE
1710{
1711 struct sockaddr *addr;
1712 int len, ret;
1713 GSocketError err;
1714
09e6e5ec 1715 if (!m_peer)
97e6ee04 1716 {
09e6e5ec 1717 m_error = GSOCK_INVADDR;
97e6ee04
DE
1718 return -1;
1719 }
1720
09e6e5ec 1721 err = _GAddress_translate_to(m_peer, &addr, &len);
97e6ee04
DE
1722 if (err != GSOCK_NOERROR)
1723 {
09e6e5ec 1724 m_error = err;
97e6ee04
DE
1725 return -1;
1726 }
1727
97e6ee04 1728 MASK_SIGNAL();
7e1e6965
WS
1729
1730 do
bb154f79
KH
1731 {
1732 ret = sendto(m_fd, (char *)buffer, size, 0, addr, len);
1aa7b427
DS
1733 }
1734 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
7e1e6965 1735
97e6ee04 1736 UNMASK_SIGNAL();
97e6ee04
DE
1737
1738 /* Frees memory allocated from _GAddress_translate_to */
1739 free(addr);
1740
1741 return ret;
1742}
1743
ba2a81d7 1744void GSocket::Detected_Read()
97e6ee04
DE
1745{
1746 char c;
1747
bb154f79
KH
1748 /* Safeguard against straggling call to Detected_Read */
1749 if (m_fd == INVALID_SOCKET)
1750 {
1751 return;
1752 }
1753
97e6ee04
DE
1754 /* If we have already detected a LOST event, then don't try
1755 * to do any further processing.
1756 */
09e6e5ec 1757 if ((m_detected & GSOCK_LOST_FLAG) != 0)
97e6ee04 1758 {
948c96ef 1759 m_establishing = false;
97e6ee04 1760
ba2a81d7 1761 CALL_CALLBACK(this, GSOCK_LOST);
09e6e5ec 1762 Shutdown();
97e6ee04
DE
1763 return;
1764 }
1765
bb154f79
KH
1766 int num = recv(m_fd, &c, 1, MSG_PEEK | GSOCKET_MSG_NOSIGNAL);
1767
1768 if (num > 0)
97e6ee04 1769 {
ba2a81d7 1770 CALL_CALLBACK(this, GSOCK_INPUT);
97e6ee04
DE
1771 }
1772 else
1773 {
09e6e5ec 1774 if (m_server && m_stream)
97e6ee04 1775 {
ba2a81d7 1776 CALL_CALLBACK(this, GSOCK_CONNECTION);
97e6ee04 1777 }
e37e082e
VZ
1778 else if (num == 0)
1779 {
01c03554
VZ
1780 if (m_stream)
1781 {
1782 /* graceful shutdown */
1783 CALL_CALLBACK(this, GSOCK_LOST);
1784 Shutdown();
1785 }
1786 else
1787 {
1788 /* Empty datagram received */
1789 CALL_CALLBACK(this, GSOCK_INPUT);
1790 }
e37e082e 1791 }
97e6ee04
DE
1792 else
1793 {
e400d27d 1794 /* Do not throw a lost event in cases where the socket isn't really lost */
7e1e6965 1795 if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR))
bb154f79
KH
1796 {
1797 CALL_CALLBACK(this, GSOCK_INPUT);
1798 }
7e1e6965 1799 else
bb154f79
KH
1800 {
1801 CALL_CALLBACK(this, GSOCK_LOST);
1802 Shutdown();
7e1e6965 1803 }
97e6ee04
DE
1804 }
1805 }
1806}
1807
ba2a81d7 1808void GSocket::Detected_Write()
97e6ee04
DE
1809{
1810 /* If we have already detected a LOST event, then don't try
1811 * to do any further processing.
1812 */
09e6e5ec 1813 if ((m_detected & GSOCK_LOST_FLAG) != 0)
97e6ee04 1814 {
948c96ef 1815 m_establishing = false;
97e6ee04 1816
ba2a81d7 1817 CALL_CALLBACK(this, GSOCK_LOST);
09e6e5ec 1818 Shutdown();
97e6ee04
DE
1819 return;
1820 }
1821
09e6e5ec 1822 if (m_establishing && !m_server)
97e6ee04
DE
1823 {
1824 int error;
ddc1a35f 1825 SOCKOPTLEN_T len = sizeof(error);
97e6ee04 1826
948c96ef 1827 m_establishing = false;
97e6ee04 1828
f71bb8ef 1829 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
97e6ee04
DE
1830
1831 if (error)
1832 {
ba2a81d7 1833 CALL_CALLBACK(this, GSOCK_LOST);
09e6e5ec 1834 Shutdown();
97e6ee04
DE
1835 }
1836 else
1837 {
ba2a81d7 1838 CALL_CALLBACK(this, GSOCK_CONNECTION);
97e6ee04
DE
1839 /* We have to fire this event by hand because CONNECTION (for clients)
1840 * and OUTPUT are internally the same and we just disabled CONNECTION
1841 * events with the above macro.
1842 */
ba2a81d7 1843 CALL_CALLBACK(this, GSOCK_OUTPUT);
97e6ee04
DE
1844 }
1845 }
1846 else
1847 {
ba2a81d7 1848 CALL_CALLBACK(this, GSOCK_OUTPUT);
97e6ee04
DE
1849 }
1850}
1851
09e6e5ec
DE
1852/* Compatibility functions for GSocket */
1853GSocket *GSocket_new(void)
1854{
ba2a81d7 1855 GSocket *newsocket = new GSocket();
1aa7b427 1856 if (newsocket->IsOk())
09e6e5ec 1857 return newsocket;
1aa7b427 1858
09e6e5ec 1859 delete newsocket;
1aa7b427 1860
09e6e5ec
DE
1861 return NULL;
1862}
1863
97e6ee04
DE
1864/*
1865 * -------------------------------------------------------------------------
1866 * GAddress
1867 * -------------------------------------------------------------------------
1868 */
1869
1870/* CHECK_ADDRESS verifies that the current address family is either
1871 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1872 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1873 * an appropiate error code.
1874 *
1875 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1876 */
1877#define CHECK_ADDRESS(address, family) \
1878{ \
1879 if (address->m_family == GSOCK_NOFAMILY) \
1880 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1881 return address->m_error; \
1882 if (address->m_family != GSOCK_##family) \
1883 { \
1884 address->m_error = GSOCK_INVADDR; \
1885 return GSOCK_INVADDR; \
1886 } \
1887}
1888
1889#define CHECK_ADDRESS_RETVAL(address, family, retval) \
1890{ \
1891 if (address->m_family == GSOCK_NOFAMILY) \
1892 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1893 return retval; \
1894 if (address->m_family != GSOCK_##family) \
1895 { \
1896 address->m_error = GSOCK_INVADDR; \
1897 return retval; \
1898 } \
1899}
1900
1901
1902GAddress *GAddress_new(void)
1903{
1904 GAddress *address;
1905
1906 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1907 return NULL;
1908
1909 address->m_family = GSOCK_NOFAMILY;
1910 address->m_addr = NULL;
1911 address->m_len = 0;
1912
1913 return address;
1914}
1915
1916GAddress *GAddress_copy(GAddress *address)
1917{
1918 GAddress *addr2;
1919
1920 assert(address != NULL);
1921
1922 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1923 return NULL;
1924
1925 memcpy(addr2, address, sizeof(GAddress));
1926
1927 if (address->m_addr && address->m_len > 0)
1928 {
1929 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
1930 if (addr2->m_addr == NULL)
1931 {
1932 free(addr2);
1933 return NULL;
1934 }
1935 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1936 }
1937
1938 return addr2;
1939}
1940
1941void GAddress_destroy(GAddress *address)
1942{
1943 assert(address != NULL);
1944
1945 if (address->m_addr)
1946 free(address->m_addr);
1947
1948 free(address);
1949}
1950
1951void GAddress_SetFamily(GAddress *address, GAddressType type)
1952{
1953 assert(address != NULL);
1954
1955 address->m_family = type;
1956}
1957
1958GAddressType GAddress_GetFamily(GAddress *address)
1959{
1960 assert(address != NULL);
1961
1962 return address->m_family;
1963}
1964
1965GSocketError _GAddress_translate_from(GAddress *address,
1966 struct sockaddr *addr, int len)
1967{
1968 address->m_realfamily = addr->sa_family;
1969 switch (addr->sa_family)
1970 {
1971 case AF_INET:
1972 address->m_family = GSOCK_INET;
1973 break;
1974 case AF_UNIX:
1975 address->m_family = GSOCK_UNIX;
1976 break;
8575ff50 1977#if wxUSE_IPV6
97e6ee04
DE
1978 case AF_INET6:
1979 address->m_family = GSOCK_INET6;
1980 break;
8575ff50 1981#endif // wxUSE_IPV6
97e6ee04
DE
1982 default:
1983 {
1984 address->m_error = GSOCK_INVOP;
1985 return GSOCK_INVOP;
1986 }
1987 }
1988
1989 if (address->m_addr)
1990 free(address->m_addr);
1991
1992 address->m_len = len;
1993 address->m_addr = (struct sockaddr *)malloc(len);
1994
1995 if (address->m_addr == NULL)
1996 {
1997 address->m_error = GSOCK_MEMERR;
1998 return GSOCK_MEMERR;
1999 }
1aa7b427 2000
97e6ee04
DE
2001 memcpy(address->m_addr, addr, len);
2002
2003 return GSOCK_NOERROR;
2004}
2005
2006GSocketError _GAddress_translate_to(GAddress *address,
2007 struct sockaddr **addr, int *len)
2008{
2009 if (!address->m_addr)
2010 {
2011 address->m_error = GSOCK_INVADDR;
2012 return GSOCK_INVADDR;
2013 }
2014
2015 *len = address->m_len;
2016 *addr = (struct sockaddr *)malloc(address->m_len);
2017 if (*addr == NULL)
2018 {
2019 address->m_error = GSOCK_MEMERR;
2020 return GSOCK_MEMERR;
2021 }
2022
2023 memcpy(*addr, address->m_addr, address->m_len);
2024 return GSOCK_NOERROR;
2025}
2026
2027/*
2028 * -------------------------------------------------------------------------
2029 * Internet address family
2030 * -------------------------------------------------------------------------
2031 */
2032
2033GSocketError _GAddress_Init_INET(GAddress *address)
2034{
2035 address->m_len = sizeof(struct sockaddr_in);
2036 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2037 if (address->m_addr == NULL)
2038 {
2039 address->m_error = GSOCK_MEMERR;
2040 return GSOCK_MEMERR;
2041 }
2042
2043 address->m_family = GSOCK_INET;
2044 address->m_realfamily = PF_INET;
2045 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
2046 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
2047
2048 return GSOCK_NOERROR;
2049}
2050
2051GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
2052{
2053 struct hostent *he;
2054 struct in_addr *addr;
2055
2056 assert(address != NULL);
2057
2058 CHECK_ADDRESS(address, INET);
2059
2060 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
2061
2062 /* If it is a numeric host name, convert it now */
2063#if defined(HAVE_INET_ATON)
2064 if (inet_aton(hostname, addr) == 0)
2065 {
2066#elif defined(HAVE_INET_ADDR)
8c0f8906 2067 if ( (addr->s_addr = inet_addr(hostname)) == (unsigned)-1 )
97e6ee04
DE
2068 {
2069#else
2070 /* Use gethostbyname by default */
9d715960 2071#ifndef __WXMAC__
ba2a81d7 2072 int val = 1; /* VA doesn't like constants in conditional expressions */
97e6ee04 2073 if (val)
9d715960 2074#endif
97e6ee04
DE
2075 {
2076#endif
2077 struct in_addr *array_addr;
2078
2079 /* It is a real name, we solve it */
127189eb
SN
2080 struct hostent h;
2081#if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2082 struct hostent_data buffer;
2083#else
2084 char buffer[1024];
2085#endif
2086 int err;
2087 he = wxGethostbyname_r(hostname, &h, (void*)&buffer, sizeof(buffer), &err);
2088 if (he == NULL)
97e6ee04
DE
2089 {
2090 /* Reset to invalid address */
2091 addr->s_addr = INADDR_NONE;
2092 address->m_error = GSOCK_NOHOST;
2093 return GSOCK_NOHOST;
2094 }
1aa7b427 2095
97e6ee04
DE
2096 array_addr = (struct in_addr *) *(he->h_addr_list);
2097 addr->s_addr = array_addr[0].s_addr;
2098 }
1aa7b427 2099
97e6ee04
DE
2100 return GSOCK_NOERROR;
2101}
2102
60edcf45
VZ
2103
2104GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
2105{
2106 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
2107}
2108
97e6ee04
DE
2109GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
2110{
2111 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
2112}
2113
2114GSocketError GAddress_INET_SetHostAddress(GAddress *address,
2115 unsigned long hostaddr)
2116{
2117 struct in_addr *addr;
2118
2119 assert(address != NULL);
2120
2121 CHECK_ADDRESS(address, INET);
2122
2123 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
9d715960 2124 addr->s_addr = htonl(hostaddr);
97e6ee04
DE
2125
2126 return GSOCK_NOERROR;
2127}
2128
2129GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
2130 const char *protocol)
2131{
2132 struct servent *se;
2133 struct sockaddr_in *addr;
2134
2135 assert(address != NULL);
2136 CHECK_ADDRESS(address, INET);
2137
2138 if (!port)
2139 {
2140 address->m_error = GSOCK_INVPORT;
2141 return GSOCK_INVPORT;
2142 }
b082b524 2143
127189eb
SN
2144#if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2145 struct servent_data buffer;
f6bc1c74 2146#else
127189eb 2147 char buffer[1024];
f6bc1c74 2148#endif
127189eb
SN
2149 struct servent serv;
2150 se = wxGetservbyname_r(port, protocol, &serv,
2151 (void*)&buffer, sizeof(buffer));
97e6ee04
DE
2152 if (!se)
2153 {
2154 /* the cast to int suppresses compiler warnings about subscript having the
2155 type char */
2156 if (isdigit((int)port[0]))
2157 {
2158 int port_int;
2159
2160 port_int = atoi(port);
2161 addr = (struct sockaddr_in *)address->m_addr;
2162 addr->sin_port = htons(port_int);
2163 return GSOCK_NOERROR;
2164 }
2165
2166 address->m_error = GSOCK_INVPORT;
2167 return GSOCK_INVPORT;
2168 }
2169
2170 addr = (struct sockaddr_in *)address->m_addr;
2171 addr->sin_port = se->s_port;
2172
2173 return GSOCK_NOERROR;
2174}
2175
2176GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
2177{
2178 struct sockaddr_in *addr;
2179
2180 assert(address != NULL);
2181 CHECK_ADDRESS(address, INET);
b082b524 2182
97e6ee04
DE
2183 addr = (struct sockaddr_in *)address->m_addr;
2184 addr->sin_port = htons(port);
2185
2186 return GSOCK_NOERROR;
2187}
2188
2189GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2190{
2191 struct hostent *he;
2192 char *addr_buf;
2193 struct sockaddr_in *addr;
2194
b082b524 2195 assert(address != NULL);
97e6ee04
DE
2196 CHECK_ADDRESS(address, INET);
2197
2198 addr = (struct sockaddr_in *)address->m_addr;
2199 addr_buf = (char *)&(addr->sin_addr);
2200
127189eb
SN
2201 struct hostent temphost;
2202#if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2203 struct hostent_data buffer;
2204#else
2205 char buffer[1024];
2206#endif
2207 int err;
2208 he = wxGethostbyaddr_r(addr_buf, sizeof(addr->sin_addr), AF_INET, &temphost,
2209 (void*)&buffer, sizeof(buffer), &err);
97e6ee04
DE
2210 if (he == NULL)
2211 {
2212 address->m_error = GSOCK_NOHOST;
2213 return GSOCK_NOHOST;
2214 }
2215
2216 strncpy(hostname, he->h_name, sbuf);
2217
2218 return GSOCK_NOERROR;
2219}
2220
2221unsigned long GAddress_INET_GetHostAddress(GAddress *address)
2222{
2223 struct sockaddr_in *addr;
2224
b082b524
DE
2225 assert(address != NULL);
2226 CHECK_ADDRESS_RETVAL(address, INET, 0);
97e6ee04
DE
2227
2228 addr = (struct sockaddr_in *)address->m_addr;
2229
9d715960 2230 return ntohl(addr->sin_addr.s_addr);
97e6ee04
DE
2231}
2232
2233unsigned short GAddress_INET_GetPort(GAddress *address)
2234{
2235 struct sockaddr_in *addr;
2236
b082b524
DE
2237 assert(address != NULL);
2238 CHECK_ADDRESS_RETVAL(address, INET, 0);
97e6ee04
DE
2239
2240 addr = (struct sockaddr_in *)address->m_addr;
2241 return ntohs(addr->sin_port);
2242}
2243
8575ff50
VZ
2244#if wxUSE_IPV6
2245/*
2246 * -------------------------------------------------------------------------
2247 * Internet IPv6 address family
2248 * -------------------------------------------------------------------------
2249 */
2250
2251GSocketError _GAddress_Init_INET6(GAddress *address)
2252{
2253 struct in6_addr any_address = IN6ADDR_ANY_INIT;
2254 address->m_len = sizeof(struct sockaddr_in6);
2255 address->m_addr = (struct sockaddr *) malloc(address->m_len);
2256 if (address->m_addr == NULL)
2257 {
2258 address->m_error = GSOCK_MEMERR;
2259 return GSOCK_MEMERR;
2260 }
2261 memset(address->m_addr,0,address->m_len);
2262
2263 address->m_family = GSOCK_INET6;
2264 address->m_realfamily = AF_INET6;
2265 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
2266 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
2267
2268 return GSOCK_NOERROR;
2269}
2270
2271GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
2272{
2273 assert(address != NULL);
2274 CHECK_ADDRESS(address, INET6);
2275
2276 addrinfo hints;
2277 memset( & hints, 0, sizeof( hints ) );
2278 hints.ai_family = AF_INET6;
2279 addrinfo * info = 0;
2280 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
2281 {
2282 address->m_error = GSOCK_NOHOST;
2283 return GSOCK_NOHOST;
2284 }
2285
2286 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
2287 freeaddrinfo( info );
2288 return GSOCK_NOERROR;
2289}
2290
2291GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
2292{
2293 assert(address != NULL);
2294
2295 CHECK_ADDRESS(address, INET6);
2296
2297 struct in6_addr addr;
2298 memset( & addr, 0, sizeof( addr ) );
2299 return GAddress_INET6_SetHostAddress(address, addr);
2300}
2301GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
2302 struct in6_addr hostaddr)
2303{
2304 assert(address != NULL);
2305
2306 CHECK_ADDRESS(address, INET6);
2307
2308 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
2309
2310 return GSOCK_NOERROR;
2311}
2312
2313GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
2314 const char *protocol)
2315{
2316 struct servent *se;
2317 struct sockaddr_in6 *addr;
2318
2319 assert(address != NULL);
2320 CHECK_ADDRESS(address, INET6);
2321
2322 if (!port)
2323 {
2324 address->m_error = GSOCK_INVPORT;
2325 return GSOCK_INVPORT;
2326 }
2327
2328 se = getservbyname(port, protocol);
2329 if (!se)
2330 {
2331 if (isdigit(port[0]))
2332 {
2333 int port_int;
2334
2335 port_int = atoi(port);
2336 addr = (struct sockaddr_in6 *)address->m_addr;
2337 addr->sin6_port = htons((u_short) port_int);
2338 return GSOCK_NOERROR;
2339 }
2340
2341 address->m_error = GSOCK_INVPORT;
2342 return GSOCK_INVPORT;
2343 }
2344
2345 addr = (struct sockaddr_in6 *)address->m_addr;
2346 addr->sin6_port = se->s_port;
2347
2348 return GSOCK_NOERROR;
2349}
2350
2351GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
2352{
2353 struct sockaddr_in6 *addr;
2354
2355 assert(address != NULL);
2356 CHECK_ADDRESS(address, INET6);
2357
2358 addr = (struct sockaddr_in6 *)address->m_addr;
2359 addr->sin6_port = htons(port);
2360
2361 return GSOCK_NOERROR;
2362}
2363
2364GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
2365{
2366 struct hostent *he;
2367 char *addr_buf;
2368 struct sockaddr_in6 *addr;
2369
2370 assert(address != NULL);
2371 CHECK_ADDRESS(address, INET6);
2372
2373 addr = (struct sockaddr_in6 *)address->m_addr;
2374 addr_buf = (char *)&(addr->sin6_addr);
2375
2376 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
2377 if (he == NULL)
2378 {
2379 address->m_error = GSOCK_NOHOST;
2380 return GSOCK_NOHOST;
2381 }
2382
2383 strncpy(hostname, he->h_name, sbuf);
2384
2385 return GSOCK_NOERROR;
2386}
2387
2388GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
2389{
2390 assert(address != NULL);
2391 assert(hostaddr != NULL);
2392 CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
2393 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
2394 return GSOCK_NOERROR;
2395}
2396
2397unsigned short GAddress_INET6_GetPort(GAddress *address)
2398{
2399 assert(address != NULL);
2400 CHECK_ADDRESS_RETVAL(address, INET6, 0);
2401
2402 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
2403}
2404
2405#endif // wxUSE_IPV6
2406
97e6ee04
DE
2407/*
2408 * -------------------------------------------------------------------------
2409 * Unix address family
2410 * -------------------------------------------------------------------------
2411 */
2412
2413#ifndef __VISAGECPP__
2414GSocketError _GAddress_Init_UNIX(GAddress *address)
2415{
2416 address->m_len = sizeof(struct sockaddr_un);
2417 address->m_addr = (struct sockaddr *)malloc(address->m_len);
2418 if (address->m_addr == NULL)
2419 {
2420 address->m_error = GSOCK_MEMERR;
2421 return GSOCK_MEMERR;
2422 }
2423
2424 address->m_family = GSOCK_UNIX;
2425 address->m_realfamily = PF_UNIX;
2426 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
2427 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
2428
2429 return GSOCK_NOERROR;
2430}
2431
2432#define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2433
2434GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
2435{
2436 struct sockaddr_un *addr;
2437
b082b524 2438 assert(address != NULL);
97e6ee04 2439
b082b524 2440 CHECK_ADDRESS(address, UNIX);
97e6ee04
DE
2441
2442 addr = ((struct sockaddr_un *)address->m_addr);
2443 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
2444 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
2445
2446 return GSOCK_NOERROR;
2447}
2448
2449GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
2450{
2451 struct sockaddr_un *addr;
2452
2453 assert(address != NULL);
2454 CHECK_ADDRESS(address, UNIX);
2455
2456 addr = (struct sockaddr_un *)address->m_addr;
2457
2458 strncpy(path, addr->sun_path, sbuf);
2459
2460 return GSOCK_NOERROR;
2461}
2462#endif /* !defined(__VISAGECPP__) */
2463#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */