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;
545 assert(gs_gui_functions
);
546 /* Per-socket GUI-specific initialization */
547 m_ok
= gs_gui_functions
->Init_Socket(this);
550 void GSocket::Close()
552 gs_gui_functions
->Disable_Events(this);
554 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
555 will close the socket during Disable_Events. However, it will only do this
556 if it is being used. That is, it won't do it in a console program. To
557 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
558 if it has closed the socket which indicates to us (at runtime, instead of
559 at compile time as this had been before) that the socket has already
562 if(m_fd
!= INVALID_SOCKET
)
564 m_fd
= INVALID_SOCKET
;
571 /* Check that the socket is really shutdowned */
572 if (m_fd
!= INVALID_SOCKET
)
575 /* Per-socket GUI-specific cleanup */
576 gs_gui_functions
->Destroy_Socket(this);
580 /* Destroy private addresses */
582 GAddress_destroy(m_local
);
585 GAddress_destroy(m_peer
);
589 * Disallow further read/write operations on this socket, close
590 * the fd and disable all callbacks.
592 void GSocket::Shutdown()
598 /* Don't allow events to fire after socket has been closed */
599 gs_gui_functions
->Disable_Events(this);
601 /* If socket has been created, shutdown it */
602 if (m_fd
!= INVALID_SOCKET
)
608 /* Disable GUI callbacks */
609 for (evt
= 0; evt
< GSOCK_MAX_EVENT
; evt
++)
610 m_cbacks
[evt
] = NULL
;
612 m_detected
= GSOCK_LOST_FLAG
;
615 /* Address handling */
621 * Set or get the local or peer address for this socket. The 'set'
622 * functions return GSOCK_NOERROR on success, an error code otherwise.
623 * The 'get' functions return a pointer to a GAddress object on success,
624 * or NULL otherwise, in which case they set the error code of the
625 * corresponding GSocket.
628 * GSOCK_INVSOCK - the socket is not valid.
629 * GSOCK_INVADDR - the address is not valid.
631 GSocketError
GSocket::SetLocal(GAddress
*address
)
635 /* the socket must be initialized, or it must be a server */
636 if ((m_fd
!= INVALID_SOCKET
&& !m_server
))
638 m_error
= GSOCK_INVSOCK
;
639 return GSOCK_INVSOCK
;
643 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
645 m_error
= GSOCK_INVADDR
;
646 return GSOCK_INVADDR
;
650 GAddress_destroy(m_local
);
652 m_local
= GAddress_copy(address
);
654 return GSOCK_NOERROR
;
657 GSocketError
GSocket::SetPeer(GAddress
*address
)
662 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
664 m_error
= GSOCK_INVADDR
;
665 return GSOCK_INVADDR
;
669 GAddress_destroy(m_peer
);
671 m_peer
= GAddress_copy(address
);
673 return GSOCK_NOERROR
;
676 GAddress
*GSocket::GetLocal()
679 struct sockaddr addr
;
680 WX_SOCKLEN_T size
= sizeof(addr
);
685 /* try to get it from the m_local var first */
687 return GAddress_copy(m_local
);
689 /* else, if the socket is initialized, try getsockname */
690 if (m_fd
== INVALID_SOCKET
)
692 m_error
= GSOCK_INVSOCK
;
696 if (getsockname(m_fd
, &addr
, (WX_SOCKLEN_T
*) &size
) < 0)
698 m_error
= GSOCK_IOERR
;
702 /* got a valid address from getsockname, create a GAddress object */
703 address
= GAddress_new();
706 m_error
= GSOCK_MEMERR
;
710 err
= _GAddress_translate_from(address
, &addr
, size
);
711 if (err
!= GSOCK_NOERROR
)
713 GAddress_destroy(address
);
721 GAddress
*GSocket::GetPeer()
725 /* try to get it from the m_peer var */
727 return GAddress_copy(m_peer
);
732 /* Server specific parts */
734 /* GSocket_SetServer:
735 * Sets up this socket as a server. The local address must have been
736 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
737 * Returns GSOCK_NOERROR on success, one of the following otherwise:
740 * GSOCK_INVSOCK - the socket is in use.
741 * GSOCK_INVADDR - the local address has not been set.
742 * GSOCK_IOERR - low-level error.
744 GSocketError
GSocket::SetServer()
750 /* must not be in use */
751 if (m_fd
!= INVALID_SOCKET
)
753 m_error
= GSOCK_INVSOCK
;
754 return GSOCK_INVSOCK
;
757 /* the local addr must have been set */
760 m_error
= GSOCK_INVADDR
;
761 return GSOCK_INVADDR
;
764 /* Initialize all fields */
768 /* Create the socket */
769 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
771 if (m_fd
== INVALID_SOCKET
)
773 m_error
= GSOCK_IOERR
;
777 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
779 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
782 ioctl(m_fd
, FIONBIO
, &arg
);
783 gs_gui_functions
->Enable_Events(this);
785 /* allow a socket to re-bind if the socket is in the TIME_WAIT
786 state after being previously closed.
790 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
792 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
796 /* Bind to the local address,
797 * retrieve the actual address bound,
798 * and listen up to 5 connections.
800 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
803 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
804 (listen(m_fd
, 5) != 0))
807 m_error
= GSOCK_IOERR
;
811 return GSOCK_NOERROR
;
814 /* GSocket_WaitConnection:
815 * Waits for an incoming client connection. Returns a pointer to
816 * a GSocket object, or NULL if there was an error, in which case
817 * the last error field will be updated for the calling GSocket.
819 * Error codes (set in the calling GSocket)
820 * GSOCK_INVSOCK - the socket is not valid or not a server.
821 * GSOCK_TIMEDOUT - timeout, no incoming connections.
822 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
823 * GSOCK_MEMERR - couldn't allocate memory.
824 * GSOCK_IOERR - low-level error.
826 GSocket
*GSocket::WaitConnection()
828 struct sockaddr from
;
829 WX_SOCKLEN_T fromlen
= sizeof(from
);
836 /* If the socket has already been created, we exit immediately */
837 if (m_fd
== INVALID_SOCKET
|| !m_server
)
839 m_error
= GSOCK_INVSOCK
;
843 /* Create a GSocket object for the new connection */
844 connection
= GSocket_new();
848 m_error
= GSOCK_MEMERR
;
852 /* Wait for a connection (with timeout) */
853 if (Input_Timeout() == GSOCK_TIMEDOUT
)
856 /* m_error set by _GSocket_Input_Timeout */
860 connection
->m_fd
= accept(m_fd
, &from
, (WX_SOCKLEN_T
*) &fromlen
);
862 /* Reenable CONNECTION events */
863 Enable(GSOCK_CONNECTION
);
865 if (connection
->m_fd
== INVALID_SOCKET
)
867 if (errno
== EWOULDBLOCK
)
868 m_error
= GSOCK_WOULDBLOCK
;
870 m_error
= GSOCK_IOERR
;
876 /* Initialize all fields */
877 connection
->m_server
= false;
878 connection
->m_stream
= true;
880 /* Setup the peer address field */
881 connection
->m_peer
= GAddress_new();
882 if (!connection
->m_peer
)
885 m_error
= GSOCK_MEMERR
;
889 err
= _GAddress_translate_from(connection
->m_peer
, &from
, fromlen
);
890 if (err
!= GSOCK_NOERROR
)
897 #if defined(__EMX__) || defined(__VISAGECPP__)
898 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
900 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
902 gs_gui_functions
->Enable_Events(connection
);
907 bool GSocket::SetReusable()
909 /* socket must not be null, and must not be in use/already bound */
910 if (this && m_fd
== INVALID_SOCKET
)
920 bool GSocket::SetBroadcast()
922 /* socket must not be in use/already bound */
923 if (m_fd
== INVALID_SOCKET
) {
930 bool GSocket::DontDoBind()
932 /* socket must not be in use/already bound */
933 if (m_fd
== INVALID_SOCKET
) {
940 /* Client specific parts */
943 * For stream (connection oriented) sockets, GSocket_Connect() tries
944 * to establish a client connection to a server using the peer address
945 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
946 * connection has been successfully established, or one of the error
947 * codes listed below. Note that for nonblocking sockets, a return
948 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
949 * request can be completed later; you should use GSocket_Select()
950 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
951 * corresponding asynchronous events.
953 * For datagram (non connection oriented) sockets, GSocket_Connect()
954 * just sets the peer address established with GSocket_SetPeer() as
955 * default destination.
958 * GSOCK_INVSOCK - the socket is in use or not valid.
959 * GSOCK_INVADDR - the peer address has not been established.
960 * GSOCK_TIMEDOUT - timeout, the connection failed.
961 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
962 * GSOCK_MEMERR - couldn't allocate memory.
963 * GSOCK_IOERR - low-level error.
965 GSocketError
GSocket::Connect(GSocketStream stream
)
972 /* Enable CONNECTION events (needed for nonblocking connections) */
973 Enable(GSOCK_CONNECTION
);
975 if (m_fd
!= INVALID_SOCKET
)
977 m_error
= GSOCK_INVSOCK
;
978 return GSOCK_INVSOCK
;
983 m_error
= GSOCK_INVADDR
;
984 return GSOCK_INVADDR
;
987 /* Streamed or dgram socket? */
988 m_stream
= (stream
== GSOCK_STREAMED
);
990 m_establishing
= false;
992 /* Create the socket */
993 m_fd
= socket(m_peer
->m_realfamily
,
994 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
996 if (m_fd
== INVALID_SOCKET
)
998 m_error
= GSOCK_IOERR
;
1002 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
1004 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
1007 #if defined(__EMX__) || defined(__VISAGECPP__)
1008 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1010 ioctl(m_fd
, FIONBIO
, &arg
);
1013 // If the reuse flag is set, use the applicable socket reuse flags(s)
1016 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1018 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1022 // If a local address has been set, then we need to bind to it before calling connect
1023 if (m_local
&& m_local
->m_addr
)
1025 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
1028 /* Connect it to the peer address, with a timeout (see below) */
1029 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
1031 /* We only call Enable_Events if we know we aren't shutting down the socket.
1032 * NB: Enable_Events needs to be called whether the socket is blocking or
1033 * non-blocking, it just shouldn't be called prior to knowing there is a
1034 * connection _if_ blocking sockets are being used.
1035 * If connect above returns 0, we are already connected and need to make the
1036 * call to Enable_Events now.
1039 if (m_non_blocking
|| ret
== 0)
1040 gs_gui_functions
->Enable_Events(this);
1046 /* If connect failed with EINPROGRESS and the GSocket object
1047 * is in blocking mode, we select() for the specified timeout
1048 * checking for writability to see if the connection request
1051 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
1053 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1056 /* m_error is set in _GSocket_Output_Timeout */
1057 return GSOCK_TIMEDOUT
;
1062 SOCKOPTLEN_T len
= sizeof(error
);
1064 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
1066 gs_gui_functions
->Enable_Events(this);
1069 return GSOCK_NOERROR
;
1073 /* If connect failed with EINPROGRESS and the GSocket object
1074 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1075 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1076 * this way if the connection completes, a GSOCK_CONNECTION
1077 * event will be generated, if enabled.
1079 if ((err
== EINPROGRESS
) && (m_non_blocking
))
1081 m_establishing
= true;
1082 m_error
= GSOCK_WOULDBLOCK
;
1083 return GSOCK_WOULDBLOCK
;
1086 /* If connect failed with an error other than EINPROGRESS,
1087 * then the call to GSocket_Connect has failed.
1090 m_error
= GSOCK_IOERR
;
1095 return GSOCK_NOERROR
;
1098 /* Datagram sockets */
1100 /* GSocket_SetNonOriented:
1101 * Sets up this socket as a non-connection oriented (datagram) socket.
1102 * Before using this function, the local address must have been set
1103 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1104 * on success, or one of the following otherwise.
1107 * GSOCK_INVSOCK - the socket is in use.
1108 * GSOCK_INVADDR - the local address has not been set.
1109 * GSOCK_IOERR - low-level error.
1111 GSocketError
GSocket::SetNonOriented()
1117 if (m_fd
!= INVALID_SOCKET
)
1119 m_error
= GSOCK_INVSOCK
;
1120 return GSOCK_INVSOCK
;
1125 m_error
= GSOCK_INVADDR
;
1126 return GSOCK_INVADDR
;
1129 /* Initialize all fields */
1133 /* Create the socket */
1134 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
1136 if (m_fd
== INVALID_SOCKET
)
1138 m_error
= GSOCK_IOERR
;
1141 #if defined(__EMX__) || defined(__VISAGECPP__)
1142 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1144 ioctl(m_fd
, FIONBIO
, &arg
);
1146 gs_gui_functions
->Enable_Events(this);
1150 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1152 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1158 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
1162 /* Bind to the local address,
1163 * and retrieve the actual address bound.
1165 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
1168 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
1171 m_error
= GSOCK_IOERR
;
1175 return GSOCK_NOERROR
;
1180 /* Like recv(), send(), ... */
1181 int GSocket::Read(char *buffer
, int size
)
1187 if (m_fd
== INVALID_SOCKET
|| m_server
)
1189 m_error
= GSOCK_INVSOCK
;
1193 /* Disable events during query of socket status */
1194 Disable(GSOCK_INPUT
);
1196 /* If the socket is blocking, wait for data (with a timeout) */
1197 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
1198 m_error
= GSOCK_TIMEDOUT
;
1199 /* Don't return here immediately, otherwise socket events would not be
1207 ret
= Recv_Stream(buffer
, size
);
1209 ret
= Recv_Dgram(buffer
, size
);
1211 /* If recv returned zero, then the connection has been gracefully closed.
1212 * Otherwise, recv has returned an error (-1), in which case we have lost the
1213 * socket only if errno does _not_ indicate that there may be more data to read.
1217 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1218 m_detected
= GSOCK_LOST_FLAG
;
1224 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1225 m_error
= GSOCK_WOULDBLOCK
;
1227 m_error
= GSOCK_IOERR
;
1231 /* Enable events again now that we are done processing */
1232 Enable(GSOCK_INPUT
);
1237 int GSocket::Write(const char *buffer
, int size
)
1243 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1245 if (m_fd
== INVALID_SOCKET
|| m_server
)
1247 m_error
= GSOCK_INVSOCK
;
1251 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1253 /* If the socket is blocking, wait for writability (with a timeout) */
1254 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1257 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1259 /* Write the data */
1261 ret
= Send_Stream(buffer
, size
);
1263 ret
= Send_Dgram(buffer
, size
);
1265 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1269 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1271 m_error
= GSOCK_WOULDBLOCK
;
1272 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1276 m_error
= GSOCK_IOERR
;
1277 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1280 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1281 * in MSW). Once the first OUTPUT event is received, users can assume
1282 * that the socket is writable until a read operation fails. Only then
1283 * will further OUTPUT events be posted.
1285 Enable(GSOCK_OUTPUT
);
1290 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1296 * Polls the socket to determine its status. This function will
1297 * check for the events specified in the 'flags' parameter, and
1298 * it will return a mask indicating which operations can be
1299 * performed. This function won't block, regardless of the
1300 * mode (blocking | nonblocking) of the socket.
1302 GSocketEventFlags
GSocket::Select(GSocketEventFlags flags
)
1304 if (!gs_gui_functions
->CanUseEventLoop())
1307 GSocketEventFlags result
= 0;
1316 return (GSOCK_LOST_FLAG
& flags
);
1318 /* Do not use a static struct, Linux can garble it */
1319 tv
.tv_sec
= m_timeout
/ 1000;
1320 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1322 wxFD_ZERO(&readfds
);
1323 wxFD_ZERO(&writefds
);
1324 wxFD_ZERO(&exceptfds
);
1325 wxFD_SET(m_fd
, &readfds
);
1326 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
1327 wxFD_SET(m_fd
, &writefds
);
1328 wxFD_SET(m_fd
, &exceptfds
);
1330 /* Check 'sticky' CONNECTION flag first */
1331 result
|= (GSOCK_CONNECTION_FLAG
& m_detected
);
1333 /* If we have already detected a LOST event, then don't try
1334 * to do any further processing.
1336 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1338 m_establishing
= false;
1340 return (GSOCK_LOST_FLAG
& flags
);
1343 /* Try select now */
1344 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) <= 0)
1346 /* What to do here? */
1347 return (result
& flags
);
1350 /* Check for exceptions and errors */
1351 if (wxFD_ISSET(m_fd
, &exceptfds
))
1353 m_establishing
= false;
1354 m_detected
= GSOCK_LOST_FLAG
;
1356 /* LOST event: Abort any further processing */
1357 return (GSOCK_LOST_FLAG
& flags
);
1360 /* Check for readability */
1361 if (wxFD_ISSET(m_fd
, &readfds
))
1363 result
|= GSOCK_INPUT_FLAG
;
1365 if (m_server
&& m_stream
)
1367 /* This is a TCP server socket that detected a connection.
1368 While the INPUT_FLAG is also set, it doesn't matter on
1369 this kind of sockets, as we can only Accept() from them. */
1370 result
|= GSOCK_CONNECTION_FLAG
;
1371 m_detected
|= GSOCK_CONNECTION_FLAG
;
1375 /* Check for writability */
1376 if (wxFD_ISSET(m_fd
, &writefds
))
1378 if (m_establishing
&& !m_server
)
1381 SOCKOPTLEN_T len
= sizeof(error
);
1383 m_establishing
= false;
1385 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1389 m_detected
= GSOCK_LOST_FLAG
;
1391 /* LOST event: Abort any further processing */
1392 return (GSOCK_LOST_FLAG
& flags
);
1396 result
|= GSOCK_CONNECTION_FLAG
;
1397 m_detected
|= GSOCK_CONNECTION_FLAG
;
1402 result
|= GSOCK_OUTPUT_FLAG
;
1406 return (result
& flags
);
1412 return flags
& m_detected
;
1418 /* GSocket_SetNonBlocking:
1419 * Sets the socket to non-blocking mode. All IO calls will return
1422 void GSocket::SetNonBlocking(bool non_block
)
1426 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1428 m_non_blocking
= non_block
;
1431 /* GSocket_SetTimeout:
1432 * Sets the timeout for blocking calls. Time is expressed in
1435 void GSocket::SetTimeout(unsigned long millisec
)
1439 m_timeout
= millisec
;
1442 /* GSocket_GetError:
1443 * Returns the last error occurred for this socket. Note that successful
1444 * operations do not clear this back to GSOCK_NOERROR, so use it only
1447 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1457 * There is data to be read in the input buffer. If, after a read
1458 * operation, there is still data available, the callback function will
1461 * The socket is available for writing. That is, the next write call
1462 * won't block. This event is generated only once, when the connection is
1463 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1464 * when the output buffer empties again. This means that the app should
1465 * assume that it can write since the first OUTPUT event, and no more
1466 * OUTPUT events will be generated unless an error occurs.
1468 * Connection successfully established, for client sockets, or incoming
1469 * client connection, for server sockets. Wait for this event (also watch
1470 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1472 * The connection is lost (or a connection request failed); this could
1473 * be due to a failure, or due to the peer closing it gracefully.
1476 /* GSocket_SetCallback:
1477 * Enables the callbacks specified by 'flags'. Note that 'flags'
1478 * may be a combination of flags OR'ed toghether, so the same
1479 * callback function can be made to accept different events.
1480 * The callback function must have the following prototype:
1482 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1484 void GSocket::SetCallback(GSocketEventFlags flags
,
1485 GSocketCallback callback
, char *cdata
)
1491 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1493 if ((flags
& (1 << count
)) != 0)
1495 m_cbacks
[count
] = callback
;
1496 m_data
[count
] = cdata
;
1501 /* GSocket_UnsetCallback:
1502 * Disables all callbacks specified by 'flags', which may be a
1503 * combination of flags OR'ed toghether.
1505 void GSocket::UnsetCallback(GSocketEventFlags flags
)
1511 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1513 if ((flags
& (1 << count
)) != 0)
1515 m_cbacks
[count
] = NULL
;
1516 m_data
[count
] = NULL
;
1521 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1522 void *optval
, int *optlen
)
1524 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1525 return GSOCK_NOERROR
;
1527 return GSOCK_OPTERR
;
1530 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1531 const void *optval
, int optlen
)
1533 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1534 return GSOCK_NOERROR
;
1536 return GSOCK_OPTERR
;
1539 #define CALL_CALLBACK(socket, event) { \
1540 socket->Disable(event); \
1541 if (socket->m_cbacks[event]) \
1542 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1546 void GSocket::Enable(GSocketEvent event
)
1548 m_detected
&= ~(1 << event
);
1549 gs_gui_functions
->Install_Callback(this, event
);
1552 void GSocket::Disable(GSocketEvent event
)
1554 m_detected
|= (1 << event
);
1555 gs_gui_functions
->Uninstall_Callback(this, event
);
1558 /* _GSocket_Input_Timeout:
1559 * For blocking sockets, wait until data is available or
1560 * until timeout ellapses.
1562 GSocketError
GSocket::Input_Timeout()
1568 /* Linux select() will overwrite the struct on return */
1569 tv
.tv_sec
= (m_timeout
/ 1000);
1570 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1572 if (!m_non_blocking
)
1574 wxFD_ZERO(&readfds
);
1575 wxFD_SET(m_fd
, &readfds
);
1576 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1579 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1580 m_error
= GSOCK_TIMEDOUT
;
1581 return GSOCK_TIMEDOUT
;
1586 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1587 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1588 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1589 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1590 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1591 m_error
= GSOCK_TIMEDOUT
;
1592 return GSOCK_TIMEDOUT
;
1596 return GSOCK_NOERROR
;
1599 /* _GSocket_Output_Timeout:
1600 * For blocking sockets, wait until data can be sent without
1601 * blocking or until timeout ellapses.
1603 GSocketError
GSocket::Output_Timeout()
1609 /* Linux select() will overwrite the struct on return */
1610 tv
.tv_sec
= (m_timeout
/ 1000);
1611 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1613 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1615 if (!m_non_blocking
)
1617 wxFD_ZERO(&writefds
);
1618 wxFD_SET(m_fd
, &writefds
);
1619 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1622 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1623 m_error
= GSOCK_TIMEDOUT
;
1624 return GSOCK_TIMEDOUT
;
1629 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1630 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1631 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1632 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1633 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1634 m_error
= GSOCK_TIMEDOUT
;
1635 return GSOCK_TIMEDOUT
;
1638 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1640 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1644 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1649 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1652 return GSOCK_NOERROR
;
1655 int GSocket::Recv_Stream(char *buffer
, int size
)
1660 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1662 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1667 int GSocket::Recv_Dgram(char *buffer
, int size
)
1669 struct sockaddr from
;
1670 WX_SOCKLEN_T fromlen
= sizeof(from
);
1674 fromlen
= sizeof(from
);
1678 ret
= recvfrom(m_fd
, buffer
, size
, 0, &from
, (WX_SOCKLEN_T
*) &fromlen
);
1680 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1685 /* Translate a system address into a GSocket address */
1688 m_peer
= GAddress_new();
1691 m_error
= GSOCK_MEMERR
;
1696 err
= _GAddress_translate_from(m_peer
, &from
, fromlen
);
1697 if (err
!= GSOCK_NOERROR
)
1699 GAddress_destroy(m_peer
);
1708 int GSocket::Send_Stream(const char *buffer
, int size
)
1716 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1718 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1725 int GSocket::Send_Dgram(const char *buffer
, int size
)
1727 struct sockaddr
*addr
;
1733 m_error
= GSOCK_INVADDR
;
1737 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1738 if (err
!= GSOCK_NOERROR
)
1748 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1750 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1754 /* Frees memory allocated from _GAddress_translate_to */
1760 void GSocket::Detected_Read()
1764 /* Safeguard against straggling call to Detected_Read */
1765 if (m_fd
== INVALID_SOCKET
)
1770 /* If we have already detected a LOST event, then don't try
1771 * to do any further processing.
1773 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1775 m_establishing
= false;
1777 CALL_CALLBACK(this, GSOCK_LOST
);
1782 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1786 CALL_CALLBACK(this, GSOCK_INPUT
);
1790 if (m_server
&& m_stream
)
1792 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1796 /* graceful shutdown */
1797 CALL_CALLBACK(this, GSOCK_LOST
);
1802 /* Do not throw a lost event in cases where the socket isn't really lost */
1803 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1805 CALL_CALLBACK(this, GSOCK_INPUT
);
1809 CALL_CALLBACK(this, GSOCK_LOST
);
1816 void GSocket::Detected_Write()
1818 /* If we have already detected a LOST event, then don't try
1819 * to do any further processing.
1821 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1823 m_establishing
= false;
1825 CALL_CALLBACK(this, GSOCK_LOST
);
1830 if (m_establishing
&& !m_server
)
1833 SOCKOPTLEN_T len
= sizeof(error
);
1835 m_establishing
= false;
1837 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1841 CALL_CALLBACK(this, GSOCK_LOST
);
1846 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1847 /* We have to fire this event by hand because CONNECTION (for clients)
1848 * and OUTPUT are internally the same and we just disabled CONNECTION
1849 * events with the above macro.
1851 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1856 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1860 /* Compatibility functions for GSocket */
1861 GSocket
*GSocket_new(void)
1863 GSocket
*newsocket
= new GSocket();
1864 if (newsocket
->IsOk())
1873 * -------------------------------------------------------------------------
1875 * -------------------------------------------------------------------------
1878 /* CHECK_ADDRESS verifies that the current address family is either
1879 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1880 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1881 * an appropiate error code.
1883 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1885 #define CHECK_ADDRESS(address, family) \
1887 if (address->m_family == GSOCK_NOFAMILY) \
1888 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1889 return address->m_error; \
1890 if (address->m_family != GSOCK_##family) \
1892 address->m_error = GSOCK_INVADDR; \
1893 return GSOCK_INVADDR; \
1897 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1899 if (address->m_family == GSOCK_NOFAMILY) \
1900 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1902 if (address->m_family != GSOCK_##family) \
1904 address->m_error = GSOCK_INVADDR; \
1910 GAddress
*GAddress_new(void)
1914 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1917 address
->m_family
= GSOCK_NOFAMILY
;
1918 address
->m_addr
= NULL
;
1924 GAddress
*GAddress_copy(GAddress
*address
)
1928 assert(address
!= NULL
);
1930 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1933 memcpy(addr2
, address
, sizeof(GAddress
));
1935 if (address
->m_addr
&& address
->m_len
> 0)
1937 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1938 if (addr2
->m_addr
== NULL
)
1943 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1949 void GAddress_destroy(GAddress
*address
)
1951 assert(address
!= NULL
);
1953 if (address
->m_addr
)
1954 free(address
->m_addr
);
1959 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1961 assert(address
!= NULL
);
1963 address
->m_family
= type
;
1966 GAddressType
GAddress_GetFamily(GAddress
*address
)
1968 assert(address
!= NULL
);
1970 return address
->m_family
;
1973 GSocketError
_GAddress_translate_from(GAddress
*address
,
1974 struct sockaddr
*addr
, int len
)
1976 address
->m_realfamily
= addr
->sa_family
;
1977 switch (addr
->sa_family
)
1980 address
->m_family
= GSOCK_INET
;
1983 address
->m_family
= GSOCK_UNIX
;
1987 address
->m_family
= GSOCK_INET6
;
1992 address
->m_error
= GSOCK_INVOP
;
1997 if (address
->m_addr
)
1998 free(address
->m_addr
);
2000 address
->m_len
= len
;
2001 address
->m_addr
= (struct sockaddr
*)malloc(len
);
2003 if (address
->m_addr
== NULL
)
2005 address
->m_error
= GSOCK_MEMERR
;
2006 return GSOCK_MEMERR
;
2009 memcpy(address
->m_addr
, addr
, len
);
2011 return GSOCK_NOERROR
;
2014 GSocketError
_GAddress_translate_to(GAddress
*address
,
2015 struct sockaddr
**addr
, int *len
)
2017 if (!address
->m_addr
)
2019 address
->m_error
= GSOCK_INVADDR
;
2020 return GSOCK_INVADDR
;
2023 *len
= address
->m_len
;
2024 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
2027 address
->m_error
= GSOCK_MEMERR
;
2028 return GSOCK_MEMERR
;
2031 memcpy(*addr
, address
->m_addr
, address
->m_len
);
2032 return GSOCK_NOERROR
;
2036 * -------------------------------------------------------------------------
2037 * Internet address family
2038 * -------------------------------------------------------------------------
2041 GSocketError
_GAddress_Init_INET(GAddress
*address
)
2043 address
->m_len
= sizeof(struct sockaddr_in
);
2044 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2045 if (address
->m_addr
== NULL
)
2047 address
->m_error
= GSOCK_MEMERR
;
2048 return GSOCK_MEMERR
;
2051 address
->m_family
= GSOCK_INET
;
2052 address
->m_realfamily
= PF_INET
;
2053 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
2054 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
2056 return GSOCK_NOERROR
;
2059 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
2062 struct in_addr
*addr
;
2064 assert(address
!= NULL
);
2066 CHECK_ADDRESS(address
, INET
);
2068 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2070 /* If it is a numeric host name, convert it now */
2071 #if defined(HAVE_INET_ATON)
2072 if (inet_aton(hostname
, addr
) == 0)
2074 #elif defined(HAVE_INET_ADDR)
2075 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
2078 /* Use gethostbyname by default */
2080 int val
= 1; /* VA doesn't like constants in conditional expressions */
2085 struct in_addr
*array_addr
;
2087 /* It is a real name, we solve it */
2089 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2090 struct hostent_data buffer
;
2095 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
2098 /* Reset to invalid address */
2099 addr
->s_addr
= INADDR_NONE
;
2100 address
->m_error
= GSOCK_NOHOST
;
2101 return GSOCK_NOHOST
;
2104 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
2105 addr
->s_addr
= array_addr
[0].s_addr
;
2108 return GSOCK_NOERROR
;
2112 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
2114 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
2117 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
2119 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
2122 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
2123 unsigned long hostaddr
)
2125 struct in_addr
*addr
;
2127 assert(address
!= NULL
);
2129 CHECK_ADDRESS(address
, INET
);
2131 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2132 addr
->s_addr
= htonl(hostaddr
);
2134 return GSOCK_NOERROR
;
2137 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
2138 const char *protocol
)
2141 struct sockaddr_in
*addr
;
2143 assert(address
!= NULL
);
2144 CHECK_ADDRESS(address
, INET
);
2148 address
->m_error
= GSOCK_INVPORT
;
2149 return GSOCK_INVPORT
;
2152 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2153 struct servent_data buffer
;
2157 struct servent serv
;
2158 se
= wxGetservbyname_r(port
, protocol
, &serv
,
2159 (void*)&buffer
, sizeof(buffer
));
2162 /* the cast to int suppresses compiler warnings about subscript having the
2164 if (isdigit((int)port
[0]))
2168 port_int
= atoi(port
);
2169 addr
= (struct sockaddr_in
*)address
->m_addr
;
2170 addr
->sin_port
= htons(port_int
);
2171 return GSOCK_NOERROR
;
2174 address
->m_error
= GSOCK_INVPORT
;
2175 return GSOCK_INVPORT
;
2178 addr
= (struct sockaddr_in
*)address
->m_addr
;
2179 addr
->sin_port
= se
->s_port
;
2181 return GSOCK_NOERROR
;
2184 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
2186 struct sockaddr_in
*addr
;
2188 assert(address
!= NULL
);
2189 CHECK_ADDRESS(address
, INET
);
2191 addr
= (struct sockaddr_in
*)address
->m_addr
;
2192 addr
->sin_port
= htons(port
);
2194 return GSOCK_NOERROR
;
2197 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2201 struct sockaddr_in
*addr
;
2203 assert(address
!= NULL
);
2204 CHECK_ADDRESS(address
, INET
);
2206 addr
= (struct sockaddr_in
*)address
->m_addr
;
2207 addr_buf
= (char *)&(addr
->sin_addr
);
2209 struct hostent temphost
;
2210 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2211 struct hostent_data buffer
;
2216 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
2217 (void*)&buffer
, sizeof(buffer
), &err
);
2220 address
->m_error
= GSOCK_NOHOST
;
2221 return GSOCK_NOHOST
;
2224 strncpy(hostname
, he
->h_name
, sbuf
);
2226 return GSOCK_NOERROR
;
2229 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
2231 struct sockaddr_in
*addr
;
2233 assert(address
!= NULL
);
2234 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2236 addr
= (struct sockaddr_in
*)address
->m_addr
;
2238 return ntohl(addr
->sin_addr
.s_addr
);
2241 unsigned short GAddress_INET_GetPort(GAddress
*address
)
2243 struct sockaddr_in
*addr
;
2245 assert(address
!= NULL
);
2246 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2248 addr
= (struct sockaddr_in
*)address
->m_addr
;
2249 return ntohs(addr
->sin_port
);
2253 * -------------------------------------------------------------------------
2254 * Unix address family
2255 * -------------------------------------------------------------------------
2258 #ifndef __VISAGECPP__
2259 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2261 address
->m_len
= sizeof(struct sockaddr_un
);
2262 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2263 if (address
->m_addr
== NULL
)
2265 address
->m_error
= GSOCK_MEMERR
;
2266 return GSOCK_MEMERR
;
2269 address
->m_family
= GSOCK_UNIX
;
2270 address
->m_realfamily
= PF_UNIX
;
2271 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2272 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2274 return GSOCK_NOERROR
;
2277 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2279 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2281 struct sockaddr_un
*addr
;
2283 assert(address
!= NULL
);
2285 CHECK_ADDRESS(address
, UNIX
);
2287 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2288 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2289 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2291 return GSOCK_NOERROR
;
2294 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2296 struct sockaddr_un
*addr
;
2298 assert(address
!= NULL
);
2299 CHECK_ADDRESS(address
, UNIX
);
2301 addr
= (struct sockaddr_un
*)address
->m_addr
;
2303 strncpy(path
, addr
->sun_path
, sbuf
);
2305 return GSOCK_NOERROR
;
2307 #endif /* !defined(__VISAGECPP__) */
2308 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */