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__ */
453 /* Table of GUI-related functions. We must call them indirectly because
454 * of wxBase and GUI separation: */
456 static GSocketGUIFunctionsTable
*gs_gui_functions
;
458 class GSocketGUIFunctionsTableNull
: public GSocketGUIFunctionsTable
461 virtual bool OnInit();
462 virtual void OnExit();
463 virtual bool CanUseEventLoop();
464 virtual bool Init_Socket(GSocket
*socket
);
465 virtual void Destroy_Socket(GSocket
*socket
);
466 virtual void Install_Callback(GSocket
*socket
, GSocketEvent event
);
467 virtual void Uninstall_Callback(GSocket
*socket
, GSocketEvent event
);
468 virtual void Enable_Events(GSocket
*socket
);
469 virtual void Disable_Events(GSocket
*socket
);
472 bool GSocketGUIFunctionsTableNull::OnInit()
474 void GSocketGUIFunctionsTableNull::OnExit()
476 bool GSocketGUIFunctionsTableNull::CanUseEventLoop()
478 bool GSocketGUIFunctionsTableNull::Init_Socket(GSocket
*WXUNUSED(socket
))
480 void GSocketGUIFunctionsTableNull::Destroy_Socket(GSocket
*WXUNUSED(socket
))
482 void GSocketGUIFunctionsTableNull::Install_Callback(GSocket
*WXUNUSED(socket
), GSocketEvent
WXUNUSED(event
))
484 void GSocketGUIFunctionsTableNull::Uninstall_Callback(GSocket
*WXUNUSED(socket
), GSocketEvent
WXUNUSED(event
))
486 void GSocketGUIFunctionsTableNull::Enable_Events(GSocket
*WXUNUSED(socket
))
488 void GSocketGUIFunctionsTableNull::Disable_Events(GSocket
*WXUNUSED(socket
))
490 /* Global initialisers */
492 void GSocket_SetGUIFunctions(GSocketGUIFunctionsTable
*guifunc
)
494 gs_gui_functions
= guifunc
;
497 int GSocket_Init(void)
499 if (!gs_gui_functions
)
501 static GSocketGUIFunctionsTableNull table
;
502 gs_gui_functions
= &table
;
504 if ( !gs_gui_functions
->OnInit() )
509 void GSocket_Cleanup(void)
511 if (gs_gui_functions
)
513 gs_gui_functions
->OnExit();
517 /* Constructors / Destructors for GSocket */
523 m_fd
= INVALID_SOCKET
;
526 for (i
=0;i
<GSOCK_MAX_EVENT
;i
++)
533 m_error
= GSOCK_NOERROR
;
536 m_gui_dependent
= NULL
;
537 m_non_blocking
= false;
541 m_timeout
= 10*60*1000;
542 /* 10 minutes * 60 sec * 1000 millisec */
543 m_establishing
= false;
544 m_initialRecvBufferSize
= -1;
545 m_initialSendBufferSize
= -1;
547 assert(gs_gui_functions
);
548 /* Per-socket GUI-specific initialization */
549 m_ok
= gs_gui_functions
->Init_Socket(this);
552 void GSocket::Close()
554 gs_gui_functions
->Disable_Events(this);
556 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
557 will close the socket during Disable_Events. However, it will only do this
558 if it is being used. That is, it won't do it in a console program. To
559 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
560 if it has closed the socket which indicates to us (at runtime, instead of
561 at compile time as this had been before) that the socket has already
564 if(m_fd
!= INVALID_SOCKET
)
566 m_fd
= INVALID_SOCKET
;
573 /* Check that the socket is really shutdowned */
574 if (m_fd
!= INVALID_SOCKET
)
577 /* Per-socket GUI-specific cleanup */
578 gs_gui_functions
->Destroy_Socket(this);
582 /* Destroy private addresses */
584 GAddress_destroy(m_local
);
587 GAddress_destroy(m_peer
);
591 * Disallow further read/write operations on this socket, close
592 * the fd and disable all callbacks.
594 void GSocket::Shutdown()
600 /* Don't allow events to fire after socket has been closed */
601 gs_gui_functions
->Disable_Events(this);
603 /* If socket has been created, shutdown it */
604 if (m_fd
!= INVALID_SOCKET
)
610 /* Disable GUI callbacks */
611 for (evt
= 0; evt
< GSOCK_MAX_EVENT
; evt
++)
612 m_cbacks
[evt
] = NULL
;
614 m_detected
= GSOCK_LOST_FLAG
;
617 /* Address handling */
623 * Set or get the local or peer address for this socket. The 'set'
624 * functions return GSOCK_NOERROR on success, an error code otherwise.
625 * The 'get' functions return a pointer to a GAddress object on success,
626 * or NULL otherwise, in which case they set the error code of the
627 * corresponding GSocket.
630 * GSOCK_INVSOCK - the socket is not valid.
631 * GSOCK_INVADDR - the address is not valid.
633 GSocketError
GSocket::SetLocal(GAddress
*address
)
637 /* the socket must be initialized, or it must be a server */
638 if ((m_fd
!= INVALID_SOCKET
&& !m_server
))
640 m_error
= GSOCK_INVSOCK
;
641 return GSOCK_INVSOCK
;
645 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
647 m_error
= GSOCK_INVADDR
;
648 return GSOCK_INVADDR
;
652 GAddress_destroy(m_local
);
654 m_local
= GAddress_copy(address
);
656 return GSOCK_NOERROR
;
659 GSocketError
GSocket::SetPeer(GAddress
*address
)
664 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
666 m_error
= GSOCK_INVADDR
;
667 return GSOCK_INVADDR
;
671 GAddress_destroy(m_peer
);
673 m_peer
= GAddress_copy(address
);
675 return GSOCK_NOERROR
;
678 GAddress
*GSocket::GetLocal()
681 struct sockaddr addr
;
682 WX_SOCKLEN_T size
= sizeof(addr
);
687 /* try to get it from the m_local var first */
689 return GAddress_copy(m_local
);
691 /* else, if the socket is initialized, try getsockname */
692 if (m_fd
== INVALID_SOCKET
)
694 m_error
= GSOCK_INVSOCK
;
698 if (getsockname(m_fd
, &addr
, (WX_SOCKLEN_T
*) &size
) < 0)
700 m_error
= GSOCK_IOERR
;
704 /* got a valid address from getsockname, create a GAddress object */
705 address
= GAddress_new();
708 m_error
= GSOCK_MEMERR
;
712 err
= _GAddress_translate_from(address
, &addr
, size
);
713 if (err
!= GSOCK_NOERROR
)
715 GAddress_destroy(address
);
723 GAddress
*GSocket::GetPeer()
727 /* try to get it from the m_peer var */
729 return GAddress_copy(m_peer
);
734 /* Server specific parts */
736 /* GSocket_SetServer:
737 * Sets up this socket as a server. The local address must have been
738 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
739 * Returns GSOCK_NOERROR on success, one of the following otherwise:
742 * GSOCK_INVSOCK - the socket is in use.
743 * GSOCK_INVADDR - the local address has not been set.
744 * GSOCK_IOERR - low-level error.
746 GSocketError
GSocket::SetServer()
752 /* must not be in use */
753 if (m_fd
!= INVALID_SOCKET
)
755 m_error
= GSOCK_INVSOCK
;
756 return GSOCK_INVSOCK
;
759 /* the local addr must have been set */
762 m_error
= GSOCK_INVADDR
;
763 return GSOCK_INVADDR
;
766 /* Initialize all fields */
770 /* Create the socket */
771 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
773 if (m_fd
== INVALID_SOCKET
)
775 m_error
= GSOCK_IOERR
;
779 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
781 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
784 ioctl(m_fd
, FIONBIO
, &arg
);
785 gs_gui_functions
->Enable_Events(this);
787 /* allow a socket to re-bind if the socket is in the TIME_WAIT
788 state after being previously closed.
792 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
794 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
798 /* Bind to the local address,
799 * retrieve the actual address bound,
800 * and listen up to 5 connections.
802 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
805 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
806 (listen(m_fd
, 5) != 0))
809 m_error
= GSOCK_IOERR
;
813 return GSOCK_NOERROR
;
816 /* GSocket_WaitConnection:
817 * Waits for an incoming client connection. Returns a pointer to
818 * a GSocket object, or NULL if there was an error, in which case
819 * the last error field will be updated for the calling GSocket.
821 * Error codes (set in the calling GSocket)
822 * GSOCK_INVSOCK - the socket is not valid or not a server.
823 * GSOCK_TIMEDOUT - timeout, no incoming connections.
824 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
825 * GSOCK_MEMERR - couldn't allocate memory.
826 * GSOCK_IOERR - low-level error.
828 GSocket
*GSocket::WaitConnection()
830 struct sockaddr from
;
831 WX_SOCKLEN_T fromlen
= sizeof(from
);
838 /* If the socket has already been created, we exit immediately */
839 if (m_fd
== INVALID_SOCKET
|| !m_server
)
841 m_error
= GSOCK_INVSOCK
;
845 /* Create a GSocket object for the new connection */
846 connection
= GSocket_new();
850 m_error
= GSOCK_MEMERR
;
854 /* Wait for a connection (with timeout) */
855 if (Input_Timeout() == GSOCK_TIMEDOUT
)
858 /* m_error set by _GSocket_Input_Timeout */
862 connection
->m_fd
= accept(m_fd
, &from
, (WX_SOCKLEN_T
*) &fromlen
);
864 /* Reenable CONNECTION events */
865 Enable(GSOCK_CONNECTION
);
867 if (connection
->m_fd
== INVALID_SOCKET
)
869 if (errno
== EWOULDBLOCK
)
870 m_error
= GSOCK_WOULDBLOCK
;
872 m_error
= GSOCK_IOERR
;
878 /* Initialize all fields */
879 connection
->m_server
= false;
880 connection
->m_stream
= true;
882 /* Setup the peer address field */
883 connection
->m_peer
= GAddress_new();
884 if (!connection
->m_peer
)
887 m_error
= GSOCK_MEMERR
;
891 err
= _GAddress_translate_from(connection
->m_peer
, &from
, fromlen
);
892 if (err
!= GSOCK_NOERROR
)
899 #if defined(__EMX__) || defined(__VISAGECPP__)
900 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
902 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
904 gs_gui_functions
->Enable_Events(connection
);
909 bool GSocket::SetReusable()
911 /* socket must not be null, and must not be in use/already bound */
912 if (this && m_fd
== INVALID_SOCKET
)
922 bool GSocket::SetBroadcast()
924 /* socket must not be in use/already bound */
925 if (m_fd
== INVALID_SOCKET
) {
932 bool GSocket::DontDoBind()
934 /* socket must not be in use/already bound */
935 if (m_fd
== INVALID_SOCKET
) {
942 /* Client specific parts */
945 * For stream (connection oriented) sockets, GSocket_Connect() tries
946 * to establish a client connection to a server using the peer address
947 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
948 * connection has been successfully established, or one of the error
949 * codes listed below. Note that for nonblocking sockets, a return
950 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
951 * request can be completed later; you should use GSocket_Select()
952 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
953 * corresponding asynchronous events.
955 * For datagram (non connection oriented) sockets, GSocket_Connect()
956 * just sets the peer address established with GSocket_SetPeer() as
957 * default destination.
960 * GSOCK_INVSOCK - the socket is in use or not valid.
961 * GSOCK_INVADDR - the peer address has not been established.
962 * GSOCK_TIMEDOUT - timeout, the connection failed.
963 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
964 * GSOCK_MEMERR - couldn't allocate memory.
965 * GSOCK_IOERR - low-level error.
967 GSocketError
GSocket::Connect(GSocketStream stream
)
974 /* Enable CONNECTION events (needed for nonblocking connections) */
975 Enable(GSOCK_CONNECTION
);
977 if (m_fd
!= INVALID_SOCKET
)
979 m_error
= GSOCK_INVSOCK
;
980 return GSOCK_INVSOCK
;
985 m_error
= GSOCK_INVADDR
;
986 return GSOCK_INVADDR
;
989 /* Streamed or dgram socket? */
990 m_stream
= (stream
== GSOCK_STREAMED
);
992 m_establishing
= false;
994 /* Create the socket */
995 m_fd
= socket(m_peer
->m_realfamily
,
996 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
998 if (m_fd
== INVALID_SOCKET
)
1000 m_error
= GSOCK_IOERR
;
1004 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
1006 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
1009 #if defined(__EMX__) || defined(__VISAGECPP__)
1010 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1012 ioctl(m_fd
, FIONBIO
, &arg
);
1015 // If the reuse flag is set, use the applicable socket reuse flags(s)
1018 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1020 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1024 if (m_initialRecvBufferSize
>= 0)
1025 setsockopt(m_fd
, SOL_SOCKET
, SO_RCVBUF
, (const char*)&m_initialRecvBufferSize
, sizeof(m_initialRecvBufferSize
));
1026 if (m_initialSendBufferSize
>= 0)
1027 setsockopt(m_fd
, SOL_SOCKET
, SO_SNDBUF
, (const char*)&m_initialSendBufferSize
, sizeof(m_initialSendBufferSize
));
1029 // If a local address has been set, then we need to bind to it before calling connect
1030 if (m_local
&& m_local
->m_addr
)
1032 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
1035 /* Connect it to the peer address, with a timeout (see below) */
1036 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
1038 /* We only call Enable_Events if we know we aren't shutting down the socket.
1039 * NB: Enable_Events needs to be called whether the socket is blocking or
1040 * non-blocking, it just shouldn't be called prior to knowing there is a
1041 * connection _if_ blocking sockets are being used.
1042 * If connect above returns 0, we are already connected and need to make the
1043 * call to Enable_Events now.
1046 if (m_non_blocking
|| ret
== 0)
1047 gs_gui_functions
->Enable_Events(this);
1053 /* If connect failed with EINPROGRESS and the GSocket object
1054 * is in blocking mode, we select() for the specified timeout
1055 * checking for writability to see if the connection request
1058 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
1060 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1063 /* m_error is set in _GSocket_Output_Timeout */
1064 return GSOCK_TIMEDOUT
;
1069 SOCKOPTLEN_T len
= sizeof(error
);
1071 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
1073 gs_gui_functions
->Enable_Events(this);
1076 return GSOCK_NOERROR
;
1080 /* If connect failed with EINPROGRESS and the GSocket object
1081 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1082 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1083 * this way if the connection completes, a GSOCK_CONNECTION
1084 * event will be generated, if enabled.
1086 if ((err
== EINPROGRESS
) && (m_non_blocking
))
1088 m_establishing
= true;
1089 m_error
= GSOCK_WOULDBLOCK
;
1090 return GSOCK_WOULDBLOCK
;
1093 /* If connect failed with an error other than EINPROGRESS,
1094 * then the call to GSocket_Connect has failed.
1097 m_error
= GSOCK_IOERR
;
1102 return GSOCK_NOERROR
;
1105 /* Datagram sockets */
1107 /* GSocket_SetNonOriented:
1108 * Sets up this socket as a non-connection oriented (datagram) socket.
1109 * Before using this function, the local address must have been set
1110 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1111 * on success, or one of the following otherwise.
1114 * GSOCK_INVSOCK - the socket is in use.
1115 * GSOCK_INVADDR - the local address has not been set.
1116 * GSOCK_IOERR - low-level error.
1118 GSocketError
GSocket::SetNonOriented()
1124 if (m_fd
!= INVALID_SOCKET
)
1126 m_error
= GSOCK_INVSOCK
;
1127 return GSOCK_INVSOCK
;
1132 m_error
= GSOCK_INVADDR
;
1133 return GSOCK_INVADDR
;
1136 /* Initialize all fields */
1140 /* Create the socket */
1141 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
1143 if (m_fd
== INVALID_SOCKET
)
1145 m_error
= GSOCK_IOERR
;
1148 #if defined(__EMX__) || defined(__VISAGECPP__)
1149 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1151 ioctl(m_fd
, FIONBIO
, &arg
);
1153 gs_gui_functions
->Enable_Events(this);
1157 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1159 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1165 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
1169 /* Bind to the local address,
1170 * and retrieve the actual address bound.
1172 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
1175 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
1178 m_error
= GSOCK_IOERR
;
1182 return GSOCK_NOERROR
;
1187 /* Like recv(), send(), ... */
1188 int GSocket::Read(char *buffer
, int size
)
1194 if (m_fd
== INVALID_SOCKET
|| m_server
)
1196 m_error
= GSOCK_INVSOCK
;
1200 /* Disable events during query of socket status */
1201 Disable(GSOCK_INPUT
);
1203 /* If the socket is blocking, wait for data (with a timeout) */
1204 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
1205 m_error
= GSOCK_TIMEDOUT
;
1206 /* Don't return here immediately, otherwise socket events would not be
1214 ret
= Recv_Stream(buffer
, size
);
1216 ret
= Recv_Dgram(buffer
, size
);
1218 /* If recv returned zero, then the connection has been gracefully closed.
1219 * Otherwise, recv has returned an error (-1), in which case we have lost the
1220 * socket only if errno does _not_ indicate that there may be more data to read.
1224 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1225 m_detected
= GSOCK_LOST_FLAG
;
1231 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1232 m_error
= GSOCK_WOULDBLOCK
;
1234 m_error
= GSOCK_IOERR
;
1238 /* Enable events again now that we are done processing */
1239 Enable(GSOCK_INPUT
);
1244 int GSocket::Write(const char *buffer
, int size
)
1250 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1252 if (m_fd
== INVALID_SOCKET
|| m_server
)
1254 m_error
= GSOCK_INVSOCK
;
1258 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1260 /* If the socket is blocking, wait for writability (with a timeout) */
1261 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1264 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1266 /* Write the data */
1268 ret
= Send_Stream(buffer
, size
);
1270 ret
= Send_Dgram(buffer
, size
);
1272 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1276 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1278 m_error
= GSOCK_WOULDBLOCK
;
1279 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1283 m_error
= GSOCK_IOERR
;
1284 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1287 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1288 * in MSW). Once the first OUTPUT event is received, users can assume
1289 * that the socket is writable until a read operation fails. Only then
1290 * will further OUTPUT events be posted.
1292 Enable(GSOCK_OUTPUT
);
1297 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1303 * Polls the socket to determine its status. This function will
1304 * check for the events specified in the 'flags' parameter, and
1305 * it will return a mask indicating which operations can be
1306 * performed. This function won't block, regardless of the
1307 * mode (blocking | nonblocking) of the socket.
1309 GSocketEventFlags
GSocket::Select(GSocketEventFlags flags
)
1311 if (!gs_gui_functions
->CanUseEventLoop())
1314 GSocketEventFlags result
= 0;
1323 return (GSOCK_LOST_FLAG
& flags
);
1325 /* Do not use a static struct, Linux can garble it */
1326 tv
.tv_sec
= m_timeout
/ 1000;
1327 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1329 wxFD_ZERO(&readfds
);
1330 wxFD_ZERO(&writefds
);
1331 wxFD_ZERO(&exceptfds
);
1332 wxFD_SET(m_fd
, &readfds
);
1333 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
1334 wxFD_SET(m_fd
, &writefds
);
1335 wxFD_SET(m_fd
, &exceptfds
);
1337 /* Check 'sticky' CONNECTION flag first */
1338 result
|= (GSOCK_CONNECTION_FLAG
& m_detected
);
1340 /* If we have already detected a LOST event, then don't try
1341 * to do any further processing.
1343 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1345 m_establishing
= false;
1347 return (GSOCK_LOST_FLAG
& flags
);
1350 /* Try select now */
1351 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) <= 0)
1353 /* What to do here? */
1354 return (result
& flags
);
1357 /* Check for exceptions and errors */
1358 if (wxFD_ISSET(m_fd
, &exceptfds
))
1360 m_establishing
= false;
1361 m_detected
= GSOCK_LOST_FLAG
;
1363 /* LOST event: Abort any further processing */
1364 return (GSOCK_LOST_FLAG
& flags
);
1367 /* Check for readability */
1368 if (wxFD_ISSET(m_fd
, &readfds
))
1370 result
|= GSOCK_INPUT_FLAG
;
1372 if (m_server
&& m_stream
)
1374 /* This is a TCP server socket that detected a connection.
1375 While the INPUT_FLAG is also set, it doesn't matter on
1376 this kind of sockets, as we can only Accept() from them. */
1377 result
|= GSOCK_CONNECTION_FLAG
;
1378 m_detected
|= GSOCK_CONNECTION_FLAG
;
1382 /* Check for writability */
1383 if (wxFD_ISSET(m_fd
, &writefds
))
1385 if (m_establishing
&& !m_server
)
1388 SOCKOPTLEN_T len
= sizeof(error
);
1390 m_establishing
= false;
1392 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1396 m_detected
= GSOCK_LOST_FLAG
;
1398 /* LOST event: Abort any further processing */
1399 return (GSOCK_LOST_FLAG
& flags
);
1403 result
|= GSOCK_CONNECTION_FLAG
;
1404 m_detected
|= GSOCK_CONNECTION_FLAG
;
1409 result
|= GSOCK_OUTPUT_FLAG
;
1413 return (result
& flags
);
1419 return flags
& m_detected
;
1425 /* GSocket_SetNonBlocking:
1426 * Sets the socket to non-blocking mode. All IO calls will return
1429 void GSocket::SetNonBlocking(bool non_block
)
1433 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1435 m_non_blocking
= non_block
;
1438 /* GSocket_SetTimeout:
1439 * Sets the timeout for blocking calls. Time is expressed in
1442 void GSocket::SetTimeout(unsigned long millisec
)
1446 m_timeout
= millisec
;
1449 /* GSocket_GetError:
1450 * Returns the last error occurred for this socket. Note that successful
1451 * operations do not clear this back to GSOCK_NOERROR, so use it only
1454 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1464 * There is data to be read in the input buffer. If, after a read
1465 * operation, there is still data available, the callback function will
1468 * The socket is available for writing. That is, the next write call
1469 * won't block. This event is generated only once, when the connection is
1470 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1471 * when the output buffer empties again. This means that the app should
1472 * assume that it can write since the first OUTPUT event, and no more
1473 * OUTPUT events will be generated unless an error occurs.
1475 * Connection successfully established, for client sockets, or incoming
1476 * client connection, for server sockets. Wait for this event (also watch
1477 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1479 * The connection is lost (or a connection request failed); this could
1480 * be due to a failure, or due to the peer closing it gracefully.
1483 /* GSocket_SetCallback:
1484 * Enables the callbacks specified by 'flags'. Note that 'flags'
1485 * may be a combination of flags OR'ed toghether, so the same
1486 * callback function can be made to accept different events.
1487 * The callback function must have the following prototype:
1489 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1491 void GSocket::SetCallback(GSocketEventFlags flags
,
1492 GSocketCallback callback
, char *cdata
)
1498 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1500 if ((flags
& (1 << count
)) != 0)
1502 m_cbacks
[count
] = callback
;
1503 m_data
[count
] = cdata
;
1508 /* GSocket_UnsetCallback:
1509 * Disables all callbacks specified by 'flags', which may be a
1510 * combination of flags OR'ed toghether.
1512 void GSocket::UnsetCallback(GSocketEventFlags flags
)
1518 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1520 if ((flags
& (1 << count
)) != 0)
1522 m_cbacks
[count
] = NULL
;
1523 m_data
[count
] = NULL
;
1528 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1529 void *optval
, int *optlen
)
1531 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1532 return GSOCK_NOERROR
;
1534 return GSOCK_OPTERR
;
1537 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1538 const void *optval
, int optlen
)
1540 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1541 return GSOCK_NOERROR
;
1543 return GSOCK_OPTERR
;
1546 #define CALL_CALLBACK(socket, event) { \
1547 socket->Disable(event); \
1548 if (socket->m_cbacks[event]) \
1549 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1553 void GSocket::Enable(GSocketEvent event
)
1555 m_detected
&= ~(1 << event
);
1556 gs_gui_functions
->Install_Callback(this, event
);
1559 void GSocket::Disable(GSocketEvent event
)
1561 m_detected
|= (1 << event
);
1562 gs_gui_functions
->Uninstall_Callback(this, event
);
1565 /* _GSocket_Input_Timeout:
1566 * For blocking sockets, wait until data is available or
1567 * until timeout ellapses.
1569 GSocketError
GSocket::Input_Timeout()
1575 /* Linux select() will overwrite the struct on return */
1576 tv
.tv_sec
= (m_timeout
/ 1000);
1577 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1579 if (!m_non_blocking
)
1581 wxFD_ZERO(&readfds
);
1582 wxFD_SET(m_fd
, &readfds
);
1583 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1586 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1587 m_error
= GSOCK_TIMEDOUT
;
1588 return GSOCK_TIMEDOUT
;
1593 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1594 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1595 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1596 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1597 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1598 m_error
= GSOCK_TIMEDOUT
;
1599 return GSOCK_TIMEDOUT
;
1603 return GSOCK_NOERROR
;
1606 /* _GSocket_Output_Timeout:
1607 * For blocking sockets, wait until data can be sent without
1608 * blocking or until timeout ellapses.
1610 GSocketError
GSocket::Output_Timeout()
1616 /* Linux select() will overwrite the struct on return */
1617 tv
.tv_sec
= (m_timeout
/ 1000);
1618 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1620 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1622 if (!m_non_blocking
)
1624 wxFD_ZERO(&writefds
);
1625 wxFD_SET(m_fd
, &writefds
);
1626 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1629 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1630 m_error
= GSOCK_TIMEDOUT
;
1631 return GSOCK_TIMEDOUT
;
1636 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1637 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1638 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1639 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1640 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1641 m_error
= GSOCK_TIMEDOUT
;
1642 return GSOCK_TIMEDOUT
;
1645 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1647 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1651 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1656 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1659 return GSOCK_NOERROR
;
1662 int GSocket::Recv_Stream(char *buffer
, int size
)
1667 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1669 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1674 int GSocket::Recv_Dgram(char *buffer
, int size
)
1676 struct sockaddr from
;
1677 WX_SOCKLEN_T fromlen
= sizeof(from
);
1681 fromlen
= sizeof(from
);
1685 ret
= recvfrom(m_fd
, buffer
, size
, 0, &from
, (WX_SOCKLEN_T
*) &fromlen
);
1687 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1692 /* Translate a system address into a GSocket address */
1695 m_peer
= GAddress_new();
1698 m_error
= GSOCK_MEMERR
;
1703 err
= _GAddress_translate_from(m_peer
, &from
, fromlen
);
1704 if (err
!= GSOCK_NOERROR
)
1706 GAddress_destroy(m_peer
);
1715 int GSocket::Send_Stream(const char *buffer
, int size
)
1723 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1725 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1732 int GSocket::Send_Dgram(const char *buffer
, int size
)
1734 struct sockaddr
*addr
;
1740 m_error
= GSOCK_INVADDR
;
1744 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1745 if (err
!= GSOCK_NOERROR
)
1755 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1757 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1761 /* Frees memory allocated from _GAddress_translate_to */
1767 void GSocket::Detected_Read()
1771 /* Safeguard against straggling call to Detected_Read */
1772 if (m_fd
== INVALID_SOCKET
)
1777 /* If we have already detected a LOST event, then don't try
1778 * to do any further processing.
1780 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1782 m_establishing
= false;
1784 CALL_CALLBACK(this, GSOCK_LOST
);
1789 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1793 CALL_CALLBACK(this, GSOCK_INPUT
);
1797 if (m_server
&& m_stream
)
1799 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1803 /* graceful shutdown */
1804 CALL_CALLBACK(this, GSOCK_LOST
);
1809 /* Do not throw a lost event in cases where the socket isn't really lost */
1810 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1812 CALL_CALLBACK(this, GSOCK_INPUT
);
1816 CALL_CALLBACK(this, GSOCK_LOST
);
1823 void GSocket::Detected_Write()
1825 /* If we have already detected a LOST event, then don't try
1826 * to do any further processing.
1828 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1830 m_establishing
= false;
1832 CALL_CALLBACK(this, GSOCK_LOST
);
1837 if (m_establishing
&& !m_server
)
1840 SOCKOPTLEN_T len
= sizeof(error
);
1842 m_establishing
= false;
1844 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1848 CALL_CALLBACK(this, GSOCK_LOST
);
1853 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1854 /* We have to fire this event by hand because CONNECTION (for clients)
1855 * and OUTPUT are internally the same and we just disabled CONNECTION
1856 * events with the above macro.
1858 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1863 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1867 /* Compatibility functions for GSocket */
1868 GSocket
*GSocket_new(void)
1870 GSocket
*newsocket
= new GSocket();
1871 if (newsocket
->IsOk())
1880 * -------------------------------------------------------------------------
1882 * -------------------------------------------------------------------------
1885 /* CHECK_ADDRESS verifies that the current address family is either
1886 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1887 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1888 * an appropiate error code.
1890 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1892 #define CHECK_ADDRESS(address, family) \
1894 if (address->m_family == GSOCK_NOFAMILY) \
1895 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1896 return address->m_error; \
1897 if (address->m_family != GSOCK_##family) \
1899 address->m_error = GSOCK_INVADDR; \
1900 return GSOCK_INVADDR; \
1904 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1906 if (address->m_family == GSOCK_NOFAMILY) \
1907 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1909 if (address->m_family != GSOCK_##family) \
1911 address->m_error = GSOCK_INVADDR; \
1917 GAddress
*GAddress_new(void)
1921 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1924 address
->m_family
= GSOCK_NOFAMILY
;
1925 address
->m_addr
= NULL
;
1931 GAddress
*GAddress_copy(GAddress
*address
)
1935 assert(address
!= NULL
);
1937 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1940 memcpy(addr2
, address
, sizeof(GAddress
));
1942 if (address
->m_addr
&& address
->m_len
> 0)
1944 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1945 if (addr2
->m_addr
== NULL
)
1950 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1956 void GAddress_destroy(GAddress
*address
)
1958 assert(address
!= NULL
);
1960 if (address
->m_addr
)
1961 free(address
->m_addr
);
1966 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1968 assert(address
!= NULL
);
1970 address
->m_family
= type
;
1973 GAddressType
GAddress_GetFamily(GAddress
*address
)
1975 assert(address
!= NULL
);
1977 return address
->m_family
;
1980 GSocketError
_GAddress_translate_from(GAddress
*address
,
1981 struct sockaddr
*addr
, int len
)
1983 address
->m_realfamily
= addr
->sa_family
;
1984 switch (addr
->sa_family
)
1987 address
->m_family
= GSOCK_INET
;
1990 address
->m_family
= GSOCK_UNIX
;
1994 address
->m_family
= GSOCK_INET6
;
1999 address
->m_error
= GSOCK_INVOP
;
2004 if (address
->m_addr
)
2005 free(address
->m_addr
);
2007 address
->m_len
= len
;
2008 address
->m_addr
= (struct sockaddr
*)malloc(len
);
2010 if (address
->m_addr
== NULL
)
2012 address
->m_error
= GSOCK_MEMERR
;
2013 return GSOCK_MEMERR
;
2016 memcpy(address
->m_addr
, addr
, len
);
2018 return GSOCK_NOERROR
;
2021 GSocketError
_GAddress_translate_to(GAddress
*address
,
2022 struct sockaddr
**addr
, int *len
)
2024 if (!address
->m_addr
)
2026 address
->m_error
= GSOCK_INVADDR
;
2027 return GSOCK_INVADDR
;
2030 *len
= address
->m_len
;
2031 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
2034 address
->m_error
= GSOCK_MEMERR
;
2035 return GSOCK_MEMERR
;
2038 memcpy(*addr
, address
->m_addr
, address
->m_len
);
2039 return GSOCK_NOERROR
;
2043 * -------------------------------------------------------------------------
2044 * Internet address family
2045 * -------------------------------------------------------------------------
2048 GSocketError
_GAddress_Init_INET(GAddress
*address
)
2050 address
->m_len
= sizeof(struct sockaddr_in
);
2051 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2052 if (address
->m_addr
== NULL
)
2054 address
->m_error
= GSOCK_MEMERR
;
2055 return GSOCK_MEMERR
;
2058 address
->m_family
= GSOCK_INET
;
2059 address
->m_realfamily
= PF_INET
;
2060 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
2061 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
2063 return GSOCK_NOERROR
;
2066 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
2069 struct in_addr
*addr
;
2071 assert(address
!= NULL
);
2073 CHECK_ADDRESS(address
, INET
);
2075 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2077 /* If it is a numeric host name, convert it now */
2078 #if defined(HAVE_INET_ATON)
2079 if (inet_aton(hostname
, addr
) == 0)
2081 #elif defined(HAVE_INET_ADDR)
2082 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
2085 /* Use gethostbyname by default */
2087 int val
= 1; /* VA doesn't like constants in conditional expressions */
2092 struct in_addr
*array_addr
;
2094 /* It is a real name, we solve it */
2096 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2097 struct hostent_data buffer
;
2102 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
2105 /* Reset to invalid address */
2106 addr
->s_addr
= INADDR_NONE
;
2107 address
->m_error
= GSOCK_NOHOST
;
2108 return GSOCK_NOHOST
;
2111 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
2112 addr
->s_addr
= array_addr
[0].s_addr
;
2115 return GSOCK_NOERROR
;
2119 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
2121 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
2124 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
2126 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
2129 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
2130 unsigned long hostaddr
)
2132 struct in_addr
*addr
;
2134 assert(address
!= NULL
);
2136 CHECK_ADDRESS(address
, INET
);
2138 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2139 addr
->s_addr
= htonl(hostaddr
);
2141 return GSOCK_NOERROR
;
2144 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
2145 const char *protocol
)
2148 struct sockaddr_in
*addr
;
2150 assert(address
!= NULL
);
2151 CHECK_ADDRESS(address
, INET
);
2155 address
->m_error
= GSOCK_INVPORT
;
2156 return GSOCK_INVPORT
;
2159 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2160 struct servent_data buffer
;
2164 struct servent serv
;
2165 se
= wxGetservbyname_r(port
, protocol
, &serv
,
2166 (void*)&buffer
, sizeof(buffer
));
2169 /* the cast to int suppresses compiler warnings about subscript having the
2171 if (isdigit((int)port
[0]))
2175 port_int
= atoi(port
);
2176 addr
= (struct sockaddr_in
*)address
->m_addr
;
2177 addr
->sin_port
= htons(port_int
);
2178 return GSOCK_NOERROR
;
2181 address
->m_error
= GSOCK_INVPORT
;
2182 return GSOCK_INVPORT
;
2185 addr
= (struct sockaddr_in
*)address
->m_addr
;
2186 addr
->sin_port
= se
->s_port
;
2188 return GSOCK_NOERROR
;
2191 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
2193 struct sockaddr_in
*addr
;
2195 assert(address
!= NULL
);
2196 CHECK_ADDRESS(address
, INET
);
2198 addr
= (struct sockaddr_in
*)address
->m_addr
;
2199 addr
->sin_port
= htons(port
);
2201 return GSOCK_NOERROR
;
2204 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2208 struct sockaddr_in
*addr
;
2210 assert(address
!= NULL
);
2211 CHECK_ADDRESS(address
, INET
);
2213 addr
= (struct sockaddr_in
*)address
->m_addr
;
2214 addr_buf
= (char *)&(addr
->sin_addr
);
2216 struct hostent temphost
;
2217 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2218 struct hostent_data buffer
;
2223 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
2224 (void*)&buffer
, sizeof(buffer
), &err
);
2227 address
->m_error
= GSOCK_NOHOST
;
2228 return GSOCK_NOHOST
;
2231 strncpy(hostname
, he
->h_name
, sbuf
);
2233 return GSOCK_NOERROR
;
2236 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
2238 struct sockaddr_in
*addr
;
2240 assert(address
!= NULL
);
2241 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2243 addr
= (struct sockaddr_in
*)address
->m_addr
;
2245 return ntohl(addr
->sin_addr
.s_addr
);
2248 unsigned short GAddress_INET_GetPort(GAddress
*address
)
2250 struct sockaddr_in
*addr
;
2252 assert(address
!= NULL
);
2253 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2255 addr
= (struct sockaddr_in
*)address
->m_addr
;
2256 return ntohs(addr
->sin_port
);
2260 * -------------------------------------------------------------------------
2261 * Unix address family
2262 * -------------------------------------------------------------------------
2265 #ifndef __VISAGECPP__
2266 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2268 address
->m_len
= sizeof(struct sockaddr_un
);
2269 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2270 if (address
->m_addr
== NULL
)
2272 address
->m_error
= GSOCK_MEMERR
;
2273 return GSOCK_MEMERR
;
2276 address
->m_family
= GSOCK_UNIX
;
2277 address
->m_realfamily
= PF_UNIX
;
2278 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2279 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2281 return GSOCK_NOERROR
;
2284 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2286 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2288 struct sockaddr_un
*addr
;
2290 assert(address
!= NULL
);
2292 CHECK_ADDRESS(address
, UNIX
);
2294 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2295 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2296 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2298 return GSOCK_NOERROR
;
2301 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2303 struct sockaddr_un
*addr
;
2305 assert(address
!= NULL
);
2306 CHECK_ADDRESS(address
, UNIX
);
2308 addr
= (struct sockaddr_un
*)address
->m_addr
;
2310 strncpy(path
, addr
->sun_path
, sbuf
);
2312 return GSOCK_NOERROR
;
2314 #endif /* !defined(__VISAGECPP__) */
2315 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */