1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Authors: David Elliott (C++ conversion, maintainer)
8 * Guillermo Rodriguez Garcia <guille@iies.es>
9 * Purpose: GSocket main Unix and OS/2 file
10 * Licence: The wxWindows licence
12 * -------------------------------------------------------------------------
15 #if defined(__WATCOMC__)
16 #include "wx/wxprec.h"
21 #ifndef __GSOCKET_STANDALONE__
23 #include "wx/private/gsocketiohandler.h"
26 #if defined(__VISAGECPP__)
27 #define BSD_SELECT /* use Berkeley Sockets select */
30 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
33 #include <sys/types.h>
38 #include <netinet/in.h>
41 #include <sys/ioctl.h>
43 #ifdef HAVE_SYS_SELECT_H
44 # include <sys/select.h>
51 u_char sun_len
; /* sockaddr len including null */
52 u_char sun_family
; /* AF_UNIX */
53 char sun_path
[108]; /* path name (gag) */
56 #include <sys/socket.h>
62 #include <netinet/in.h>
63 #include <arpa/inet.h>
70 #include <machine/endian.h>
76 #define EBADF SOCEBADF
82 #include <sys/socket.h>
83 #include <sys/ioctl.h>
84 #include <sys/select.h>
86 #define close(a) soclose(a)
87 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
88 int _System
bsdselect(int,
93 int _System
soclose(int);
97 #include <sys/select.h>
105 # include <sys/filio.h>
108 # include <bstring.h>
111 # include <strings.h>
118 # define WX_SOCKLEN_T unsigned int
122 # define WX_SOCKLEN_T socklen_t
124 # elif defined(__WXMAC__)
125 # define WX_SOCKLEN_T socklen_t
127 # define WX_SOCKLEN_T int
131 #endif /* SOCKLEN_T */
134 #define SOCKOPTLEN_T WX_SOCKLEN_T
138 * MSW defines this, Unices don't.
140 #ifndef INVALID_SOCKET
141 #define INVALID_SOCKET -1
144 /* UnixWare reportedly needs this for FIONBIO definition */
146 #include <sys/filio.h>
150 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
151 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
154 #define INADDR_NONE INADDR_BROADCAST
157 #if defined(__VISAGECPP__) || defined(__WATCOMC__)
159 #define MASK_SIGNAL() {
160 #define UNMASK_SIGNAL() }
163 extern "C" { typedef void (*wxSigHandler
)(int); }
165 #define MASK_SIGNAL() \
167 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
169 #define UNMASK_SIGNAL() \
170 signal(SIGPIPE, old_handler); \
175 /* If a SIGPIPE is issued by a socket call on a remotely closed socket,
176 the program will "crash" unless it explicitly handles the SIGPIPE.
177 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
178 use SO_NOSIGPIPE (if available), the BSD equivalent. */
180 # define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
181 #else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
182 # define GSOCKET_MSG_NOSIGNAL 0
183 #endif /* MSG_NOSIGNAL */
185 #ifndef __GSOCKET_STANDALONE__
186 # include "wx/unix/gsockunx.h"
187 # include "wx/unix/private.h"
188 # include "wx/gsocket.h"
189 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
190 # include "wx/thread.h"
193 # include "gsockunx.h"
194 # include "gsocket.h"
198 #endif /* __GSOCKET_STANDALONE__ */
200 #if defined(HAVE_GETHOSTBYNAME)
201 static struct hostent
* deepCopyHostent(struct hostent
*h
,
202 const struct hostent
*he
,
203 char *buffer
, int size
, int *err
)
205 /* copy old structure */
206 memcpy(h
, he
, sizeof(struct hostent
));
209 int len
= strlen(h
->h_name
);
215 memcpy(buffer
, h
->h_name
, len
);
219 /* track position in the buffer */
222 /* reuse len to store address length */
225 /* ensure pointer alignment */
226 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
227 if(misalign
< sizeof(char *))
230 /* leave space for pointer list */
231 char **p
= h
->h_addr_list
, **q
;
232 char **h_addr_list
= (char **)(buffer
+ pos
);
234 pos
+= sizeof(char *);
236 /* copy addresses and fill new pointer list */
237 for (p
= h
->h_addr_list
, q
= h_addr_list
; *p
!= 0; p
++, q
++)
239 if (size
< pos
+ len
)
244 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
245 *q
= buffer
+ pos
; /* set copied pointer to copied content */
248 *++q
= 0; /* null terminate the pointer list */
249 h
->h_addr_list
= h_addr_list
; /* copy pointer to pointers */
251 /* ensure word alignment of pointers */
252 misalign
= sizeof(char *) - pos%sizeof
(char *);
253 if(misalign
< sizeof(char *))
256 /* leave space for pointer list */
258 char **h_aliases
= (char **)(buffer
+ pos
);
260 pos
+= sizeof(char *);
262 /* copy aliases and fill new pointer list */
263 for (p
= h
->h_aliases
, q
= h_aliases
; *p
!= 0; p
++, q
++)
266 if (size
<= pos
+ len
)
271 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
272 buffer
[pos
+ len
] = '\0';
273 *q
= buffer
+ pos
; /* set copied pointer to copied content */
276 *++q
= 0; /* null terminate the pointer list */
277 h
->h_aliases
= h_aliases
; /* copy pointer to pointers */
283 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
284 static wxMutex nameLock
;
286 struct hostent
* wxGethostbyname_r(const char *hostname
, struct hostent
*h
,
287 void *buffer
, int size
, int *err
)
290 struct hostent
*he
= NULL
;
292 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
293 if (gethostbyname_r(hostname
, h
, (char*)buffer
, size
, &he
, err
))
295 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
296 he
= gethostbyname_r(hostname
, h
, (char*)buffer
, size
, err
);
297 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
298 if (gethostbyname_r(hostname
, h
, (struct hostent_data
*) buffer
))
305 #elif defined(HAVE_GETHOSTBYNAME)
307 wxMutexLocker
locker(nameLock
);
309 he
= gethostbyname(hostname
);
313 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
318 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
319 static wxMutex addrLock
;
321 struct hostent
* wxGethostbyaddr_r(const char *addr_buf
, int buf_size
,
322 int proto
, struct hostent
*h
,
323 void *buffer
, int size
, int *err
)
325 struct hostent
*he
= NULL
;
327 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
328 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
329 (char*)buffer
, size
, &he
, err
))
331 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
332 he
= gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
, (char*)buffer
, size
, err
);
333 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
334 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
335 (struct hostent_data
*) buffer
))
342 #elif defined(HAVE_GETHOSTBYNAME)
344 wxMutexLocker
locker(addrLock
);
346 he
= gethostbyaddr(addr_buf
, buf_size
, proto
);
350 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
355 #if defined(HAVE_GETSERVBYNAME)
356 static struct servent
* deepCopyServent(struct servent
*s
,
357 const struct servent
*se
,
358 char *buffer
, int size
)
360 /* copy plain old structure */
361 memcpy(s
, se
, sizeof(struct servent
));
364 int len
= strlen(s
->s_name
);
369 memcpy(buffer
, s
->s_name
, len
);
373 /* track position in the buffer */
377 len
= strlen(s
->s_proto
);
378 if (pos
+ len
>= size
)
382 memcpy(buffer
+ pos
, s
->s_proto
, len
);
383 buffer
[pos
+ len
] = '\0';
384 s
->s_proto
= buffer
+ pos
;
386 /* track position in the buffer */
389 /* ensure pointer alignment */
390 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
391 if(misalign
< sizeof(char *))
394 /* leave space for pointer list */
395 char **p
= s
->s_aliases
, **q
;
396 char **s_aliases
= (char **)(buffer
+ pos
);
398 pos
+= sizeof(char *);
400 /* copy addresses and fill new pointer list */
401 for (p
= s
->s_aliases
, q
= s_aliases
; *p
!= 0; p
++, q
++){
403 if (size
<= pos
+ len
)
407 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
408 buffer
[pos
+ len
] = '\0';
409 *q
= buffer
+ pos
; /* set copied pointer to copied content */
412 *++q
= 0; /* null terminate the pointer list */
413 s
->s_aliases
= s_aliases
; /* copy pointer to pointers */
418 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
419 static wxMutex servLock
;
421 struct servent
*wxGetservbyname_r(const char *port
, const char *protocol
,
422 struct servent
*serv
, void *buffer
, int size
)
424 struct servent
*se
= NULL
;
425 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
426 if (getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
, &se
))
428 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
429 se
= getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
);
430 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
431 if (getservbyname_r(port
, protocol
, serv
, (struct servent_data
*) buffer
))
435 #elif defined(HAVE_GETSERVBYNAME)
437 wxMutexLocker
locker(servLock
);
439 se
= getservbyname(port
, protocol
);
441 se
= deepCopyServent(serv
, se
, (char*)buffer
, size
);
446 /* debugging helpers */
447 #ifdef __GSOCKET_DEBUG__
448 # define GSocket_Debug(args) printf args
450 # define GSocket_Debug(args)
451 #endif /* __GSOCKET_DEBUG__ */
454 typedef struct sockaddr_storage wxSockAddr
;
456 typedef struct sockaddr wxSockAddr
;
459 /* Table of GUI-related functions. We must call them indirectly because
460 * of wxBase and GUI separation: */
462 static GSocketGUIFunctionsTable
*gs_gui_functions
;
464 class GSocketGUIFunctionsTableNull
: public GSocketGUIFunctionsTable
467 virtual bool OnInit();
468 virtual void OnExit();
469 virtual bool CanUseEventLoop();
470 virtual bool Init_Socket(GSocket
*socket
);
471 virtual void Destroy_Socket(GSocket
*socket
);
472 virtual void Install_Callback(GSocket
*socket
, GSocketEvent event
);
473 virtual void Uninstall_Callback(GSocket
*socket
, GSocketEvent event
);
474 virtual void Enable_Events(GSocket
*socket
);
475 virtual void Disable_Events(GSocket
*socket
);
478 bool GSocketGUIFunctionsTableNull::OnInit()
480 void GSocketGUIFunctionsTableNull::OnExit()
482 bool GSocketGUIFunctionsTableNull::CanUseEventLoop()
484 bool GSocketGUIFunctionsTableNull::Init_Socket(GSocket
*WXUNUSED(socket
))
486 void GSocketGUIFunctionsTableNull::Destroy_Socket(GSocket
*WXUNUSED(socket
))
488 void GSocketGUIFunctionsTableNull::Install_Callback(GSocket
*WXUNUSED(socket
), GSocketEvent
WXUNUSED(event
))
490 void GSocketGUIFunctionsTableNull::Uninstall_Callback(GSocket
*WXUNUSED(socket
), GSocketEvent
WXUNUSED(event
))
492 void GSocketGUIFunctionsTableNull::Enable_Events(GSocket
*WXUNUSED(socket
))
494 void GSocketGUIFunctionsTableNull::Disable_Events(GSocket
*WXUNUSED(socket
))
496 /* Global initialisers */
498 void GSocket_SetGUIFunctions(GSocketGUIFunctionsTable
*guifunc
)
500 gs_gui_functions
= guifunc
;
503 int GSocket_Init(void)
505 if (!gs_gui_functions
)
507 static GSocketGUIFunctionsTableNull table
;
508 gs_gui_functions
= &table
;
510 if ( !gs_gui_functions
->OnInit() )
515 void GSocket_Cleanup(void)
517 if (gs_gui_functions
)
519 gs_gui_functions
->OnExit();
523 /* Constructors / Destructors for GSocket */
529 m_fd
= INVALID_SOCKET
;
532 for (i
=0;i
<GSOCK_MAX_EVENT
;i
++)
539 m_error
= GSOCK_NOERROR
;
542 m_gui_dependent
= NULL
;
543 m_non_blocking
= false;
547 m_timeout
= 10*60*1000;
548 /* 10 minutes * 60 sec * 1000 millisec */
549 m_establishing
= false;
550 m_initialRecvBufferSize
= -1;
551 m_initialSendBufferSize
= -1;
553 assert(gs_gui_functions
);
554 /* Per-socket GUI-specific initialization */
555 m_ok
= gs_gui_functions
->Init_Socket(this);
558 void GSocket::Close()
560 gs_gui_functions
->Disable_Events(this);
562 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
563 will close the socket during Disable_Events. However, it will only do this
564 if it is being used. That is, it won't do it in a console program. To
565 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
566 if it has closed the socket which indicates to us (at runtime, instead of
567 at compile time as this had been before) that the socket has already
570 if(m_fd
!= INVALID_SOCKET
)
572 m_fd
= INVALID_SOCKET
;
579 /* Check that the socket is really shutdowned */
580 if (m_fd
!= INVALID_SOCKET
)
583 /* Per-socket GUI-specific cleanup */
584 gs_gui_functions
->Destroy_Socket(this);
588 /* Destroy private addresses */
590 GAddress_destroy(m_local
);
593 GAddress_destroy(m_peer
);
597 * Disallow further read/write operations on this socket, close
598 * the fd and disable all callbacks.
600 void GSocket::Shutdown()
606 /* Don't allow events to fire after socket has been closed */
607 gs_gui_functions
->Disable_Events(this);
609 /* If socket has been created, shutdown it */
610 if (m_fd
!= INVALID_SOCKET
)
616 /* Disable GUI callbacks */
617 for (evt
= 0; evt
< GSOCK_MAX_EVENT
; evt
++)
618 m_cbacks
[evt
] = NULL
;
620 m_detected
= GSOCK_LOST_FLAG
;
623 /* Address handling */
629 * Set or get the local or peer address for this socket. The 'set'
630 * functions return GSOCK_NOERROR on success, an error code otherwise.
631 * The 'get' functions return a pointer to a GAddress object on success,
632 * or NULL otherwise, in which case they set the error code of the
633 * corresponding GSocket.
636 * GSOCK_INVSOCK - the socket is not valid.
637 * GSOCK_INVADDR - the address is not valid.
639 GSocketError
GSocket::SetLocal(GAddress
*address
)
643 /* the socket must be initialized, or it must be a server */
644 if ((m_fd
!= INVALID_SOCKET
&& !m_server
))
646 m_error
= GSOCK_INVSOCK
;
647 return GSOCK_INVSOCK
;
651 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
653 m_error
= GSOCK_INVADDR
;
654 return GSOCK_INVADDR
;
658 GAddress_destroy(m_local
);
660 m_local
= GAddress_copy(address
);
662 return GSOCK_NOERROR
;
665 GSocketError
GSocket::SetPeer(GAddress
*address
)
670 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
672 m_error
= GSOCK_INVADDR
;
673 return GSOCK_INVADDR
;
677 GAddress_destroy(m_peer
);
679 m_peer
= GAddress_copy(address
);
681 return GSOCK_NOERROR
;
684 GAddress
*GSocket::GetLocal()
688 WX_SOCKLEN_T size
= sizeof(addr
);
693 /* try to get it from the m_local var first */
695 return GAddress_copy(m_local
);
697 /* else, if the socket is initialized, try getsockname */
698 if (m_fd
== INVALID_SOCKET
)
700 m_error
= GSOCK_INVSOCK
;
704 if (getsockname(m_fd
, (sockaddr
*)&addr
, (WX_SOCKLEN_T
*) &size
) < 0)
706 m_error
= GSOCK_IOERR
;
710 /* got a valid address from getsockname, create a GAddress object */
711 address
= GAddress_new();
714 m_error
= GSOCK_MEMERR
;
718 err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
);
719 if (err
!= GSOCK_NOERROR
)
721 GAddress_destroy(address
);
729 GAddress
*GSocket::GetPeer()
733 /* try to get it from the m_peer var */
735 return GAddress_copy(m_peer
);
740 /* Server specific parts */
742 /* GSocket_SetServer:
743 * Sets up this socket as a server. The local address must have been
744 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
745 * Returns GSOCK_NOERROR on success, one of the following otherwise:
748 * GSOCK_INVSOCK - the socket is in use.
749 * GSOCK_INVADDR - the local address has not been set.
750 * GSOCK_IOERR - low-level error.
752 GSocketError
GSocket::SetServer()
758 /* must not be in use */
759 if (m_fd
!= INVALID_SOCKET
)
761 m_error
= GSOCK_INVSOCK
;
762 return GSOCK_INVSOCK
;
765 /* the local addr must have been set */
768 m_error
= GSOCK_INVADDR
;
769 return GSOCK_INVADDR
;
772 /* Initialize all fields */
776 /* Create the socket */
777 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
779 if (m_fd
== INVALID_SOCKET
)
781 m_error
= GSOCK_IOERR
;
785 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
787 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
790 ioctl(m_fd
, FIONBIO
, &arg
);
791 gs_gui_functions
->Enable_Events(this);
793 /* allow a socket to re-bind if the socket is in the TIME_WAIT
794 state after being previously closed.
798 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
800 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
804 /* Bind to the local address,
805 * retrieve the actual address bound,
806 * and listen up to 5 connections.
808 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
811 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
812 (listen(m_fd
, 5) != 0))
815 m_error
= GSOCK_IOERR
;
819 return GSOCK_NOERROR
;
822 /* GSocket_WaitConnection:
823 * Waits for an incoming client connection. Returns a pointer to
824 * a GSocket object, or NULL if there was an error, in which case
825 * the last error field will be updated for the calling GSocket.
827 * Error codes (set in the calling GSocket)
828 * GSOCK_INVSOCK - the socket is not valid or not a server.
829 * GSOCK_TIMEDOUT - timeout, no incoming connections.
830 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
831 * GSOCK_MEMERR - couldn't allocate memory.
832 * GSOCK_IOERR - low-level error.
834 GSocket
*GSocket::WaitConnection()
837 WX_SOCKLEN_T fromlen
= sizeof(from
);
844 /* If the socket has already been created, we exit immediately */
845 if (m_fd
== INVALID_SOCKET
|| !m_server
)
847 m_error
= GSOCK_INVSOCK
;
851 /* Create a GSocket object for the new connection */
852 connection
= GSocket_new();
856 m_error
= GSOCK_MEMERR
;
860 /* Wait for a connection (with timeout) */
861 if (Input_Timeout() == GSOCK_TIMEDOUT
)
864 /* m_error set by _GSocket_Input_Timeout */
868 connection
->m_fd
= accept(m_fd
, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
870 /* Reenable CONNECTION events */
871 Enable(GSOCK_CONNECTION
);
873 if (connection
->m_fd
== INVALID_SOCKET
)
875 if (errno
== EWOULDBLOCK
)
876 m_error
= GSOCK_WOULDBLOCK
;
878 m_error
= GSOCK_IOERR
;
884 /* Initialize all fields */
885 connection
->m_server
= false;
886 connection
->m_stream
= true;
888 /* Setup the peer address field */
889 connection
->m_peer
= GAddress_new();
890 if (!connection
->m_peer
)
893 m_error
= GSOCK_MEMERR
;
897 err
= _GAddress_translate_from(connection
->m_peer
, (sockaddr
*)&from
, fromlen
);
898 if (err
!= GSOCK_NOERROR
)
905 #if defined(__EMX__) || defined(__VISAGECPP__)
906 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
908 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
910 gs_gui_functions
->Enable_Events(connection
);
915 bool GSocket::SetReusable()
917 /* socket must not be null, and must not be in use/already bound */
918 if (this && m_fd
== INVALID_SOCKET
)
928 bool GSocket::SetBroadcast()
930 /* socket must not be in use/already bound */
931 if (m_fd
== INVALID_SOCKET
) {
938 bool GSocket::DontDoBind()
940 /* socket must not be in use/already bound */
941 if (m_fd
== INVALID_SOCKET
) {
948 /* Client specific parts */
951 * For stream (connection oriented) sockets, GSocket_Connect() tries
952 * to establish a client connection to a server using the peer address
953 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
954 * connection has been successfully established, or one of the error
955 * codes listed below. Note that for nonblocking sockets, a return
956 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
957 * request can be completed later; you should use GSocket_Select()
958 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
959 * corresponding asynchronous events.
961 * For datagram (non connection oriented) sockets, GSocket_Connect()
962 * just sets the peer address established with GSocket_SetPeer() as
963 * default destination.
966 * GSOCK_INVSOCK - the socket is in use or not valid.
967 * GSOCK_INVADDR - the peer address has not been established.
968 * GSOCK_TIMEDOUT - timeout, the connection failed.
969 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
970 * GSOCK_MEMERR - couldn't allocate memory.
971 * GSOCK_IOERR - low-level error.
973 GSocketError
GSocket::Connect(GSocketStream stream
)
980 /* Enable CONNECTION events (needed for nonblocking connections) */
981 Enable(GSOCK_CONNECTION
);
983 if (m_fd
!= INVALID_SOCKET
)
985 m_error
= GSOCK_INVSOCK
;
986 return GSOCK_INVSOCK
;
991 m_error
= GSOCK_INVADDR
;
992 return GSOCK_INVADDR
;
995 /* Streamed or dgram socket? */
996 m_stream
= (stream
== GSOCK_STREAMED
);
998 m_establishing
= false;
1000 /* Create the socket */
1001 m_fd
= socket(m_peer
->m_realfamily
,
1002 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
1004 if (m_fd
== INVALID_SOCKET
)
1006 m_error
= GSOCK_IOERR
;
1010 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
1012 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
1015 #if defined(__EMX__) || defined(__VISAGECPP__)
1016 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1018 ioctl(m_fd
, FIONBIO
, &arg
);
1021 // If the reuse flag is set, use the applicable socket reuse flags(s)
1024 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1026 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1030 if (m_initialRecvBufferSize
>= 0)
1031 setsockopt(m_fd
, SOL_SOCKET
, SO_RCVBUF
, (const char*)&m_initialRecvBufferSize
, sizeof(m_initialRecvBufferSize
));
1032 if (m_initialSendBufferSize
>= 0)
1033 setsockopt(m_fd
, SOL_SOCKET
, SO_SNDBUF
, (const char*)&m_initialSendBufferSize
, sizeof(m_initialSendBufferSize
));
1035 // If a local address has been set, then we need to bind to it before calling connect
1036 if (m_local
&& m_local
->m_addr
)
1038 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
1041 /* Connect it to the peer address, with a timeout (see below) */
1042 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
1044 /* We only call Enable_Events if we know we aren't shutting down the socket.
1045 * NB: Enable_Events needs to be called whether the socket is blocking or
1046 * non-blocking, it just shouldn't be called prior to knowing there is a
1047 * connection _if_ blocking sockets are being used.
1048 * If connect above returns 0, we are already connected and need to make the
1049 * call to Enable_Events now.
1052 if (m_non_blocking
|| ret
== 0)
1053 gs_gui_functions
->Enable_Events(this);
1059 /* If connect failed with EINPROGRESS and the GSocket object
1060 * is in blocking mode, we select() for the specified timeout
1061 * checking for writability to see if the connection request
1064 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
1066 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1069 /* m_error is set in _GSocket_Output_Timeout */
1070 return GSOCK_TIMEDOUT
;
1075 SOCKOPTLEN_T len
= sizeof(error
);
1077 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
1079 gs_gui_functions
->Enable_Events(this);
1082 return GSOCK_NOERROR
;
1086 /* If connect failed with EINPROGRESS and the GSocket object
1087 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1088 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1089 * this way if the connection completes, a GSOCK_CONNECTION
1090 * event will be generated, if enabled.
1092 if ((err
== EINPROGRESS
) && (m_non_blocking
))
1094 m_establishing
= true;
1095 m_error
= GSOCK_WOULDBLOCK
;
1096 return GSOCK_WOULDBLOCK
;
1099 /* If connect failed with an error other than EINPROGRESS,
1100 * then the call to GSocket_Connect has failed.
1103 m_error
= GSOCK_IOERR
;
1108 return GSOCK_NOERROR
;
1111 /* Datagram sockets */
1113 /* GSocket_SetNonOriented:
1114 * Sets up this socket as a non-connection oriented (datagram) socket.
1115 * Before using this function, the local address must have been set
1116 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1117 * on success, or one of the following otherwise.
1120 * GSOCK_INVSOCK - the socket is in use.
1121 * GSOCK_INVADDR - the local address has not been set.
1122 * GSOCK_IOERR - low-level error.
1124 GSocketError
GSocket::SetNonOriented()
1130 if (m_fd
!= INVALID_SOCKET
)
1132 m_error
= GSOCK_INVSOCK
;
1133 return GSOCK_INVSOCK
;
1138 m_error
= GSOCK_INVADDR
;
1139 return GSOCK_INVADDR
;
1142 /* Initialize all fields */
1146 /* Create the socket */
1147 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
1149 if (m_fd
== INVALID_SOCKET
)
1151 m_error
= GSOCK_IOERR
;
1154 #if defined(__EMX__) || defined(__VISAGECPP__)
1155 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1157 ioctl(m_fd
, FIONBIO
, &arg
);
1159 gs_gui_functions
->Enable_Events(this);
1163 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1165 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1171 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
1175 /* Bind to the local address,
1176 * and retrieve the actual address bound.
1178 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
1181 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
1184 m_error
= GSOCK_IOERR
;
1188 return GSOCK_NOERROR
;
1193 /* Like recv(), send(), ... */
1194 int GSocket::Read(char *buffer
, int size
)
1200 if (m_fd
== INVALID_SOCKET
|| m_server
)
1202 m_error
= GSOCK_INVSOCK
;
1206 /* Disable events during query of socket status */
1207 Disable(GSOCK_INPUT
);
1209 /* If the socket is blocking, wait for data (with a timeout) */
1210 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
1211 m_error
= GSOCK_TIMEDOUT
;
1212 /* Don't return here immediately, otherwise socket events would not be
1220 ret
= Recv_Stream(buffer
, size
);
1222 ret
= Recv_Dgram(buffer
, size
);
1224 /* If recv returned zero, then the connection has been gracefully closed.
1225 * Otherwise, recv has returned an error (-1), in which case we have lost the
1226 * socket only if errno does _not_ indicate that there may be more data to read.
1230 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1231 m_detected
= GSOCK_LOST_FLAG
;
1237 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1238 m_error
= GSOCK_WOULDBLOCK
;
1240 m_error
= GSOCK_IOERR
;
1244 /* Enable events again now that we are done processing */
1245 Enable(GSOCK_INPUT
);
1250 int GSocket::Write(const char *buffer
, int size
)
1256 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1258 if (m_fd
== INVALID_SOCKET
|| m_server
)
1260 m_error
= GSOCK_INVSOCK
;
1264 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1266 /* If the socket is blocking, wait for writability (with a timeout) */
1267 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1270 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1272 /* Write the data */
1274 ret
= Send_Stream(buffer
, size
);
1276 ret
= Send_Dgram(buffer
, size
);
1278 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1282 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1284 m_error
= GSOCK_WOULDBLOCK
;
1285 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1289 m_error
= GSOCK_IOERR
;
1290 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1293 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1294 * in MSW). Once the first OUTPUT event is received, users can assume
1295 * that the socket is writable until a read operation fails. Only then
1296 * will further OUTPUT events be posted.
1298 Enable(GSOCK_OUTPUT
);
1303 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1309 * Polls the socket to determine its status. This function will
1310 * check for the events specified in the 'flags' parameter, and
1311 * it will return a mask indicating which operations can be
1312 * performed. This function won't block, regardless of the
1313 * mode (blocking | nonblocking) of the socket.
1315 GSocketEventFlags
GSocket::Select(GSocketEventFlags flags
)
1317 if (!gs_gui_functions
->CanUseEventLoop())
1320 GSocketEventFlags result
= 0;
1329 return (GSOCK_LOST_FLAG
& flags
);
1331 /* Do not use a static struct, Linux can garble it */
1332 tv
.tv_sec
= m_timeout
/ 1000;
1333 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1335 wxFD_ZERO(&readfds
);
1336 wxFD_ZERO(&writefds
);
1337 wxFD_ZERO(&exceptfds
);
1338 wxFD_SET(m_fd
, &readfds
);
1339 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
1340 wxFD_SET(m_fd
, &writefds
);
1341 wxFD_SET(m_fd
, &exceptfds
);
1343 /* Check 'sticky' CONNECTION flag first */
1344 result
|= (GSOCK_CONNECTION_FLAG
& m_detected
);
1346 /* If we have already detected a LOST event, then don't try
1347 * to do any further processing.
1349 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1351 m_establishing
= false;
1353 return (GSOCK_LOST_FLAG
& flags
);
1356 /* Try select now */
1357 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) <= 0)
1359 /* What to do here? */
1360 return (result
& flags
);
1363 /* Check for exceptions and errors */
1364 if (wxFD_ISSET(m_fd
, &exceptfds
))
1366 m_establishing
= false;
1367 m_detected
= GSOCK_LOST_FLAG
;
1369 /* LOST event: Abort any further processing */
1370 return (GSOCK_LOST_FLAG
& flags
);
1373 /* Check for readability */
1374 if (wxFD_ISSET(m_fd
, &readfds
))
1376 result
|= GSOCK_INPUT_FLAG
;
1378 if (m_server
&& m_stream
)
1380 /* This is a TCP server socket that detected a connection.
1381 While the INPUT_FLAG is also set, it doesn't matter on
1382 this kind of sockets, as we can only Accept() from them. */
1383 result
|= GSOCK_CONNECTION_FLAG
;
1384 m_detected
|= GSOCK_CONNECTION_FLAG
;
1388 /* Check for writability */
1389 if (wxFD_ISSET(m_fd
, &writefds
))
1391 if (m_establishing
&& !m_server
)
1394 SOCKOPTLEN_T len
= sizeof(error
);
1396 m_establishing
= false;
1398 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1402 m_detected
= GSOCK_LOST_FLAG
;
1404 /* LOST event: Abort any further processing */
1405 return (GSOCK_LOST_FLAG
& flags
);
1409 result
|= GSOCK_CONNECTION_FLAG
;
1410 m_detected
|= GSOCK_CONNECTION_FLAG
;
1415 result
|= GSOCK_OUTPUT_FLAG
;
1419 return (result
& flags
);
1425 return flags
& m_detected
;
1431 /* GSocket_SetNonBlocking:
1432 * Sets the socket to non-blocking mode. All IO calls will return
1435 void GSocket::SetNonBlocking(bool non_block
)
1439 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1441 m_non_blocking
= non_block
;
1444 /* GSocket_SetTimeout:
1445 * Sets the timeout for blocking calls. Time is expressed in
1448 void GSocket::SetTimeout(unsigned long millisec
)
1452 m_timeout
= millisec
;
1455 /* GSocket_GetError:
1456 * Returns the last error occurred for this socket. Note that successful
1457 * operations do not clear this back to GSOCK_NOERROR, so use it only
1460 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1470 * There is data to be read in the input buffer. If, after a read
1471 * operation, there is still data available, the callback function will
1474 * The socket is available for writing. That is, the next write call
1475 * won't block. This event is generated only once, when the connection is
1476 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1477 * when the output buffer empties again. This means that the app should
1478 * assume that it can write since the first OUTPUT event, and no more
1479 * OUTPUT events will be generated unless an error occurs.
1481 * Connection successfully established, for client sockets, or incoming
1482 * client connection, for server sockets. Wait for this event (also watch
1483 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1485 * The connection is lost (or a connection request failed); this could
1486 * be due to a failure, or due to the peer closing it gracefully.
1489 /* GSocket_SetCallback:
1490 * Enables the callbacks specified by 'flags'. Note that 'flags'
1491 * may be a combination of flags OR'ed toghether, so the same
1492 * callback function can be made to accept different events.
1493 * The callback function must have the following prototype:
1495 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1497 void GSocket::SetCallback(GSocketEventFlags flags
,
1498 GSocketCallback callback
, char *cdata
)
1504 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1506 if ((flags
& (1 << count
)) != 0)
1508 m_cbacks
[count
] = callback
;
1509 m_data
[count
] = cdata
;
1514 /* GSocket_UnsetCallback:
1515 * Disables all callbacks specified by 'flags', which may be a
1516 * combination of flags OR'ed toghether.
1518 void GSocket::UnsetCallback(GSocketEventFlags flags
)
1524 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1526 if ((flags
& (1 << count
)) != 0)
1528 m_cbacks
[count
] = NULL
;
1529 m_data
[count
] = NULL
;
1534 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1535 void *optval
, int *optlen
)
1537 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1538 return GSOCK_NOERROR
;
1540 return GSOCK_OPTERR
;
1543 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1544 const void *optval
, int optlen
)
1546 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1547 return GSOCK_NOERROR
;
1549 return GSOCK_OPTERR
;
1552 #define CALL_CALLBACK(socket, event) { \
1553 socket->Disable(event); \
1554 if (socket->m_cbacks[event]) \
1555 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1559 void GSocket::Enable(GSocketEvent event
)
1561 m_detected
&= ~(1 << event
);
1562 gs_gui_functions
->Install_Callback(this, event
);
1565 void GSocket::Disable(GSocketEvent event
)
1567 m_detected
|= (1 << event
);
1568 gs_gui_functions
->Uninstall_Callback(this, event
);
1571 /* _GSocket_Input_Timeout:
1572 * For blocking sockets, wait until data is available or
1573 * until timeout ellapses.
1575 GSocketError
GSocket::Input_Timeout()
1581 /* Linux select() will overwrite the struct on return */
1582 tv
.tv_sec
= (m_timeout
/ 1000);
1583 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1585 if (!m_non_blocking
)
1587 wxFD_ZERO(&readfds
);
1588 wxFD_SET(m_fd
, &readfds
);
1589 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1592 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1593 m_error
= GSOCK_TIMEDOUT
;
1594 return GSOCK_TIMEDOUT
;
1599 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1600 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1601 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1602 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1603 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1604 m_error
= GSOCK_TIMEDOUT
;
1605 return GSOCK_TIMEDOUT
;
1609 return GSOCK_NOERROR
;
1612 /* _GSocket_Output_Timeout:
1613 * For blocking sockets, wait until data can be sent without
1614 * blocking or until timeout ellapses.
1616 GSocketError
GSocket::Output_Timeout()
1622 /* Linux select() will overwrite the struct on return */
1623 tv
.tv_sec
= (m_timeout
/ 1000);
1624 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1626 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1628 if (!m_non_blocking
)
1630 wxFD_ZERO(&writefds
);
1631 wxFD_SET(m_fd
, &writefds
);
1632 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1635 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1636 m_error
= GSOCK_TIMEDOUT
;
1637 return GSOCK_TIMEDOUT
;
1642 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1643 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1644 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1645 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1646 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1647 m_error
= GSOCK_TIMEDOUT
;
1648 return GSOCK_TIMEDOUT
;
1651 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1653 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1657 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1662 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1665 return GSOCK_NOERROR
;
1668 int GSocket::Recv_Stream(char *buffer
, int size
)
1673 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1675 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1680 int GSocket::Recv_Dgram(char *buffer
, int size
)
1683 WX_SOCKLEN_T fromlen
= sizeof(from
);
1687 fromlen
= sizeof(from
);
1691 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1693 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1698 /* Translate a system address into a GSocket address */
1701 m_peer
= GAddress_new();
1704 m_error
= GSOCK_MEMERR
;
1709 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1710 if (err
!= GSOCK_NOERROR
)
1712 GAddress_destroy(m_peer
);
1721 int GSocket::Send_Stream(const char *buffer
, int size
)
1729 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1731 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1738 int GSocket::Send_Dgram(const char *buffer
, int size
)
1740 struct sockaddr
*addr
;
1746 m_error
= GSOCK_INVADDR
;
1750 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1751 if (err
!= GSOCK_NOERROR
)
1761 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1763 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1767 /* Frees memory allocated from _GAddress_translate_to */
1773 void GSocket::Detected_Read()
1777 /* Safeguard against straggling call to Detected_Read */
1778 if (m_fd
== INVALID_SOCKET
)
1783 /* If we have already detected a LOST event, then don't try
1784 * to do any further processing.
1786 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1788 m_establishing
= false;
1790 CALL_CALLBACK(this, GSOCK_LOST
);
1795 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1799 CALL_CALLBACK(this, GSOCK_INPUT
);
1803 if (m_server
&& m_stream
)
1805 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1809 /* graceful shutdown */
1810 CALL_CALLBACK(this, GSOCK_LOST
);
1815 /* Do not throw a lost event in cases where the socket isn't really lost */
1816 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1818 CALL_CALLBACK(this, GSOCK_INPUT
);
1822 CALL_CALLBACK(this, GSOCK_LOST
);
1829 void GSocket::Detected_Write()
1831 /* If we have already detected a LOST event, then don't try
1832 * to do any further processing.
1834 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1836 m_establishing
= false;
1838 CALL_CALLBACK(this, GSOCK_LOST
);
1843 if (m_establishing
&& !m_server
)
1846 SOCKOPTLEN_T len
= sizeof(error
);
1848 m_establishing
= false;
1850 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1854 CALL_CALLBACK(this, GSOCK_LOST
);
1859 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1860 /* We have to fire this event by hand because CONNECTION (for clients)
1861 * and OUTPUT are internally the same and we just disabled CONNECTION
1862 * events with the above macro.
1864 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1869 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1873 /* Compatibility functions for GSocket */
1874 GSocket
*GSocket_new(void)
1876 GSocket
*newsocket
= new GSocket();
1877 if (newsocket
->IsOk())
1886 * -------------------------------------------------------------------------
1888 * -------------------------------------------------------------------------
1891 /* CHECK_ADDRESS verifies that the current address family is either
1892 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1893 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1894 * an appropiate error code.
1896 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1898 #define CHECK_ADDRESS(address, family) \
1900 if (address->m_family == GSOCK_NOFAMILY) \
1901 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1902 return address->m_error; \
1903 if (address->m_family != GSOCK_##family) \
1905 address->m_error = GSOCK_INVADDR; \
1906 return GSOCK_INVADDR; \
1910 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1912 if (address->m_family == GSOCK_NOFAMILY) \
1913 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1915 if (address->m_family != GSOCK_##family) \
1917 address->m_error = GSOCK_INVADDR; \
1923 GAddress
*GAddress_new(void)
1927 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1930 address
->m_family
= GSOCK_NOFAMILY
;
1931 address
->m_addr
= NULL
;
1937 GAddress
*GAddress_copy(GAddress
*address
)
1941 assert(address
!= NULL
);
1943 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1946 memcpy(addr2
, address
, sizeof(GAddress
));
1948 if (address
->m_addr
&& address
->m_len
> 0)
1950 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1951 if (addr2
->m_addr
== NULL
)
1956 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1962 void GAddress_destroy(GAddress
*address
)
1964 assert(address
!= NULL
);
1966 if (address
->m_addr
)
1967 free(address
->m_addr
);
1972 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1974 assert(address
!= NULL
);
1976 address
->m_family
= type
;
1979 GAddressType
GAddress_GetFamily(GAddress
*address
)
1981 assert(address
!= NULL
);
1983 return address
->m_family
;
1986 GSocketError
_GAddress_translate_from(GAddress
*address
,
1987 struct sockaddr
*addr
, int len
)
1989 address
->m_realfamily
= addr
->sa_family
;
1990 switch (addr
->sa_family
)
1993 address
->m_family
= GSOCK_INET
;
1996 address
->m_family
= GSOCK_UNIX
;
2000 address
->m_family
= GSOCK_INET6
;
2002 #endif // wxUSE_IPV6
2005 address
->m_error
= GSOCK_INVOP
;
2010 if (address
->m_addr
)
2011 free(address
->m_addr
);
2013 address
->m_len
= len
;
2014 address
->m_addr
= (struct sockaddr
*)malloc(len
);
2016 if (address
->m_addr
== NULL
)
2018 address
->m_error
= GSOCK_MEMERR
;
2019 return GSOCK_MEMERR
;
2022 memcpy(address
->m_addr
, addr
, len
);
2024 return GSOCK_NOERROR
;
2027 GSocketError
_GAddress_translate_to(GAddress
*address
,
2028 struct sockaddr
**addr
, int *len
)
2030 if (!address
->m_addr
)
2032 address
->m_error
= GSOCK_INVADDR
;
2033 return GSOCK_INVADDR
;
2036 *len
= address
->m_len
;
2037 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
2040 address
->m_error
= GSOCK_MEMERR
;
2041 return GSOCK_MEMERR
;
2044 memcpy(*addr
, address
->m_addr
, address
->m_len
);
2045 return GSOCK_NOERROR
;
2049 * -------------------------------------------------------------------------
2050 * Internet address family
2051 * -------------------------------------------------------------------------
2054 GSocketError
_GAddress_Init_INET(GAddress
*address
)
2056 address
->m_len
= sizeof(struct sockaddr_in
);
2057 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2058 if (address
->m_addr
== NULL
)
2060 address
->m_error
= GSOCK_MEMERR
;
2061 return GSOCK_MEMERR
;
2064 address
->m_family
= GSOCK_INET
;
2065 address
->m_realfamily
= PF_INET
;
2066 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
2067 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
2069 return GSOCK_NOERROR
;
2072 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
2075 struct in_addr
*addr
;
2077 assert(address
!= NULL
);
2079 CHECK_ADDRESS(address
, INET
);
2081 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2083 /* If it is a numeric host name, convert it now */
2084 #if defined(HAVE_INET_ATON)
2085 if (inet_aton(hostname
, addr
) == 0)
2087 #elif defined(HAVE_INET_ADDR)
2088 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
2091 /* Use gethostbyname by default */
2093 int val
= 1; /* VA doesn't like constants in conditional expressions */
2098 struct in_addr
*array_addr
;
2100 /* It is a real name, we solve it */
2102 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2103 struct hostent_data buffer
;
2108 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
2111 /* Reset to invalid address */
2112 addr
->s_addr
= INADDR_NONE
;
2113 address
->m_error
= GSOCK_NOHOST
;
2114 return GSOCK_NOHOST
;
2117 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
2118 addr
->s_addr
= array_addr
[0].s_addr
;
2121 return GSOCK_NOERROR
;
2125 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
2127 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
2130 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
2132 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
2135 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
2136 unsigned long hostaddr
)
2138 struct in_addr
*addr
;
2140 assert(address
!= NULL
);
2142 CHECK_ADDRESS(address
, INET
);
2144 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2145 addr
->s_addr
= htonl(hostaddr
);
2147 return GSOCK_NOERROR
;
2150 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
2151 const char *protocol
)
2154 struct sockaddr_in
*addr
;
2156 assert(address
!= NULL
);
2157 CHECK_ADDRESS(address
, INET
);
2161 address
->m_error
= GSOCK_INVPORT
;
2162 return GSOCK_INVPORT
;
2165 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2166 struct servent_data buffer
;
2170 struct servent serv
;
2171 se
= wxGetservbyname_r(port
, protocol
, &serv
,
2172 (void*)&buffer
, sizeof(buffer
));
2175 /* the cast to int suppresses compiler warnings about subscript having the
2177 if (isdigit((int)port
[0]))
2181 port_int
= atoi(port
);
2182 addr
= (struct sockaddr_in
*)address
->m_addr
;
2183 addr
->sin_port
= htons(port_int
);
2184 return GSOCK_NOERROR
;
2187 address
->m_error
= GSOCK_INVPORT
;
2188 return GSOCK_INVPORT
;
2191 addr
= (struct sockaddr_in
*)address
->m_addr
;
2192 addr
->sin_port
= se
->s_port
;
2194 return GSOCK_NOERROR
;
2197 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
2199 struct sockaddr_in
*addr
;
2201 assert(address
!= NULL
);
2202 CHECK_ADDRESS(address
, INET
);
2204 addr
= (struct sockaddr_in
*)address
->m_addr
;
2205 addr
->sin_port
= htons(port
);
2207 return GSOCK_NOERROR
;
2210 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2214 struct sockaddr_in
*addr
;
2216 assert(address
!= NULL
);
2217 CHECK_ADDRESS(address
, INET
);
2219 addr
= (struct sockaddr_in
*)address
->m_addr
;
2220 addr_buf
= (char *)&(addr
->sin_addr
);
2222 struct hostent temphost
;
2223 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2224 struct hostent_data buffer
;
2229 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
2230 (void*)&buffer
, sizeof(buffer
), &err
);
2233 address
->m_error
= GSOCK_NOHOST
;
2234 return GSOCK_NOHOST
;
2237 strncpy(hostname
, he
->h_name
, sbuf
);
2239 return GSOCK_NOERROR
;
2242 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
2244 struct sockaddr_in
*addr
;
2246 assert(address
!= NULL
);
2247 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2249 addr
= (struct sockaddr_in
*)address
->m_addr
;
2251 return ntohl(addr
->sin_addr
.s_addr
);
2254 unsigned short GAddress_INET_GetPort(GAddress
*address
)
2256 struct sockaddr_in
*addr
;
2258 assert(address
!= NULL
);
2259 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2261 addr
= (struct sockaddr_in
*)address
->m_addr
;
2262 return ntohs(addr
->sin_port
);
2267 * -------------------------------------------------------------------------
2268 * Internet IPv6 address family
2269 * -------------------------------------------------------------------------
2272 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
2274 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
2275 address
->m_len
= sizeof(struct sockaddr_in6
);
2276 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2277 if (address
->m_addr
== NULL
)
2279 address
->m_error
= GSOCK_MEMERR
;
2280 return GSOCK_MEMERR
;
2282 memset(address
->m_addr
,0,address
->m_len
);
2284 address
->m_family
= GSOCK_INET6
;
2285 address
->m_realfamily
= AF_INET6
;
2286 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
2287 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
2289 return GSOCK_NOERROR
;
2292 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
2294 assert(address
!= NULL
);
2295 CHECK_ADDRESS(address
, INET6
);
2298 memset( & hints
, 0, sizeof( hints
) );
2299 hints
.ai_family
= AF_INET6
;
2300 addrinfo
* info
= 0;
2301 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
2303 address
->m_error
= GSOCK_NOHOST
;
2304 return GSOCK_NOHOST
;
2307 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
2308 freeaddrinfo( info
);
2309 return GSOCK_NOERROR
;
2312 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
2314 assert(address
!= NULL
);
2316 CHECK_ADDRESS(address
, INET6
);
2318 struct in6_addr addr
;
2319 memset( & addr
, 0, sizeof( addr
) );
2320 return GAddress_INET6_SetHostAddress(address
, addr
);
2322 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
2323 struct in6_addr hostaddr
)
2325 assert(address
!= NULL
);
2327 CHECK_ADDRESS(address
, INET6
);
2329 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
2331 return GSOCK_NOERROR
;
2334 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
2335 const char *protocol
)
2338 struct sockaddr_in6
*addr
;
2340 assert(address
!= NULL
);
2341 CHECK_ADDRESS(address
, INET6
);
2345 address
->m_error
= GSOCK_INVPORT
;
2346 return GSOCK_INVPORT
;
2349 se
= getservbyname(port
, protocol
);
2352 if (isdigit(port
[0]))
2356 port_int
= atoi(port
);
2357 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2358 addr
->sin6_port
= htons((u_short
) port_int
);
2359 return GSOCK_NOERROR
;
2362 address
->m_error
= GSOCK_INVPORT
;
2363 return GSOCK_INVPORT
;
2366 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2367 addr
->sin6_port
= se
->s_port
;
2369 return GSOCK_NOERROR
;
2372 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
2374 struct sockaddr_in6
*addr
;
2376 assert(address
!= NULL
);
2377 CHECK_ADDRESS(address
, INET6
);
2379 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2380 addr
->sin6_port
= htons(port
);
2382 return GSOCK_NOERROR
;
2385 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2389 struct sockaddr_in6
*addr
;
2391 assert(address
!= NULL
);
2392 CHECK_ADDRESS(address
, INET6
);
2394 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2395 addr_buf
= (char *)&(addr
->sin6_addr
);
2397 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
2400 address
->m_error
= GSOCK_NOHOST
;
2401 return GSOCK_NOHOST
;
2404 strncpy(hostname
, he
->h_name
, sbuf
);
2406 return GSOCK_NOERROR
;
2409 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
2411 assert(address
!= NULL
);
2412 assert(hostaddr
!= NULL
);
2413 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
2414 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
2415 return GSOCK_NOERROR
;
2418 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2420 assert(address
!= NULL
);
2421 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2423 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2426 #endif // wxUSE_IPV6
2429 * -------------------------------------------------------------------------
2430 * Unix address family
2431 * -------------------------------------------------------------------------
2434 #ifndef __VISAGECPP__
2435 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2437 address
->m_len
= sizeof(struct sockaddr_un
);
2438 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2439 if (address
->m_addr
== NULL
)
2441 address
->m_error
= GSOCK_MEMERR
;
2442 return GSOCK_MEMERR
;
2445 address
->m_family
= GSOCK_UNIX
;
2446 address
->m_realfamily
= PF_UNIX
;
2447 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2448 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2450 return GSOCK_NOERROR
;
2453 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2455 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2457 struct sockaddr_un
*addr
;
2459 assert(address
!= NULL
);
2461 CHECK_ADDRESS(address
, UNIX
);
2463 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2464 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2465 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2467 return GSOCK_NOERROR
;
2470 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2472 struct sockaddr_un
*addr
;
2474 assert(address
!= NULL
);
2475 CHECK_ADDRESS(address
, UNIX
);
2477 addr
= (struct sockaddr_un
*)address
->m_addr
;
2479 strncpy(path
, addr
->sun_path
, sbuf
);
2481 return GSOCK_NOERROR
;
2483 #endif /* !defined(__VISAGECPP__) */
2484 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */