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