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>
48struct 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)
87int _System bsdselect(int,
88                      struct fd_set *,
89                      struct fd_set *,
90                      struct fd_set *,
91                      struct timeval *);
92int _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)
200static 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
283static wxMutex nameLock;
284#endif
285struct 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
318static wxMutex addrLock;
319#endif
320struct 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)
355static 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
418static wxMutex servLock;
419#endif
420struct 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
455static GSocketGUIFunctionsTable *gs_gui_functions;
456
457class GSocketGUIFunctionsTableNull: public GSocketGUIFunctionsTable
458{
459public:
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
471bool GSocketGUIFunctionsTableNull::OnInit()
472{   return true; }
473void GSocketGUIFunctionsTableNull::OnExit()
474{}
475bool GSocketGUIFunctionsTableNull::CanUseEventLoop()
476{   return false; }
477bool GSocketGUIFunctionsTableNull::Init_Socket(GSocket *WXUNUSED(socket))
478{   return true; }
479void GSocketGUIFunctionsTableNull::Destroy_Socket(GSocket *WXUNUSED(socket))
480{}
481void GSocketGUIFunctionsTableNull::Install_Callback(GSocket *WXUNUSED(socket), GSocketEvent WXUNUSED(event))
482{}
483void GSocketGUIFunctionsTableNull::Uninstall_Callback(GSocket *WXUNUSED(socket), GSocketEvent WXUNUSED(event))
484{}
485void GSocketGUIFunctionsTableNull::Enable_Events(GSocket *WXUNUSED(socket))
486{}
487void GSocketGUIFunctionsTableNull::Disable_Events(GSocket *WXUNUSED(socket))
488{}
489/* Global initialisers */
490
491void GSocket_SetGUIFunctions(GSocketGUIFunctionsTable *guifunc)
492{
493  gs_gui_functions = guifunc;
494}
495
496int 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
508void GSocket_Cleanup(void)
509{
510  if (gs_gui_functions)
511  {
512      gs_gui_functions->OnExit();
513  }
514}
515
516/* Constructors / Destructors for GSocket */
517
518GSocket::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
545void 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
562GSocket::~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 */
585void 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 */
624GSocketError 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
650GSocketError 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
669GAddress *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
714GAddress *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 */
737GSocketError 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 */
819GSocket *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
900bool 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 */
938GSocketError 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 */
1089GSocketError 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(), ... */
1153int 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
1214int 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 */
1279GSocketEventFlags 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 */
1399void 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 */
1412void 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 */
1424GSocketError 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 */
1461void 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 */
1482void 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
1498GSocketError 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
1507GSocketError 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
1523void GSocket::Enable(GSocketEvent event)
1524{
1525  m_detected &= ~(1 << event);
1526  gs_gui_functions->Install_Callback(this, event);
1527}
1528
1529void 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 */
1539GSocketError 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 */
1589GSocketError 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
1641int 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
1653int 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
1694int 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
1711int 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
1746void 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
1810void 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 */
1855GSocket *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
1904GAddress *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
1918GAddress *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
1943void 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
1953void GAddress_SetFamily(GAddress *address, GAddressType type)
1954{
1955  assert(address != NULL);
1956
1957  address->m_family = type;
1958}
1959
1960GAddressType GAddress_GetFamily(GAddress *address)
1961{
1962  assert(address != NULL);
1963
1964  return address->m_family;
1965}
1966
1967GSocketError _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
2008GSocketError _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
2035GSocketError _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
2053GSocketError 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
2106GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
2107{
2108  return GAddress_INET_SetHostAddress(address, INADDR_ANY);
2109}
2110
2111GSocketError 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
2126GSocketError 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
2174GSocketError 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
2187GSocketError 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
2220unsigned 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
2232unsigned 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__
2250GSocketError _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
2270GSocketError 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
2285GSocketError 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