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