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