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