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"
24 #include "wx/thread.h" // for wxThread::IsMain() used in assert
27 #if defined(__VISAGECPP__)
28 #define BSD_SELECT /* use Berkeley Sockets select */
31 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
34 #include <sys/types.h>
39 #include <netinet/in.h>
42 #include <sys/ioctl.h>
44 #ifdef HAVE_SYS_SELECT_H
45 # include <sys/select.h>
52 u_char sun_len
; /* sockaddr len including null */
53 u_char sun_family
; /* AF_UNIX */
54 char sun_path
[108]; /* path name (gag) */
57 #include <sys/socket.h>
63 #include <netinet/in.h>
64 #include <arpa/inet.h>
71 #include <machine/endian.h>
77 #define EBADF SOCEBADF
83 #include <sys/socket.h>
84 #include <sys/ioctl.h>
85 #include <sys/select.h>
87 #define close(a) soclose(a)
88 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
89 int _System
bsdselect(int,
94 int _System
soclose(int);
98 #include <sys/select.h>
106 # include <sys/filio.h>
109 # include <bstring.h>
112 # include <strings.h>
119 # define WX_SOCKLEN_T unsigned int
123 # define WX_SOCKLEN_T socklen_t
125 # elif defined(__WXMAC__)
126 # define WX_SOCKLEN_T socklen_t
128 # define WX_SOCKLEN_T int
132 #endif /* SOCKLEN_T */
135 #define SOCKOPTLEN_T WX_SOCKLEN_T
139 * MSW defines this, Unices don't.
141 #ifndef INVALID_SOCKET
142 #define INVALID_SOCKET -1
145 /* UnixWare reportedly needs this for FIONBIO definition */
147 #include <sys/filio.h>
151 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
152 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
155 #define INADDR_NONE INADDR_BROADCAST
158 #if defined(__VISAGECPP__) || defined(__WATCOMC__)
160 #define MASK_SIGNAL() {
161 #define UNMASK_SIGNAL() }
164 extern "C" { typedef void (*wxSigHandler
)(int); }
166 #define MASK_SIGNAL() \
168 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
170 #define UNMASK_SIGNAL() \
171 signal(SIGPIPE, old_handler); \
176 /* If a SIGPIPE is issued by a socket call on a remotely closed socket,
177 the program will "crash" unless it explicitly handles the SIGPIPE.
178 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
179 use SO_NOSIGPIPE (if available), the BSD equivalent. */
181 # define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
182 #else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
183 # define GSOCKET_MSG_NOSIGNAL 0
184 #endif /* MSG_NOSIGNAL */
186 #ifndef __GSOCKET_STANDALONE__
187 # include "wx/unix/gsockunx.h"
188 # include "wx/unix/private.h"
189 # include "wx/gsocket.h"
190 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
191 # include "wx/thread.h"
194 # include "gsockunx.h"
195 # include "gsocket.h"
199 #endif /* __GSOCKET_STANDALONE__ */
201 #if defined(HAVE_GETHOSTBYNAME)
202 static struct hostent
* deepCopyHostent(struct hostent
*h
,
203 const struct hostent
*he
,
204 char *buffer
, int size
, int *err
)
206 /* copy old structure */
207 memcpy(h
, he
, sizeof(struct hostent
));
210 int len
= strlen(h
->h_name
);
216 memcpy(buffer
, h
->h_name
, len
);
220 /* track position in the buffer */
223 /* reuse len to store address length */
226 /* ensure pointer alignment */
227 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
228 if(misalign
< sizeof(char *))
231 /* leave space for pointer list */
232 char **p
= h
->h_addr_list
, **q
;
233 char **h_addr_list
= (char **)(buffer
+ pos
);
235 pos
+= sizeof(char *);
237 /* copy addresses and fill new pointer list */
238 for (p
= h
->h_addr_list
, q
= h_addr_list
; *p
!= 0; p
++, q
++)
240 if (size
< pos
+ len
)
245 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
246 *q
= buffer
+ pos
; /* set copied pointer to copied content */
249 *++q
= 0; /* null terminate the pointer list */
250 h
->h_addr_list
= h_addr_list
; /* copy pointer to pointers */
252 /* ensure word alignment of pointers */
253 misalign
= sizeof(char *) - pos%sizeof
(char *);
254 if(misalign
< sizeof(char *))
257 /* leave space for pointer list */
259 char **h_aliases
= (char **)(buffer
+ pos
);
261 pos
+= sizeof(char *);
263 /* copy aliases and fill new pointer list */
264 for (p
= h
->h_aliases
, q
= h_aliases
; *p
!= 0; p
++, q
++)
267 if (size
<= pos
+ len
)
272 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
273 buffer
[pos
+ len
] = '\0';
274 *q
= buffer
+ pos
; /* set copied pointer to copied content */
277 *++q
= 0; /* null terminate the pointer list */
278 h
->h_aliases
= h_aliases
; /* copy pointer to pointers */
284 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
285 static wxMutex nameLock
;
287 struct hostent
* wxGethostbyname_r(const char *hostname
, struct hostent
*h
,
288 void *buffer
, int size
, int *err
)
291 struct hostent
*he
= NULL
;
293 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
294 if (gethostbyname_r(hostname
, h
, (char*)buffer
, size
, &he
, err
))
296 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
297 he
= gethostbyname_r(hostname
, h
, (char*)buffer
, size
, err
);
298 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
299 if (gethostbyname_r(hostname
, h
, (struct hostent_data
*) buffer
))
306 #elif defined(HAVE_GETHOSTBYNAME)
308 wxMutexLocker
locker(nameLock
);
310 he
= gethostbyname(hostname
);
314 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
319 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
320 static wxMutex addrLock
;
322 struct hostent
* wxGethostbyaddr_r(const char *addr_buf
, int buf_size
,
323 int proto
, struct hostent
*h
,
324 void *buffer
, int size
, int *err
)
326 struct hostent
*he
= NULL
;
328 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
329 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
330 (char*)buffer
, size
, &he
, err
))
332 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
333 he
= gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
, (char*)buffer
, size
, err
);
334 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
335 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
336 (struct hostent_data
*) buffer
))
343 #elif defined(HAVE_GETHOSTBYNAME)
345 wxMutexLocker
locker(addrLock
);
347 he
= gethostbyaddr(addr_buf
, buf_size
, proto
);
351 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
356 #if defined(HAVE_GETSERVBYNAME)
357 static struct servent
* deepCopyServent(struct servent
*s
,
358 const struct servent
*se
,
359 char *buffer
, int size
)
361 /* copy plain old structure */
362 memcpy(s
, se
, sizeof(struct servent
));
365 int len
= strlen(s
->s_name
);
370 memcpy(buffer
, s
->s_name
, len
);
374 /* track position in the buffer */
378 len
= strlen(s
->s_proto
);
379 if (pos
+ len
>= size
)
383 memcpy(buffer
+ pos
, s
->s_proto
, len
);
384 buffer
[pos
+ len
] = '\0';
385 s
->s_proto
= buffer
+ pos
;
387 /* track position in the buffer */
390 /* ensure pointer alignment */
391 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
392 if(misalign
< sizeof(char *))
395 /* leave space for pointer list */
396 char **p
= s
->s_aliases
, **q
;
397 char **s_aliases
= (char **)(buffer
+ pos
);
399 pos
+= sizeof(char *);
401 /* copy addresses and fill new pointer list */
402 for (p
= s
->s_aliases
, q
= s_aliases
; *p
!= 0; p
++, q
++){
404 if (size
<= pos
+ len
)
408 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
409 buffer
[pos
+ len
] = '\0';
410 *q
= buffer
+ pos
; /* set copied pointer to copied content */
413 *++q
= 0; /* null terminate the pointer list */
414 s
->s_aliases
= s_aliases
; /* copy pointer to pointers */
419 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
420 static wxMutex servLock
;
422 struct servent
*wxGetservbyname_r(const char *port
, const char *protocol
,
423 struct servent
*serv
, void *buffer
, int size
)
425 struct servent
*se
= NULL
;
426 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
427 if (getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
, &se
))
429 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
430 se
= getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
);
431 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
432 if (getservbyname_r(port
, protocol
, serv
, (struct servent_data
*) buffer
))
436 #elif defined(HAVE_GETSERVBYNAME)
438 wxMutexLocker
locker(servLock
);
440 se
= getservbyname(port
, protocol
);
442 se
= deepCopyServent(serv
, se
, (char*)buffer
, size
);
447 /* debugging helpers */
448 #ifdef __GSOCKET_DEBUG__
449 # define GSocket_Debug(args) printf args
451 # define GSocket_Debug(args)
452 #endif /* __GSOCKET_DEBUG__ */
455 typedef struct sockaddr_storage wxSockAddr
;
457 typedef struct sockaddr wxSockAddr
;
460 /* Table of GUI-related functions. We must call them indirectly because
461 * of wxBase and GUI separation: */
465 GSocketManager
* const manager
= GSocketManager::Get();
466 return manager
&& manager
->OnInit();
469 void GSocket_Cleanup()
471 GSocketManager
* const manager
= GSocketManager::Get();
476 /* Constructors / Destructors for GSocket */
482 m_fd
= INVALID_SOCKET
;
485 for (i
=0;i
<GSOCK_MAX_EVENT
;i
++)
492 m_error
= GSOCK_NOERROR
;
495 m_gui_dependent
= NULL
;
496 m_non_blocking
= false;
500 m_timeout
= 10*60*1000;
501 /* 10 minutes * 60 sec * 1000 millisec */
502 m_establishing
= false;
503 m_use_events
= false;
504 m_initialRecvBufferSize
= -1;
505 m_initialSendBufferSize
= -1;
507 m_ok
= GSocketManager::Get()->Init_Socket(this);
510 void GSocket::Close()
515 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
516 will close the socket during Disable_Events. However, it will only do this
517 if it is being used. That is, it won't do it in a console program. To
518 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
519 if it has closed the socket which indicates to us (at runtime, instead of
520 at compile time as this had been before) that the socket has already
523 if(m_fd
!= INVALID_SOCKET
)
525 m_fd
= INVALID_SOCKET
;
532 /* Check that the socket is really shutdowned */
533 if (m_fd
!= INVALID_SOCKET
)
536 GSocketManager::Get()->Destroy_Socket(this);
540 /* Destroy private addresses */
542 GAddress_destroy(m_local
);
545 GAddress_destroy(m_peer
);
550 * Disallow further read/write operations on this socket, close
551 * the fd and disable all callbacks.
553 void GSocket::Shutdown()
559 /* Don't allow events to fire after socket has been closed */
563 /* If socket has been created, shutdown it */
564 if (m_fd
!= INVALID_SOCKET
)
570 /* Disable GUI callbacks */
571 for (evt
= 0; evt
< GSOCK_MAX_EVENT
; evt
++)
572 m_cbacks
[evt
] = NULL
;
574 m_detected
= GSOCK_LOST_FLAG
;
577 /* Address handling */
583 * Set or get the local or peer address for this socket. The 'set'
584 * functions return GSOCK_NOERROR on success, an error code otherwise.
585 * The 'get' functions return a pointer to a GAddress object on success,
586 * or NULL otherwise, in which case they set the error code of the
587 * corresponding GSocket.
590 * GSOCK_INVSOCK - the socket is not valid.
591 * GSOCK_INVADDR - the address is not valid.
593 GSocketError
GSocket::SetLocal(GAddress
*address
)
597 /* the socket must be initialized, or it must be a server */
598 if ((m_fd
!= INVALID_SOCKET
&& !m_server
))
600 m_error
= GSOCK_INVSOCK
;
601 return GSOCK_INVSOCK
;
605 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
607 m_error
= GSOCK_INVADDR
;
608 return GSOCK_INVADDR
;
612 GAddress_destroy(m_local
);
614 m_local
= GAddress_copy(address
);
616 return GSOCK_NOERROR
;
619 GSocketError
GSocket::SetPeer(GAddress
*address
)
624 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
626 m_error
= GSOCK_INVADDR
;
627 return GSOCK_INVADDR
;
631 GAddress_destroy(m_peer
);
633 m_peer
= GAddress_copy(address
);
635 return GSOCK_NOERROR
;
638 GAddress
*GSocket::GetLocal()
642 WX_SOCKLEN_T size
= sizeof(addr
);
647 /* try to get it from the m_local var first */
649 return GAddress_copy(m_local
);
651 /* else, if the socket is initialized, try getsockname */
652 if (m_fd
== INVALID_SOCKET
)
654 m_error
= GSOCK_INVSOCK
;
658 if (getsockname(m_fd
, (sockaddr
*)&addr
, (WX_SOCKLEN_T
*) &size
) < 0)
660 m_error
= GSOCK_IOERR
;
664 /* got a valid address from getsockname, create a GAddress object */
665 address
= GAddress_new();
668 m_error
= GSOCK_MEMERR
;
672 err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
);
673 if (err
!= GSOCK_NOERROR
)
675 GAddress_destroy(address
);
683 GAddress
*GSocket::GetPeer()
687 /* try to get it from the m_peer var */
689 return GAddress_copy(m_peer
);
694 /* Server specific parts */
696 /* GSocket_SetServer:
697 * Sets up this socket as a server. The local address must have been
698 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
699 * Returns GSOCK_NOERROR on success, one of the following otherwise:
702 * GSOCK_INVSOCK - the socket is in use.
703 * GSOCK_INVADDR - the local address has not been set.
704 * GSOCK_IOERR - low-level error.
706 GSocketError
GSocket::SetServer()
712 /* must not be in use */
713 if (m_fd
!= INVALID_SOCKET
)
715 m_error
= GSOCK_INVSOCK
;
716 return GSOCK_INVSOCK
;
719 /* the local addr must have been set */
722 m_error
= GSOCK_INVADDR
;
723 return GSOCK_INVADDR
;
726 /* Initialize all fields */
730 /* Create the socket */
731 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
733 if (m_fd
== INVALID_SOCKET
)
735 m_error
= GSOCK_IOERR
;
739 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
741 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
744 ioctl(m_fd
, FIONBIO
, &arg
);
748 /* allow a socket to re-bind if the socket is in the TIME_WAIT
749 state after being previously closed.
753 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
755 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
759 /* Bind to the local address,
760 * retrieve the actual address bound,
761 * and listen up to 5 connections.
763 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
766 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
767 (listen(m_fd
, 5) != 0))
770 m_error
= GSOCK_IOERR
;
774 return GSOCK_NOERROR
;
777 /* GSocket_WaitConnection:
778 * Waits for an incoming client connection. Returns a pointer to
779 * a GSocket object, or NULL if there was an error, in which case
780 * the last error field will be updated for the calling GSocket.
782 * Error codes (set in the calling GSocket)
783 * GSOCK_INVSOCK - the socket is not valid or not a server.
784 * GSOCK_TIMEDOUT - timeout, no incoming connections.
785 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
786 * GSOCK_MEMERR - couldn't allocate memory.
787 * GSOCK_IOERR - low-level error.
789 GSocket
*GSocket::WaitConnection()
792 WX_SOCKLEN_T fromlen
= sizeof(from
);
799 /* If the socket has already been created, we exit immediately */
800 if (m_fd
== INVALID_SOCKET
|| !m_server
)
802 m_error
= GSOCK_INVSOCK
;
806 /* Create a GSocket object for the new connection */
807 connection
= GSocket_new();
811 m_error
= GSOCK_MEMERR
;
815 /* Wait for a connection (with timeout) */
816 if (Input_Timeout() == GSOCK_TIMEDOUT
)
819 /* m_error set by _GSocket_Input_Timeout */
823 connection
->m_fd
= accept(m_fd
, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
825 /* Reenable CONNECTION events */
826 Enable(GSOCK_CONNECTION
);
828 if (connection
->m_fd
== INVALID_SOCKET
)
830 if (errno
== EWOULDBLOCK
)
831 m_error
= GSOCK_WOULDBLOCK
;
833 m_error
= GSOCK_IOERR
;
839 /* Initialize all fields */
840 connection
->m_server
= false;
841 connection
->m_stream
= true;
843 /* Setup the peer address field */
844 connection
->m_peer
= GAddress_new();
845 if (!connection
->m_peer
)
848 m_error
= GSOCK_MEMERR
;
852 err
= _GAddress_translate_from(connection
->m_peer
, (sockaddr
*)&from
, fromlen
);
853 if (err
!= GSOCK_NOERROR
)
860 #if defined(__EMX__) || defined(__VISAGECPP__)
861 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
863 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
866 connection
->Notify(true);
871 void GSocket::Notify(bool flag
)
873 if (flag
== m_use_events
)
876 // it is not safe to attach or detach i/o descriptor in child thread
877 wxASSERT_MSG( wxThread::IsMain(), "should be called in main thread only" );
883 void GSocket::EnableEvents(bool flag
)
886 GSocketManager::Get()->Enable_Events(this);
888 GSocketManager::Get()->Disable_Events(this);
891 bool GSocket::SetReusable()
893 /* socket must not be null, and must not be in use/already bound */
894 if (this && m_fd
== INVALID_SOCKET
)
904 bool GSocket::SetBroadcast()
906 /* socket must not be in use/already bound */
907 if (m_fd
== INVALID_SOCKET
) {
914 bool GSocket::DontDoBind()
916 /* socket must not be in use/already bound */
917 if (m_fd
== INVALID_SOCKET
) {
924 /* Client specific parts */
927 * For stream (connection oriented) sockets, GSocket_Connect() tries
928 * to establish a client connection to a server using the peer address
929 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
930 * connection has been successfully established, or one of the error
931 * codes listed below. Note that for nonblocking sockets, a return
932 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
933 * request can be completed later; you should use GSocket_Select()
934 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
935 * corresponding asynchronous events.
937 * For datagram (non connection oriented) sockets, GSocket_Connect()
938 * just sets the peer address established with GSocket_SetPeer() as
939 * default destination.
942 * GSOCK_INVSOCK - the socket is in use or not valid.
943 * GSOCK_INVADDR - the peer address has not been established.
944 * GSOCK_TIMEDOUT - timeout, the connection failed.
945 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
946 * GSOCK_MEMERR - couldn't allocate memory.
947 * GSOCK_IOERR - low-level error.
949 GSocketError
GSocket::Connect(GSocketStream stream
)
956 /* Enable CONNECTION events (needed for nonblocking connections) */
957 Enable(GSOCK_CONNECTION
);
959 if (m_fd
!= INVALID_SOCKET
)
961 m_error
= GSOCK_INVSOCK
;
962 return GSOCK_INVSOCK
;
967 m_error
= GSOCK_INVADDR
;
968 return GSOCK_INVADDR
;
971 /* Streamed or dgram socket? */
972 m_stream
= (stream
== GSOCK_STREAMED
);
974 m_establishing
= false;
976 /* Create the socket */
977 m_fd
= socket(m_peer
->m_realfamily
,
978 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
980 if (m_fd
== INVALID_SOCKET
)
982 m_error
= GSOCK_IOERR
;
986 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
988 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
991 #if defined(__EMX__) || defined(__VISAGECPP__)
992 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
994 ioctl(m_fd
, FIONBIO
, &arg
);
997 // If the reuse flag is set, use the applicable socket reuse flags(s)
1000 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1002 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1006 if (m_initialRecvBufferSize
>= 0)
1007 setsockopt(m_fd
, SOL_SOCKET
, SO_RCVBUF
, (const char*)&m_initialRecvBufferSize
, sizeof(m_initialRecvBufferSize
));
1008 if (m_initialSendBufferSize
>= 0)
1009 setsockopt(m_fd
, SOL_SOCKET
, SO_SNDBUF
, (const char*)&m_initialSendBufferSize
, sizeof(m_initialSendBufferSize
));
1011 // If a local address has been set, then we need to bind to it before calling connect
1012 if (m_local
&& m_local
->m_addr
)
1014 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
1017 /* Connect it to the peer address, with a timeout (see below) */
1018 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
1020 /* We only call Enable_Events if we know we aren't shutting down the socket.
1021 * NB: Enable_Events needs to be called whether the socket is blocking or
1022 * non-blocking, it just shouldn't be called prior to knowing there is a
1023 * connection _if_ blocking sockets are being used.
1024 * If connect above returns 0, we are already connected and need to make the
1025 * call to Enable_Events now.
1028 if (m_use_events
&& (m_non_blocking
|| ret
== 0))
1035 /* If connect failed with EINPROGRESS and the GSocket object
1036 * is in blocking mode, we select() for the specified timeout
1037 * checking for writability to see if the connection request
1040 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
1042 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1045 /* m_error is set in _GSocket_Output_Timeout */
1046 return GSOCK_TIMEDOUT
;
1051 SOCKOPTLEN_T len
= sizeof(error
);
1053 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
1058 return GSOCK_NOERROR
;
1062 /* If connect failed with EINPROGRESS and the GSocket object
1063 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1064 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1065 * this way if the connection completes, a GSOCK_CONNECTION
1066 * event will be generated, if enabled.
1068 if ((err
== EINPROGRESS
) && (m_non_blocking
))
1070 m_establishing
= true;
1071 m_error
= GSOCK_WOULDBLOCK
;
1072 return GSOCK_WOULDBLOCK
;
1075 /* If connect failed with an error other than EINPROGRESS,
1076 * then the call to GSocket_Connect has failed.
1079 m_error
= GSOCK_IOERR
;
1084 return GSOCK_NOERROR
;
1087 /* Datagram sockets */
1089 /* GSocket_SetNonOriented:
1090 * Sets up this socket as a non-connection oriented (datagram) socket.
1091 * Before using this function, the local address must have been set
1092 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1093 * on success, or one of the following otherwise.
1096 * GSOCK_INVSOCK - the socket is in use.
1097 * GSOCK_INVADDR - the local address has not been set.
1098 * GSOCK_IOERR - low-level error.
1100 GSocketError
GSocket::SetNonOriented()
1106 if (m_fd
!= INVALID_SOCKET
)
1108 m_error
= GSOCK_INVSOCK
;
1109 return GSOCK_INVSOCK
;
1114 m_error
= GSOCK_INVADDR
;
1115 return GSOCK_INVADDR
;
1118 /* Initialize all fields */
1122 /* Create the socket */
1123 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
1125 if (m_fd
== INVALID_SOCKET
)
1127 m_error
= GSOCK_IOERR
;
1130 #if defined(__EMX__) || defined(__VISAGECPP__)
1131 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1133 ioctl(m_fd
, FIONBIO
, &arg
);
1140 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1142 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1148 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
1152 /* Bind to the local address,
1153 * and retrieve the actual address bound.
1155 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
1158 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
1161 m_error
= GSOCK_IOERR
;
1165 return GSOCK_NOERROR
;
1170 /* Like recv(), send(), ... */
1171 int GSocket::Read(char *buffer
, int size
)
1177 if (m_fd
== INVALID_SOCKET
|| m_server
)
1179 m_error
= GSOCK_INVSOCK
;
1183 /* Disable events during query of socket status */
1184 Disable(GSOCK_INPUT
);
1186 /* If the socket is blocking, wait for data (with a timeout) */
1187 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
1188 m_error
= GSOCK_TIMEDOUT
;
1189 /* Don't return here immediately, otherwise socket events would not be
1197 ret
= Recv_Stream(buffer
, size
);
1199 ret
= Recv_Dgram(buffer
, size
);
1202 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1203 * socket and empty datagrams are possible), then the connection has been
1204 * gracefully closed.
1206 * Otherwise, recv has returned an error (-1), in which case we have lost
1207 * the socket only if errno does _not_ indicate that there may be more data
1210 if ((ret
== 0) && m_stream
)
1212 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1215 m_detected
= GSOCK_LOST_FLAG
;
1222 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1223 m_error
= GSOCK_WOULDBLOCK
;
1225 m_error
= GSOCK_IOERR
;
1229 /* Enable events again now that we are done processing */
1230 Enable(GSOCK_INPUT
);
1235 int GSocket::Write(const char *buffer
, int size
)
1241 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1243 if (m_fd
== INVALID_SOCKET
|| m_server
)
1245 m_error
= GSOCK_INVSOCK
;
1249 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1251 /* If the socket is blocking, wait for writability (with a timeout) */
1252 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1255 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1257 /* Write the data */
1259 ret
= Send_Stream(buffer
, size
);
1261 ret
= Send_Dgram(buffer
, size
);
1263 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1267 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1269 m_error
= GSOCK_WOULDBLOCK
;
1270 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1274 m_error
= GSOCK_IOERR
;
1275 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1278 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1279 * in MSW). Once the first OUTPUT event is received, users can assume
1280 * that the socket is writable until a read operation fails. Only then
1281 * will further OUTPUT events be posted.
1283 Enable(GSOCK_OUTPUT
);
1288 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1294 * Polls the socket to determine its status. This function will
1295 * check for the events specified in the 'flags' parameter, and
1296 * it will return a mask indicating which operations can be
1297 * performed. This function won't block, regardless of the
1298 * mode (blocking | nonblocking) of the socket.
1300 GSocketEventFlags
GSocket::Select(GSocketEventFlags flags
)
1304 GSocketEventFlags result
= 0;
1311 return (GSOCK_LOST_FLAG
& flags
);
1313 /* Do not use a static struct, Linux can garble it */
1317 wxFD_ZERO(&readfds
);
1318 wxFD_ZERO(&writefds
);
1319 wxFD_ZERO(&exceptfds
);
1320 wxFD_SET(m_fd
, &readfds
);
1321 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
1322 wxFD_SET(m_fd
, &writefds
);
1323 wxFD_SET(m_fd
, &exceptfds
);
1325 /* Check 'sticky' CONNECTION flag first */
1326 result
|= GSOCK_CONNECTION_FLAG
& m_detected
;
1328 /* If we have already detected a LOST event, then don't try
1329 * to do any further processing.
1331 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1333 m_establishing
= false;
1334 return (GSOCK_LOST_FLAG
& flags
);
1337 /* Try select now */
1338 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
1340 /* What to do here? */
1341 return (result
& flags
);
1344 /* Check for exceptions and errors */
1345 if (wxFD_ISSET(m_fd
, &exceptfds
))
1347 m_establishing
= false;
1348 m_detected
= GSOCK_LOST_FLAG
;
1350 /* LOST event: Abort any further processing */
1351 return (GSOCK_LOST_FLAG
& flags
);
1354 /* Check for readability */
1355 if (wxFD_ISSET(m_fd
, &readfds
))
1357 result
|= GSOCK_INPUT_FLAG
;
1359 if (m_server
&& m_stream
)
1361 /* This is a TCP server socket that detected a connection.
1362 While the INPUT_FLAG is also set, it doesn't matter on
1363 this kind of sockets, as we can only Accept() from them. */
1364 m_detected
|= GSOCK_CONNECTION_FLAG
;
1368 /* Check for writability */
1369 if (wxFD_ISSET(m_fd
, &writefds
))
1371 if (m_establishing
&& !m_server
)
1374 SOCKOPTLEN_T len
= sizeof(error
);
1375 m_establishing
= false;
1376 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1380 m_detected
= GSOCK_LOST_FLAG
;
1382 /* LOST event: Abort any further processing */
1383 return (GSOCK_LOST_FLAG
& flags
);
1387 m_detected
|= GSOCK_CONNECTION_FLAG
;
1392 result
|= GSOCK_OUTPUT_FLAG
;
1396 return (result
| m_detected
) & flags
;
1401 /* GSocket_SetNonBlocking:
1402 * Sets the socket to non-blocking mode. All IO calls will return
1405 void GSocket::SetNonBlocking(bool non_block
)
1409 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1411 m_non_blocking
= non_block
;
1414 /* GSocket_SetTimeout:
1415 * Sets the timeout for blocking calls. Time is expressed in
1418 void GSocket::SetTimeout(unsigned long millisec
)
1422 m_timeout
= millisec
;
1425 /* GSocket_GetError:
1426 * Returns the last error occurred for this socket. Note that successful
1427 * operations do not clear this back to GSOCK_NOERROR, so use it only
1430 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1440 * There is data to be read in the input buffer. If, after a read
1441 * operation, there is still data available, the callback function will
1444 * The socket is available for writing. That is, the next write call
1445 * won't block. This event is generated only once, when the connection is
1446 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1447 * when the output buffer empties again. This means that the app should
1448 * assume that it can write since the first OUTPUT event, and no more
1449 * OUTPUT events will be generated unless an error occurs.
1451 * Connection successfully established, for client sockets, or incoming
1452 * client connection, for server sockets. Wait for this event (also watch
1453 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1455 * The connection is lost (or a connection request failed); this could
1456 * be due to a failure, or due to the peer closing it gracefully.
1459 /* GSocket_SetCallback:
1460 * Enables the callbacks specified by 'flags'. Note that 'flags'
1461 * may be a combination of flags OR'ed toghether, so the same
1462 * callback function can be made to accept different events.
1463 * The callback function must have the following prototype:
1465 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1467 void GSocket::SetCallback(GSocketEventFlags flags
,
1468 GSocketCallback callback
, char *cdata
)
1474 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1476 if ((flags
& (1 << count
)) != 0)
1478 m_cbacks
[count
] = callback
;
1479 m_data
[count
] = cdata
;
1484 /* GSocket_UnsetCallback:
1485 * Disables all callbacks specified by 'flags', which may be a
1486 * combination of flags OR'ed toghether.
1488 void GSocket::UnsetCallback(GSocketEventFlags flags
)
1494 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1496 if ((flags
& (1 << count
)) != 0)
1498 m_cbacks
[count
] = NULL
;
1499 m_data
[count
] = NULL
;
1504 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1505 void *optval
, int *optlen
)
1507 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1508 return GSOCK_NOERROR
;
1510 return GSOCK_OPTERR
;
1513 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1514 const void *optval
, int optlen
)
1516 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1517 return GSOCK_NOERROR
;
1519 return GSOCK_OPTERR
;
1522 #define CALL_CALLBACK(socket, event) { \
1523 socket->Disable(event); \
1524 if (socket->m_cbacks[event]) \
1525 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1529 void GSocket::Enable(GSocketEvent event
)
1533 m_detected
&= ~(1 << event
);
1534 GSocketManager::Get()->Install_Callback(this, event
);
1538 void GSocket::Disable(GSocketEvent event
)
1542 m_detected
|= (1 << event
);
1543 GSocketManager::Get()->Uninstall_Callback(this, event
);
1547 /* _GSocket_Input_Timeout:
1548 * For blocking sockets, wait until data is available or
1549 * until timeout ellapses.
1551 GSocketError
GSocket::Input_Timeout()
1557 /* Linux select() will overwrite the struct on return */
1558 tv
.tv_sec
= (m_timeout
/ 1000);
1559 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1561 if (!m_non_blocking
)
1563 wxFD_ZERO(&readfds
);
1564 wxFD_SET(m_fd
, &readfds
);
1565 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1568 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1569 m_error
= GSOCK_TIMEDOUT
;
1570 return GSOCK_TIMEDOUT
;
1575 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1576 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1577 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1578 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1579 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1580 m_error
= GSOCK_TIMEDOUT
;
1581 return GSOCK_TIMEDOUT
;
1585 return GSOCK_NOERROR
;
1588 /* _GSocket_Output_Timeout:
1589 * For blocking sockets, wait until data can be sent without
1590 * blocking or until timeout ellapses.
1592 GSocketError
GSocket::Output_Timeout()
1598 /* Linux select() will overwrite the struct on return */
1599 tv
.tv_sec
= (m_timeout
/ 1000);
1600 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1602 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1604 if (!m_non_blocking
)
1606 wxFD_ZERO(&writefds
);
1607 wxFD_SET(m_fd
, &writefds
);
1608 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1611 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1612 m_error
= GSOCK_TIMEDOUT
;
1613 return GSOCK_TIMEDOUT
;
1618 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1619 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1620 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1621 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1622 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1623 m_error
= GSOCK_TIMEDOUT
;
1624 return GSOCK_TIMEDOUT
;
1627 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1629 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1633 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1638 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1641 return GSOCK_NOERROR
;
1644 int GSocket::Recv_Stream(char *buffer
, int size
)
1649 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1651 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1656 int GSocket::Recv_Dgram(char *buffer
, int size
)
1659 WX_SOCKLEN_T fromlen
= sizeof(from
);
1663 fromlen
= sizeof(from
);
1667 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1669 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1674 /* Translate a system address into a GSocket address */
1677 m_peer
= GAddress_new();
1680 m_error
= GSOCK_MEMERR
;
1685 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1686 if (err
!= GSOCK_NOERROR
)
1688 GAddress_destroy(m_peer
);
1697 int GSocket::Send_Stream(const char *buffer
, int size
)
1705 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1707 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1714 int GSocket::Send_Dgram(const char *buffer
, int size
)
1716 struct sockaddr
*addr
;
1722 m_error
= GSOCK_INVADDR
;
1726 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1727 if (err
!= GSOCK_NOERROR
)
1737 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1739 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1743 /* Frees memory allocated from _GAddress_translate_to */
1749 void GSocket::Detected_Read()
1753 /* Safeguard against straggling call to Detected_Read */
1754 if (m_fd
== INVALID_SOCKET
)
1759 /* If we have already detected a LOST event, then don't try
1760 * to do any further processing.
1762 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1764 m_establishing
= false;
1766 CALL_CALLBACK(this, GSOCK_LOST
);
1771 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1775 CALL_CALLBACK(this, GSOCK_INPUT
);
1779 if (m_server
&& m_stream
)
1781 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1787 /* graceful shutdown */
1788 CALL_CALLBACK(this, GSOCK_LOST
);
1793 /* Empty datagram received */
1794 CALL_CALLBACK(this, GSOCK_INPUT
);
1799 /* Do not throw a lost event in cases where the socket isn't really lost */
1800 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1802 CALL_CALLBACK(this, GSOCK_INPUT
);
1806 CALL_CALLBACK(this, GSOCK_LOST
);
1813 void GSocket::Detected_Write()
1815 /* If we have already detected a LOST event, then don't try
1816 * to do any further processing.
1818 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1820 m_establishing
= false;
1822 CALL_CALLBACK(this, GSOCK_LOST
);
1827 if (m_establishing
&& !m_server
)
1830 SOCKOPTLEN_T len
= sizeof(error
);
1832 m_establishing
= false;
1834 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1838 CALL_CALLBACK(this, GSOCK_LOST
);
1843 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1844 /* We have to fire this event by hand because CONNECTION (for clients)
1845 * and OUTPUT are internally the same and we just disabled CONNECTION
1846 * events with the above macro.
1848 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1853 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1857 /* Compatibility functions for GSocket */
1858 GSocket
*GSocket_new(void)
1860 GSocket
*newsocket
= new GSocket();
1861 if (newsocket
->IsOk())
1870 * -------------------------------------------------------------------------
1872 * -------------------------------------------------------------------------
1875 /* CHECK_ADDRESS verifies that the current address family is either
1876 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1877 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1878 * an appropiate error code.
1880 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1882 #define CHECK_ADDRESS(address, family) \
1884 if (address->m_family == GSOCK_NOFAMILY) \
1885 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1886 return address->m_error; \
1887 if (address->m_family != GSOCK_##family) \
1889 address->m_error = GSOCK_INVADDR; \
1890 return GSOCK_INVADDR; \
1894 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1896 if (address->m_family == GSOCK_NOFAMILY) \
1897 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1899 if (address->m_family != GSOCK_##family) \
1901 address->m_error = GSOCK_INVADDR; \
1907 GAddress
*GAddress_new(void)
1911 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1914 address
->m_family
= GSOCK_NOFAMILY
;
1915 address
->m_addr
= NULL
;
1921 GAddress
*GAddress_copy(GAddress
*address
)
1925 assert(address
!= NULL
);
1927 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1930 memcpy(addr2
, address
, sizeof(GAddress
));
1932 if (address
->m_addr
&& address
->m_len
> 0)
1934 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1935 if (addr2
->m_addr
== NULL
)
1940 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1946 void GAddress_destroy(GAddress
*address
)
1948 assert(address
!= NULL
);
1950 if (address
->m_addr
)
1951 free(address
->m_addr
);
1956 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1958 assert(address
!= NULL
);
1960 address
->m_family
= type
;
1963 GAddressType
GAddress_GetFamily(GAddress
*address
)
1965 assert(address
!= NULL
);
1967 return address
->m_family
;
1970 GSocketError
_GAddress_translate_from(GAddress
*address
,
1971 struct sockaddr
*addr
, int len
)
1973 address
->m_realfamily
= addr
->sa_family
;
1974 switch (addr
->sa_family
)
1977 address
->m_family
= GSOCK_INET
;
1980 address
->m_family
= GSOCK_UNIX
;
1984 address
->m_family
= GSOCK_INET6
;
1986 #endif // wxUSE_IPV6
1989 address
->m_error
= GSOCK_INVOP
;
1994 if (address
->m_addr
)
1995 free(address
->m_addr
);
1997 address
->m_len
= len
;
1998 address
->m_addr
= (struct sockaddr
*)malloc(len
);
2000 if (address
->m_addr
== NULL
)
2002 address
->m_error
= GSOCK_MEMERR
;
2003 return GSOCK_MEMERR
;
2006 memcpy(address
->m_addr
, addr
, len
);
2008 return GSOCK_NOERROR
;
2011 GSocketError
_GAddress_translate_to(GAddress
*address
,
2012 struct sockaddr
**addr
, int *len
)
2014 if (!address
->m_addr
)
2016 address
->m_error
= GSOCK_INVADDR
;
2017 return GSOCK_INVADDR
;
2020 *len
= address
->m_len
;
2021 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
2024 address
->m_error
= GSOCK_MEMERR
;
2025 return GSOCK_MEMERR
;
2028 memcpy(*addr
, address
->m_addr
, address
->m_len
);
2029 return GSOCK_NOERROR
;
2033 * -------------------------------------------------------------------------
2034 * Internet address family
2035 * -------------------------------------------------------------------------
2038 GSocketError
_GAddress_Init_INET(GAddress
*address
)
2040 address
->m_len
= sizeof(struct sockaddr_in
);
2041 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2042 if (address
->m_addr
== NULL
)
2044 address
->m_error
= GSOCK_MEMERR
;
2045 return GSOCK_MEMERR
;
2048 address
->m_family
= GSOCK_INET
;
2049 address
->m_realfamily
= PF_INET
;
2050 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
2051 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
2053 return GSOCK_NOERROR
;
2056 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
2059 struct in_addr
*addr
;
2061 assert(address
!= NULL
);
2063 CHECK_ADDRESS(address
, INET
);
2065 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2067 /* If it is a numeric host name, convert it now */
2068 #if defined(HAVE_INET_ATON)
2069 if (inet_aton(hostname
, addr
) == 0)
2071 #elif defined(HAVE_INET_ADDR)
2072 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
2075 /* Use gethostbyname by default */
2077 int val
= 1; /* VA doesn't like constants in conditional expressions */
2082 struct in_addr
*array_addr
;
2084 /* It is a real name, we solve it */
2086 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2087 struct hostent_data buffer
;
2092 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
2095 /* Reset to invalid address */
2096 addr
->s_addr
= INADDR_NONE
;
2097 address
->m_error
= GSOCK_NOHOST
;
2098 return GSOCK_NOHOST
;
2101 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
2102 addr
->s_addr
= array_addr
[0].s_addr
;
2105 return GSOCK_NOERROR
;
2109 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
2111 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
2114 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
2116 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
2119 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
2120 unsigned long hostaddr
)
2122 struct in_addr
*addr
;
2124 assert(address
!= NULL
);
2126 CHECK_ADDRESS(address
, INET
);
2128 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2129 addr
->s_addr
= htonl(hostaddr
);
2131 return GSOCK_NOERROR
;
2134 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
2135 const char *protocol
)
2138 struct sockaddr_in
*addr
;
2140 assert(address
!= NULL
);
2141 CHECK_ADDRESS(address
, INET
);
2145 address
->m_error
= GSOCK_INVPORT
;
2146 return GSOCK_INVPORT
;
2149 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2150 struct servent_data buffer
;
2154 struct servent serv
;
2155 se
= wxGetservbyname_r(port
, protocol
, &serv
,
2156 (void*)&buffer
, sizeof(buffer
));
2159 /* the cast to int suppresses compiler warnings about subscript having the
2161 if (isdigit((int)port
[0]))
2165 port_int
= atoi(port
);
2166 addr
= (struct sockaddr_in
*)address
->m_addr
;
2167 addr
->sin_port
= htons(port_int
);
2168 return GSOCK_NOERROR
;
2171 address
->m_error
= GSOCK_INVPORT
;
2172 return GSOCK_INVPORT
;
2175 addr
= (struct sockaddr_in
*)address
->m_addr
;
2176 addr
->sin_port
= se
->s_port
;
2178 return GSOCK_NOERROR
;
2181 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
2183 struct sockaddr_in
*addr
;
2185 assert(address
!= NULL
);
2186 CHECK_ADDRESS(address
, INET
);
2188 addr
= (struct sockaddr_in
*)address
->m_addr
;
2189 addr
->sin_port
= htons(port
);
2191 return GSOCK_NOERROR
;
2194 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2198 struct sockaddr_in
*addr
;
2200 assert(address
!= NULL
);
2201 CHECK_ADDRESS(address
, INET
);
2203 addr
= (struct sockaddr_in
*)address
->m_addr
;
2204 addr_buf
= (char *)&(addr
->sin_addr
);
2206 struct hostent temphost
;
2207 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2208 struct hostent_data buffer
;
2213 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
2214 (void*)&buffer
, sizeof(buffer
), &err
);
2217 address
->m_error
= GSOCK_NOHOST
;
2218 return GSOCK_NOHOST
;
2221 strncpy(hostname
, he
->h_name
, sbuf
);
2223 return GSOCK_NOERROR
;
2226 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
2228 struct sockaddr_in
*addr
;
2230 assert(address
!= NULL
);
2231 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2233 addr
= (struct sockaddr_in
*)address
->m_addr
;
2235 return ntohl(addr
->sin_addr
.s_addr
);
2238 unsigned short GAddress_INET_GetPort(GAddress
*address
)
2240 struct sockaddr_in
*addr
;
2242 assert(address
!= NULL
);
2243 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2245 addr
= (struct sockaddr_in
*)address
->m_addr
;
2246 return ntohs(addr
->sin_port
);
2251 * -------------------------------------------------------------------------
2252 * Internet IPv6 address family
2253 * -------------------------------------------------------------------------
2256 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
2258 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
2259 address
->m_len
= sizeof(struct sockaddr_in6
);
2260 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2261 if (address
->m_addr
== NULL
)
2263 address
->m_error
= GSOCK_MEMERR
;
2264 return GSOCK_MEMERR
;
2266 memset(address
->m_addr
,0,address
->m_len
);
2268 address
->m_family
= GSOCK_INET6
;
2269 address
->m_realfamily
= AF_INET6
;
2270 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
2271 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
2273 return GSOCK_NOERROR
;
2276 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
2278 assert(address
!= NULL
);
2279 CHECK_ADDRESS(address
, INET6
);
2282 memset( & hints
, 0, sizeof( hints
) );
2283 hints
.ai_family
= AF_INET6
;
2284 addrinfo
* info
= 0;
2285 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
2287 address
->m_error
= GSOCK_NOHOST
;
2288 return GSOCK_NOHOST
;
2291 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
2292 freeaddrinfo( info
);
2293 return GSOCK_NOERROR
;
2296 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
2298 assert(address
!= NULL
);
2300 CHECK_ADDRESS(address
, INET6
);
2302 struct in6_addr addr
;
2303 memset( & addr
, 0, sizeof( addr
) );
2304 return GAddress_INET6_SetHostAddress(address
, addr
);
2306 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
2307 struct in6_addr hostaddr
)
2309 assert(address
!= NULL
);
2311 CHECK_ADDRESS(address
, INET6
);
2313 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
2315 return GSOCK_NOERROR
;
2318 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
2319 const char *protocol
)
2322 struct sockaddr_in6
*addr
;
2324 assert(address
!= NULL
);
2325 CHECK_ADDRESS(address
, INET6
);
2329 address
->m_error
= GSOCK_INVPORT
;
2330 return GSOCK_INVPORT
;
2333 se
= getservbyname(port
, protocol
);
2336 if (isdigit(port
[0]))
2340 port_int
= atoi(port
);
2341 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2342 addr
->sin6_port
= htons((u_short
) port_int
);
2343 return GSOCK_NOERROR
;
2346 address
->m_error
= GSOCK_INVPORT
;
2347 return GSOCK_INVPORT
;
2350 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2351 addr
->sin6_port
= se
->s_port
;
2353 return GSOCK_NOERROR
;
2356 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
2358 struct sockaddr_in6
*addr
;
2360 assert(address
!= NULL
);
2361 CHECK_ADDRESS(address
, INET6
);
2363 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2364 addr
->sin6_port
= htons(port
);
2366 return GSOCK_NOERROR
;
2369 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2373 struct sockaddr_in6
*addr
;
2375 assert(address
!= NULL
);
2376 CHECK_ADDRESS(address
, INET6
);
2378 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2379 addr_buf
= (char *)&(addr
->sin6_addr
);
2381 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
2384 address
->m_error
= GSOCK_NOHOST
;
2385 return GSOCK_NOHOST
;
2388 strncpy(hostname
, he
->h_name
, sbuf
);
2390 return GSOCK_NOERROR
;
2393 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
2395 assert(address
!= NULL
);
2396 assert(hostaddr
!= NULL
);
2397 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
2398 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
2399 return GSOCK_NOERROR
;
2402 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2404 assert(address
!= NULL
);
2405 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2407 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2410 #endif // wxUSE_IPV6
2413 * -------------------------------------------------------------------------
2414 * Unix address family
2415 * -------------------------------------------------------------------------
2418 #ifndef __VISAGECPP__
2419 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2421 address
->m_len
= sizeof(struct sockaddr_un
);
2422 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2423 if (address
->m_addr
== NULL
)
2425 address
->m_error
= GSOCK_MEMERR
;
2426 return GSOCK_MEMERR
;
2429 address
->m_family
= GSOCK_UNIX
;
2430 address
->m_realfamily
= PF_UNIX
;
2431 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2432 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2434 return GSOCK_NOERROR
;
2437 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2439 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2441 struct sockaddr_un
*addr
;
2443 assert(address
!= NULL
);
2445 CHECK_ADDRESS(address
, UNIX
);
2447 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2448 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2449 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2451 return GSOCK_NOERROR
;
2454 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2456 struct sockaddr_un
*addr
;
2458 assert(address
!= NULL
);
2459 CHECK_ADDRESS(address
, UNIX
);
2461 addr
= (struct sockaddr_un
*)address
->m_addr
;
2463 strncpy(path
, addr
->sun_path
, sbuf
);
2465 return GSOCK_NOERROR
;
2467 #endif /* !defined(__VISAGECPP__) */
2468 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */