1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Authors: David Elliott (C++ conversion, maintainer)
8 * Guillermo Rodriguez Garcia <guille@iies.es>
9 * Purpose: GSocket main Unix and OS/2 file
10 * Licence: The wxWindows licence
12 * -------------------------------------------------------------------------
15 #if defined(__WATCOMC__)
16 #include "wx/wxprec.h"
21 #ifndef __GSOCKET_STANDALONE__
23 #include "wx/private/gsocketiohandler.h"
26 #if defined(__VISAGECPP__)
27 #define BSD_SELECT /* use Berkeley Sockets select */
30 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
33 #include <sys/types.h>
38 #include <netinet/in.h>
41 #include <sys/ioctl.h>
43 #ifdef HAVE_SYS_SELECT_H
44 # include <sys/select.h>
51 u_char sun_len
; /* sockaddr len including null */
52 u_char sun_family
; /* AF_UNIX */
53 char sun_path
[108]; /* path name (gag) */
56 #include <sys/socket.h>
62 #include <netinet/in.h>
63 #include <arpa/inet.h>
70 #include <machine/endian.h>
76 #define EBADF SOCEBADF
82 #include <sys/socket.h>
83 #include <sys/ioctl.h>
84 #include <sys/select.h>
86 #define close(a) soclose(a)
87 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
88 int _System
bsdselect(int,
93 int _System
soclose(int);
97 #include <sys/select.h>
105 # include <sys/filio.h>
108 # include <bstring.h>
111 # include <strings.h>
118 # define WX_SOCKLEN_T unsigned int
122 # define WX_SOCKLEN_T socklen_t
124 # elif defined(__WXMAC__)
125 # define WX_SOCKLEN_T socklen_t
127 # define WX_SOCKLEN_T int
131 #endif /* SOCKLEN_T */
134 #define SOCKOPTLEN_T WX_SOCKLEN_T
138 * MSW defines this, Unices don't.
140 #ifndef INVALID_SOCKET
141 #define INVALID_SOCKET -1
144 /* UnixWare reportedly needs this for FIONBIO definition */
146 #include <sys/filio.h>
150 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
151 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
154 #define INADDR_NONE INADDR_BROADCAST
157 #if defined(__VISAGECPP__) || defined(__WATCOMC__)
159 #define MASK_SIGNAL() {
160 #define UNMASK_SIGNAL() }
163 extern "C" { typedef void (*wxSigHandler
)(int); }
165 #define MASK_SIGNAL() \
167 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
169 #define UNMASK_SIGNAL() \
170 signal(SIGPIPE, old_handler); \
175 /* If a SIGPIPE is issued by a socket call on a remotely closed socket,
176 the program will "crash" unless it explicitly handles the SIGPIPE.
177 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
178 use SO_NOSIGPIPE (if available), the BSD equivalent. */
180 # define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
181 #else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
182 # define GSOCKET_MSG_NOSIGNAL 0
183 #endif /* MSG_NOSIGNAL */
185 #ifndef __GSOCKET_STANDALONE__
186 # include "wx/unix/gsockunx.h"
187 # include "wx/unix/private.h"
188 # include "wx/gsocket.h"
189 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
190 # include "wx/thread.h"
193 # include "gsockunx.h"
194 # include "gsocket.h"
198 #endif /* __GSOCKET_STANDALONE__ */
200 #if defined(HAVE_GETHOSTBYNAME)
201 static struct hostent
* deepCopyHostent(struct hostent
*h
,
202 const struct hostent
*he
,
203 char *buffer
, int size
, int *err
)
205 /* copy old structure */
206 memcpy(h
, he
, sizeof(struct hostent
));
209 int len
= strlen(h
->h_name
);
215 memcpy(buffer
, h
->h_name
, len
);
219 /* track position in the buffer */
222 /* reuse len to store address length */
225 /* ensure pointer alignment */
226 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
227 if(misalign
< sizeof(char *))
230 /* leave space for pointer list */
231 char **p
= h
->h_addr_list
, **q
;
232 char **h_addr_list
= (char **)(buffer
+ pos
);
234 pos
+= sizeof(char *);
236 /* copy addresses and fill new pointer list */
237 for (p
= h
->h_addr_list
, q
= h_addr_list
; *p
!= 0; p
++, q
++)
239 if (size
< pos
+ len
)
244 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
245 *q
= buffer
+ pos
; /* set copied pointer to copied content */
248 *++q
= 0; /* null terminate the pointer list */
249 h
->h_addr_list
= h_addr_list
; /* copy pointer to pointers */
251 /* ensure word alignment of pointers */
252 misalign
= sizeof(char *) - pos%sizeof
(char *);
253 if(misalign
< sizeof(char *))
256 /* leave space for pointer list */
258 char **h_aliases
= (char **)(buffer
+ pos
);
260 pos
+= sizeof(char *);
262 /* copy aliases and fill new pointer list */
263 for (p
= h
->h_aliases
, q
= h_aliases
; *p
!= 0; p
++, q
++)
266 if (size
<= pos
+ len
)
271 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
272 buffer
[pos
+ len
] = '\0';
273 *q
= buffer
+ pos
; /* set copied pointer to copied content */
276 *++q
= 0; /* null terminate the pointer list */
277 h
->h_aliases
= h_aliases
; /* copy pointer to pointers */
283 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
284 static wxMutex nameLock
;
286 struct hostent
* wxGethostbyname_r(const char *hostname
, struct hostent
*h
,
287 void *buffer
, int size
, int *err
)
290 struct hostent
*he
= NULL
;
292 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
293 if (gethostbyname_r(hostname
, h
, (char*)buffer
, size
, &he
, err
))
295 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
296 he
= gethostbyname_r(hostname
, h
, (char*)buffer
, size
, err
);
297 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
298 if (gethostbyname_r(hostname
, h
, (struct hostent_data
*) buffer
))
305 #elif defined(HAVE_GETHOSTBYNAME)
307 wxMutexLocker
locker(nameLock
);
309 he
= gethostbyname(hostname
);
313 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
318 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
319 static wxMutex addrLock
;
321 struct hostent
* wxGethostbyaddr_r(const char *addr_buf
, int buf_size
,
322 int proto
, struct hostent
*h
,
323 void *buffer
, int size
, int *err
)
325 struct hostent
*he
= NULL
;
327 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
328 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
329 (char*)buffer
, size
, &he
, err
))
331 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
332 he
= gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
, (char*)buffer
, size
, err
);
333 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
334 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
335 (struct hostent_data
*) buffer
))
342 #elif defined(HAVE_GETHOSTBYNAME)
344 wxMutexLocker
locker(addrLock
);
346 he
= gethostbyaddr(addr_buf
, buf_size
, proto
);
350 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
355 #if defined(HAVE_GETSERVBYNAME)
356 static struct servent
* deepCopyServent(struct servent
*s
,
357 const struct servent
*se
,
358 char *buffer
, int size
)
360 /* copy plain old structure */
361 memcpy(s
, se
, sizeof(struct servent
));
364 int len
= strlen(s
->s_name
);
369 memcpy(buffer
, s
->s_name
, len
);
373 /* track position in the buffer */
377 len
= strlen(s
->s_proto
);
378 if (pos
+ len
>= size
)
382 memcpy(buffer
+ pos
, s
->s_proto
, len
);
383 buffer
[pos
+ len
] = '\0';
384 s
->s_proto
= buffer
+ pos
;
386 /* track position in the buffer */
389 /* ensure pointer alignment */
390 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
391 if(misalign
< sizeof(char *))
394 /* leave space for pointer list */
395 char **p
= s
->s_aliases
, **q
;
396 char **s_aliases
= (char **)(buffer
+ pos
);
398 pos
+= sizeof(char *);
400 /* copy addresses and fill new pointer list */
401 for (p
= s
->s_aliases
, q
= s_aliases
; *p
!= 0; p
++, q
++){
403 if (size
<= pos
+ len
)
407 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
408 buffer
[pos
+ len
] = '\0';
409 *q
= buffer
+ pos
; /* set copied pointer to copied content */
412 *++q
= 0; /* null terminate the pointer list */
413 s
->s_aliases
= s_aliases
; /* copy pointer to pointers */
418 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
419 static wxMutex servLock
;
421 struct servent
*wxGetservbyname_r(const char *port
, const char *protocol
,
422 struct servent
*serv
, void *buffer
, int size
)
424 struct servent
*se
= NULL
;
425 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
426 if (getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
, &se
))
428 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
429 se
= getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
);
430 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
431 if (getservbyname_r(port
, protocol
, serv
, (struct servent_data
*) buffer
))
435 #elif defined(HAVE_GETSERVBYNAME)
437 wxMutexLocker
locker(servLock
);
439 se
= getservbyname(port
, protocol
);
441 se
= deepCopyServent(serv
, se
, (char*)buffer
, size
);
446 /* debugging helpers */
447 #ifdef __GSOCKET_DEBUG__
448 # define GSocket_Debug(args) printf args
450 # define GSocket_Debug(args)
451 #endif /* __GSOCKET_DEBUG__ */
454 typedef struct sockaddr_storage wxSockAddr
;
456 typedef struct sockaddr wxSockAddr
;
459 /* Table of GUI-related functions. We must call them indirectly because
460 * of wxBase and GUI separation: */
464 GSocketManager
* const manager
= GSocketManager::Get();
465 return manager
&& manager
->OnInit();
468 void GSocket_Cleanup()
470 GSocketManager
* const manager
= GSocketManager::Get();
475 /* Constructors / Destructors for GSocket */
481 m_fd
= INVALID_SOCKET
;
484 for (i
=0;i
<GSOCK_MAX_EVENT
;i
++)
491 m_error
= GSOCK_NOERROR
;
494 m_gui_dependent
= NULL
;
495 m_non_blocking
= false;
499 m_timeout
= 10*60*1000;
500 /* 10 minutes * 60 sec * 1000 millisec */
501 m_establishing
= false;
502 m_use_events
= false;
503 m_initialRecvBufferSize
= -1;
504 m_initialSendBufferSize
= -1;
506 m_ok
= GSocketManager::Get()->Init_Socket(this);
509 void GSocket::Close()
514 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
515 will close the socket during Disable_Events. However, it will only do this
516 if it is being used. That is, it won't do it in a console program. To
517 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
518 if it has closed the socket which indicates to us (at runtime, instead of
519 at compile time as this had been before) that the socket has already
522 if(m_fd
!= INVALID_SOCKET
)
524 m_fd
= INVALID_SOCKET
;
531 /* Check that the socket is really shutdowned */
532 if (m_fd
!= INVALID_SOCKET
)
535 GSocketManager::Get()->Destroy_Socket(this);
539 /* Destroy private addresses */
541 GAddress_destroy(m_local
);
544 GAddress_destroy(m_peer
);
549 * Disallow further read/write operations on this socket, close
550 * the fd and disable all callbacks.
552 void GSocket::Shutdown()
558 /* Don't allow events to fire after socket has been closed */
562 /* If socket has been created, shutdown it */
563 if (m_fd
!= INVALID_SOCKET
)
569 /* Disable GUI callbacks */
570 for (evt
= 0; evt
< GSOCK_MAX_EVENT
; evt
++)
571 m_cbacks
[evt
] = NULL
;
573 m_detected
= GSOCK_LOST_FLAG
;
576 /* Address handling */
582 * Set or get the local or peer address for this socket. The 'set'
583 * functions return GSOCK_NOERROR on success, an error code otherwise.
584 * The 'get' functions return a pointer to a GAddress object on success,
585 * or NULL otherwise, in which case they set the error code of the
586 * corresponding GSocket.
589 * GSOCK_INVSOCK - the socket is not valid.
590 * GSOCK_INVADDR - the address is not valid.
592 GSocketError
GSocket::SetLocal(GAddress
*address
)
596 /* the socket must be initialized, or it must be a server */
597 if ((m_fd
!= INVALID_SOCKET
&& !m_server
))
599 m_error
= GSOCK_INVSOCK
;
600 return GSOCK_INVSOCK
;
604 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
606 m_error
= GSOCK_INVADDR
;
607 return GSOCK_INVADDR
;
611 GAddress_destroy(m_local
);
613 m_local
= GAddress_copy(address
);
615 return GSOCK_NOERROR
;
618 GSocketError
GSocket::SetPeer(GAddress
*address
)
623 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
625 m_error
= GSOCK_INVADDR
;
626 return GSOCK_INVADDR
;
630 GAddress_destroy(m_peer
);
632 m_peer
= GAddress_copy(address
);
634 return GSOCK_NOERROR
;
637 GAddress
*GSocket::GetLocal()
641 WX_SOCKLEN_T size
= sizeof(addr
);
646 /* try to get it from the m_local var first */
648 return GAddress_copy(m_local
);
650 /* else, if the socket is initialized, try getsockname */
651 if (m_fd
== INVALID_SOCKET
)
653 m_error
= GSOCK_INVSOCK
;
657 if (getsockname(m_fd
, (sockaddr
*)&addr
, (WX_SOCKLEN_T
*) &size
) < 0)
659 m_error
= GSOCK_IOERR
;
663 /* got a valid address from getsockname, create a GAddress object */
664 address
= GAddress_new();
667 m_error
= GSOCK_MEMERR
;
671 err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
);
672 if (err
!= GSOCK_NOERROR
)
674 GAddress_destroy(address
);
682 GAddress
*GSocket::GetPeer()
686 /* try to get it from the m_peer var */
688 return GAddress_copy(m_peer
);
693 /* Server specific parts */
695 /* GSocket_SetServer:
696 * Sets up this socket as a server. The local address must have been
697 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
698 * Returns GSOCK_NOERROR on success, one of the following otherwise:
701 * GSOCK_INVSOCK - the socket is in use.
702 * GSOCK_INVADDR - the local address has not been set.
703 * GSOCK_IOERR - low-level error.
705 GSocketError
GSocket::SetServer()
711 /* must not be in use */
712 if (m_fd
!= INVALID_SOCKET
)
714 m_error
= GSOCK_INVSOCK
;
715 return GSOCK_INVSOCK
;
718 /* the local addr must have been set */
721 m_error
= GSOCK_INVADDR
;
722 return GSOCK_INVADDR
;
725 /* Initialize all fields */
729 /* Create the socket */
730 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
732 if (m_fd
== INVALID_SOCKET
)
734 m_error
= GSOCK_IOERR
;
738 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
740 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
743 ioctl(m_fd
, FIONBIO
, &arg
);
747 /* allow a socket to re-bind if the socket is in the TIME_WAIT
748 state after being previously closed.
752 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
754 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
758 /* Bind to the local address,
759 * retrieve the actual address bound,
760 * and listen up to 5 connections.
762 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
765 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
766 (listen(m_fd
, 5) != 0))
769 m_error
= GSOCK_IOERR
;
773 return GSOCK_NOERROR
;
776 /* GSocket_WaitConnection:
777 * Waits for an incoming client connection. Returns a pointer to
778 * a GSocket object, or NULL if there was an error, in which case
779 * the last error field will be updated for the calling GSocket.
781 * Error codes (set in the calling GSocket)
782 * GSOCK_INVSOCK - the socket is not valid or not a server.
783 * GSOCK_TIMEDOUT - timeout, no incoming connections.
784 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
785 * GSOCK_MEMERR - couldn't allocate memory.
786 * GSOCK_IOERR - low-level error.
788 GSocket
*GSocket::WaitConnection()
791 WX_SOCKLEN_T fromlen
= sizeof(from
);
798 /* If the socket has already been created, we exit immediately */
799 if (m_fd
== INVALID_SOCKET
|| !m_server
)
801 m_error
= GSOCK_INVSOCK
;
805 /* Create a GSocket object for the new connection */
806 connection
= GSocket_new();
810 m_error
= GSOCK_MEMERR
;
814 /* Wait for a connection (with timeout) */
815 if (Input_Timeout() == GSOCK_TIMEDOUT
)
818 /* m_error set by _GSocket_Input_Timeout */
822 connection
->m_fd
= accept(m_fd
, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
824 /* Reenable CONNECTION events */
825 Enable(GSOCK_CONNECTION
);
827 if (connection
->m_fd
== INVALID_SOCKET
)
829 if (errno
== EWOULDBLOCK
)
830 m_error
= GSOCK_WOULDBLOCK
;
832 m_error
= GSOCK_IOERR
;
838 /* Initialize all fields */
839 connection
->m_server
= false;
840 connection
->m_stream
= true;
842 /* Setup the peer address field */
843 connection
->m_peer
= GAddress_new();
844 if (!connection
->m_peer
)
847 m_error
= GSOCK_MEMERR
;
851 err
= _GAddress_translate_from(connection
->m_peer
, (sockaddr
*)&from
, fromlen
);
852 if (err
!= GSOCK_NOERROR
)
859 #if defined(__EMX__) || defined(__VISAGECPP__)
860 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
862 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
865 connection
->Notify(true);
870 void GSocket::Notify(bool flag
)
872 if (flag
== m_use_events
)
878 void GSocket::EnableEvents(bool flag
)
881 GSocketManager::Get()->Enable_Events(this);
883 GSocketManager::Get()->Disable_Events(this);
886 bool GSocket::SetReusable()
888 /* socket must not be null, and must not be in use/already bound */
889 if (this && m_fd
== INVALID_SOCKET
)
899 bool GSocket::SetBroadcast()
901 /* socket must not be in use/already bound */
902 if (m_fd
== INVALID_SOCKET
) {
909 bool GSocket::DontDoBind()
911 /* socket must not be in use/already bound */
912 if (m_fd
== INVALID_SOCKET
) {
919 /* Client specific parts */
922 * For stream (connection oriented) sockets, GSocket_Connect() tries
923 * to establish a client connection to a server using the peer address
924 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
925 * connection has been successfully established, or one of the error
926 * codes listed below. Note that for nonblocking sockets, a return
927 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
928 * request can be completed later; you should use GSocket_Select()
929 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
930 * corresponding asynchronous events.
932 * For datagram (non connection oriented) sockets, GSocket_Connect()
933 * just sets the peer address established with GSocket_SetPeer() as
934 * default destination.
937 * GSOCK_INVSOCK - the socket is in use or not valid.
938 * GSOCK_INVADDR - the peer address has not been established.
939 * GSOCK_TIMEDOUT - timeout, the connection failed.
940 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
941 * GSOCK_MEMERR - couldn't allocate memory.
942 * GSOCK_IOERR - low-level error.
944 GSocketError
GSocket::Connect(GSocketStream stream
)
951 /* Enable CONNECTION events (needed for nonblocking connections) */
952 Enable(GSOCK_CONNECTION
);
954 if (m_fd
!= INVALID_SOCKET
)
956 m_error
= GSOCK_INVSOCK
;
957 return GSOCK_INVSOCK
;
962 m_error
= GSOCK_INVADDR
;
963 return GSOCK_INVADDR
;
966 /* Streamed or dgram socket? */
967 m_stream
= (stream
== GSOCK_STREAMED
);
969 m_establishing
= false;
971 /* Create the socket */
972 m_fd
= socket(m_peer
->m_realfamily
,
973 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
975 if (m_fd
== INVALID_SOCKET
)
977 m_error
= GSOCK_IOERR
;
981 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
983 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
986 #if defined(__EMX__) || defined(__VISAGECPP__)
987 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
989 ioctl(m_fd
, FIONBIO
, &arg
);
992 // If the reuse flag is set, use the applicable socket reuse flags(s)
995 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
997 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1001 if (m_initialRecvBufferSize
>= 0)
1002 setsockopt(m_fd
, SOL_SOCKET
, SO_RCVBUF
, (const char*)&m_initialRecvBufferSize
, sizeof(m_initialRecvBufferSize
));
1003 if (m_initialSendBufferSize
>= 0)
1004 setsockopt(m_fd
, SOL_SOCKET
, SO_SNDBUF
, (const char*)&m_initialSendBufferSize
, sizeof(m_initialSendBufferSize
));
1006 // If a local address has been set, then we need to bind to it before calling connect
1007 if (m_local
&& m_local
->m_addr
)
1009 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
1012 /* Connect it to the peer address, with a timeout (see below) */
1013 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
1015 /* We only call Enable_Events if we know we aren't shutting down the socket.
1016 * NB: Enable_Events needs to be called whether the socket is blocking or
1017 * non-blocking, it just shouldn't be called prior to knowing there is a
1018 * connection _if_ blocking sockets are being used.
1019 * If connect above returns 0, we are already connected and need to make the
1020 * call to Enable_Events now.
1023 if (m_use_events
&& (m_non_blocking
|| ret
== 0))
1030 /* If connect failed with EINPROGRESS and the GSocket object
1031 * is in blocking mode, we select() for the specified timeout
1032 * checking for writability to see if the connection request
1035 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
1037 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1040 /* m_error is set in _GSocket_Output_Timeout */
1041 return GSOCK_TIMEDOUT
;
1046 SOCKOPTLEN_T len
= sizeof(error
);
1048 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
1053 return GSOCK_NOERROR
;
1057 /* If connect failed with EINPROGRESS and the GSocket object
1058 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1059 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1060 * this way if the connection completes, a GSOCK_CONNECTION
1061 * event will be generated, if enabled.
1063 if ((err
== EINPROGRESS
) && (m_non_blocking
))
1065 m_establishing
= true;
1066 m_error
= GSOCK_WOULDBLOCK
;
1067 return GSOCK_WOULDBLOCK
;
1070 /* If connect failed with an error other than EINPROGRESS,
1071 * then the call to GSocket_Connect has failed.
1074 m_error
= GSOCK_IOERR
;
1079 return GSOCK_NOERROR
;
1082 /* Datagram sockets */
1084 /* GSocket_SetNonOriented:
1085 * Sets up this socket as a non-connection oriented (datagram) socket.
1086 * Before using this function, the local address must have been set
1087 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1088 * on success, or one of the following otherwise.
1091 * GSOCK_INVSOCK - the socket is in use.
1092 * GSOCK_INVADDR - the local address has not been set.
1093 * GSOCK_IOERR - low-level error.
1095 GSocketError
GSocket::SetNonOriented()
1101 if (m_fd
!= INVALID_SOCKET
)
1103 m_error
= GSOCK_INVSOCK
;
1104 return GSOCK_INVSOCK
;
1109 m_error
= GSOCK_INVADDR
;
1110 return GSOCK_INVADDR
;
1113 /* Initialize all fields */
1117 /* Create the socket */
1118 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
1120 if (m_fd
== INVALID_SOCKET
)
1122 m_error
= GSOCK_IOERR
;
1125 #if defined(__EMX__) || defined(__VISAGECPP__)
1126 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1128 ioctl(m_fd
, FIONBIO
, &arg
);
1135 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1137 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1143 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
1147 /* Bind to the local address,
1148 * and retrieve the actual address bound.
1150 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
1153 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
1156 m_error
= GSOCK_IOERR
;
1160 return GSOCK_NOERROR
;
1165 /* Like recv(), send(), ... */
1166 int GSocket::Read(char *buffer
, int size
)
1172 if (m_fd
== INVALID_SOCKET
|| m_server
)
1174 m_error
= GSOCK_INVSOCK
;
1178 /* Disable events during query of socket status */
1179 Disable(GSOCK_INPUT
);
1181 /* If the socket is blocking, wait for data (with a timeout) */
1182 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
1183 m_error
= GSOCK_TIMEDOUT
;
1184 /* Don't return here immediately, otherwise socket events would not be
1192 ret
= Recv_Stream(buffer
, size
);
1194 ret
= Recv_Dgram(buffer
, size
);
1197 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1198 * socket and empty datagrams are possible), then the connection has been
1199 * gracefully closed.
1201 * Otherwise, recv has returned an error (-1), in which case we have lost
1202 * the socket only if errno does _not_ indicate that there may be more data
1205 if ((ret
== 0) && m_stream
)
1207 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1210 m_detected
= GSOCK_LOST_FLAG
;
1217 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1218 m_error
= GSOCK_WOULDBLOCK
;
1220 m_error
= GSOCK_IOERR
;
1224 /* Enable events again now that we are done processing */
1225 Enable(GSOCK_INPUT
);
1230 int GSocket::Write(const char *buffer
, int size
)
1236 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1238 if (m_fd
== INVALID_SOCKET
|| m_server
)
1240 m_error
= GSOCK_INVSOCK
;
1244 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1246 /* If the socket is blocking, wait for writability (with a timeout) */
1247 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1250 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1252 /* Write the data */
1254 ret
= Send_Stream(buffer
, size
);
1256 ret
= Send_Dgram(buffer
, size
);
1258 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1262 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1264 m_error
= GSOCK_WOULDBLOCK
;
1265 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1269 m_error
= GSOCK_IOERR
;
1270 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1273 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1274 * in MSW). Once the first OUTPUT event is received, users can assume
1275 * that the socket is writable until a read operation fails. Only then
1276 * will further OUTPUT events be posted.
1278 Enable(GSOCK_OUTPUT
);
1283 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1289 * Polls the socket to determine its status. This function will
1290 * check for the events specified in the 'flags' parameter, and
1291 * it will return a mask indicating which operations can be
1292 * performed. This function won't block, regardless of the
1293 * mode (blocking | nonblocking) of the socket.
1295 GSocketEventFlags
GSocket::Select(GSocketEventFlags flags
)
1299 GSocketEventFlags result
= 0;
1306 return (GSOCK_LOST_FLAG
& flags
);
1308 /* Do not use a static struct, Linux can garble it */
1312 wxFD_ZERO(&readfds
);
1313 wxFD_ZERO(&writefds
);
1314 wxFD_ZERO(&exceptfds
);
1315 wxFD_SET(m_fd
, &readfds
);
1316 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
1317 wxFD_SET(m_fd
, &writefds
);
1318 wxFD_SET(m_fd
, &exceptfds
);
1320 /* Check 'sticky' CONNECTION flag first */
1321 result
|= GSOCK_CONNECTION_FLAG
& m_detected
;
1323 /* If we have already detected a LOST event, then don't try
1324 * to do any further processing.
1326 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1328 m_establishing
= false;
1329 return (GSOCK_LOST_FLAG
& flags
);
1332 /* Try select now */
1333 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
1335 /* What to do here? */
1336 return (result
& flags
);
1339 /* Check for exceptions and errors */
1340 if (wxFD_ISSET(m_fd
, &exceptfds
))
1342 m_establishing
= false;
1343 m_detected
= GSOCK_LOST_FLAG
;
1345 /* LOST event: Abort any further processing */
1346 return (GSOCK_LOST_FLAG
& flags
);
1349 /* Check for readability */
1350 if (wxFD_ISSET(m_fd
, &readfds
))
1352 result
|= GSOCK_INPUT_FLAG
;
1354 if (m_server
&& m_stream
)
1356 /* This is a TCP server socket that detected a connection.
1357 While the INPUT_FLAG is also set, it doesn't matter on
1358 this kind of sockets, as we can only Accept() from them. */
1359 m_detected
|= GSOCK_CONNECTION_FLAG
;
1363 /* Check for writability */
1364 if (wxFD_ISSET(m_fd
, &writefds
))
1366 if (m_establishing
&& !m_server
)
1369 SOCKOPTLEN_T len
= sizeof(error
);
1370 m_establishing
= false;
1371 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1375 m_detected
= GSOCK_LOST_FLAG
;
1377 /* LOST event: Abort any further processing */
1378 return (GSOCK_LOST_FLAG
& flags
);
1382 m_detected
|= GSOCK_CONNECTION_FLAG
;
1387 result
|= GSOCK_OUTPUT_FLAG
;
1391 return (result
| m_detected
) & flags
;
1396 /* GSocket_SetNonBlocking:
1397 * Sets the socket to non-blocking mode. All IO calls will return
1400 void GSocket::SetNonBlocking(bool non_block
)
1404 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1406 m_non_blocking
= non_block
;
1409 /* GSocket_SetTimeout:
1410 * Sets the timeout for blocking calls. Time is expressed in
1413 void GSocket::SetTimeout(unsigned long millisec
)
1417 m_timeout
= millisec
;
1420 /* GSocket_GetError:
1421 * Returns the last error occurred for this socket. Note that successful
1422 * operations do not clear this back to GSOCK_NOERROR, so use it only
1425 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1435 * There is data to be read in the input buffer. If, after a read
1436 * operation, there is still data available, the callback function will
1439 * The socket is available for writing. That is, the next write call
1440 * won't block. This event is generated only once, when the connection is
1441 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1442 * when the output buffer empties again. This means that the app should
1443 * assume that it can write since the first OUTPUT event, and no more
1444 * OUTPUT events will be generated unless an error occurs.
1446 * Connection successfully established, for client sockets, or incoming
1447 * client connection, for server sockets. Wait for this event (also watch
1448 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1450 * The connection is lost (or a connection request failed); this could
1451 * be due to a failure, or due to the peer closing it gracefully.
1454 /* GSocket_SetCallback:
1455 * Enables the callbacks specified by 'flags'. Note that 'flags'
1456 * may be a combination of flags OR'ed toghether, so the same
1457 * callback function can be made to accept different events.
1458 * The callback function must have the following prototype:
1460 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1462 void GSocket::SetCallback(GSocketEventFlags flags
,
1463 GSocketCallback callback
, char *cdata
)
1469 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1471 if ((flags
& (1 << count
)) != 0)
1473 m_cbacks
[count
] = callback
;
1474 m_data
[count
] = cdata
;
1479 /* GSocket_UnsetCallback:
1480 * Disables all callbacks specified by 'flags', which may be a
1481 * combination of flags OR'ed toghether.
1483 void GSocket::UnsetCallback(GSocketEventFlags flags
)
1489 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1491 if ((flags
& (1 << count
)) != 0)
1493 m_cbacks
[count
] = NULL
;
1494 m_data
[count
] = NULL
;
1499 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1500 void *optval
, int *optlen
)
1502 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1503 return GSOCK_NOERROR
;
1505 return GSOCK_OPTERR
;
1508 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1509 const void *optval
, int optlen
)
1511 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1512 return GSOCK_NOERROR
;
1514 return GSOCK_OPTERR
;
1517 #define CALL_CALLBACK(socket, event) { \
1518 socket->Disable(event); \
1519 if (socket->m_cbacks[event]) \
1520 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1524 void GSocket::Enable(GSocketEvent event
)
1528 m_detected
&= ~(1 << event
);
1529 GSocketManager::Get()->Install_Callback(this, event
);
1533 void GSocket::Disable(GSocketEvent event
)
1537 m_detected
|= (1 << event
);
1538 GSocketManager::Get()->Uninstall_Callback(this, event
);
1542 /* _GSocket_Input_Timeout:
1543 * For blocking sockets, wait until data is available or
1544 * until timeout ellapses.
1546 GSocketError
GSocket::Input_Timeout()
1552 /* Linux select() will overwrite the struct on return */
1553 tv
.tv_sec
= (m_timeout
/ 1000);
1554 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1556 if (!m_non_blocking
)
1558 wxFD_ZERO(&readfds
);
1559 wxFD_SET(m_fd
, &readfds
);
1560 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1563 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1564 m_error
= GSOCK_TIMEDOUT
;
1565 return GSOCK_TIMEDOUT
;
1570 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1571 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1572 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1573 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1574 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1575 m_error
= GSOCK_TIMEDOUT
;
1576 return GSOCK_TIMEDOUT
;
1580 return GSOCK_NOERROR
;
1583 /* _GSocket_Output_Timeout:
1584 * For blocking sockets, wait until data can be sent without
1585 * blocking or until timeout ellapses.
1587 GSocketError
GSocket::Output_Timeout()
1593 /* Linux select() will overwrite the struct on return */
1594 tv
.tv_sec
= (m_timeout
/ 1000);
1595 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1597 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1599 if (!m_non_blocking
)
1601 wxFD_ZERO(&writefds
);
1602 wxFD_SET(m_fd
, &writefds
);
1603 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1606 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1607 m_error
= GSOCK_TIMEDOUT
;
1608 return GSOCK_TIMEDOUT
;
1613 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1614 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1615 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1616 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1617 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1618 m_error
= GSOCK_TIMEDOUT
;
1619 return GSOCK_TIMEDOUT
;
1622 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1624 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1628 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1633 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1636 return GSOCK_NOERROR
;
1639 int GSocket::Recv_Stream(char *buffer
, int size
)
1644 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1646 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1651 int GSocket::Recv_Dgram(char *buffer
, int size
)
1654 WX_SOCKLEN_T fromlen
= sizeof(from
);
1658 fromlen
= sizeof(from
);
1662 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1664 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1669 /* Translate a system address into a GSocket address */
1672 m_peer
= GAddress_new();
1675 m_error
= GSOCK_MEMERR
;
1680 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1681 if (err
!= GSOCK_NOERROR
)
1683 GAddress_destroy(m_peer
);
1692 int GSocket::Send_Stream(const char *buffer
, int size
)
1700 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1702 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1709 int GSocket::Send_Dgram(const char *buffer
, int size
)
1711 struct sockaddr
*addr
;
1717 m_error
= GSOCK_INVADDR
;
1721 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1722 if (err
!= GSOCK_NOERROR
)
1732 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1734 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1738 /* Frees memory allocated from _GAddress_translate_to */
1744 void GSocket::Detected_Read()
1748 /* Safeguard against straggling call to Detected_Read */
1749 if (m_fd
== INVALID_SOCKET
)
1754 /* If we have already detected a LOST event, then don't try
1755 * to do any further processing.
1757 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1759 m_establishing
= false;
1761 CALL_CALLBACK(this, GSOCK_LOST
);
1766 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1770 CALL_CALLBACK(this, GSOCK_INPUT
);
1774 if (m_server
&& m_stream
)
1776 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1782 /* graceful shutdown */
1783 CALL_CALLBACK(this, GSOCK_LOST
);
1788 /* Empty datagram received */
1789 CALL_CALLBACK(this, GSOCK_INPUT
);
1794 /* Do not throw a lost event in cases where the socket isn't really lost */
1795 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1797 CALL_CALLBACK(this, GSOCK_INPUT
);
1801 CALL_CALLBACK(this, GSOCK_LOST
);
1808 void GSocket::Detected_Write()
1810 /* If we have already detected a LOST event, then don't try
1811 * to do any further processing.
1813 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1815 m_establishing
= false;
1817 CALL_CALLBACK(this, GSOCK_LOST
);
1822 if (m_establishing
&& !m_server
)
1825 SOCKOPTLEN_T len
= sizeof(error
);
1827 m_establishing
= false;
1829 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1833 CALL_CALLBACK(this, GSOCK_LOST
);
1838 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1839 /* We have to fire this event by hand because CONNECTION (for clients)
1840 * and OUTPUT are internally the same and we just disabled CONNECTION
1841 * events with the above macro.
1843 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1848 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1852 /* Compatibility functions for GSocket */
1853 GSocket
*GSocket_new(void)
1855 GSocket
*newsocket
= new GSocket();
1856 if (newsocket
->IsOk())
1865 * -------------------------------------------------------------------------
1867 * -------------------------------------------------------------------------
1870 /* CHECK_ADDRESS verifies that the current address family is either
1871 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1872 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1873 * an appropiate error code.
1875 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1877 #define CHECK_ADDRESS(address, family) \
1879 if (address->m_family == GSOCK_NOFAMILY) \
1880 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1881 return address->m_error; \
1882 if (address->m_family != GSOCK_##family) \
1884 address->m_error = GSOCK_INVADDR; \
1885 return GSOCK_INVADDR; \
1889 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1891 if (address->m_family == GSOCK_NOFAMILY) \
1892 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1894 if (address->m_family != GSOCK_##family) \
1896 address->m_error = GSOCK_INVADDR; \
1902 GAddress
*GAddress_new(void)
1906 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1909 address
->m_family
= GSOCK_NOFAMILY
;
1910 address
->m_addr
= NULL
;
1916 GAddress
*GAddress_copy(GAddress
*address
)
1920 assert(address
!= NULL
);
1922 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1925 memcpy(addr2
, address
, sizeof(GAddress
));
1927 if (address
->m_addr
&& address
->m_len
> 0)
1929 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1930 if (addr2
->m_addr
== NULL
)
1935 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1941 void GAddress_destroy(GAddress
*address
)
1943 assert(address
!= NULL
);
1945 if (address
->m_addr
)
1946 free(address
->m_addr
);
1951 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1953 assert(address
!= NULL
);
1955 address
->m_family
= type
;
1958 GAddressType
GAddress_GetFamily(GAddress
*address
)
1960 assert(address
!= NULL
);
1962 return address
->m_family
;
1965 GSocketError
_GAddress_translate_from(GAddress
*address
,
1966 struct sockaddr
*addr
, int len
)
1968 address
->m_realfamily
= addr
->sa_family
;
1969 switch (addr
->sa_family
)
1972 address
->m_family
= GSOCK_INET
;
1975 address
->m_family
= GSOCK_UNIX
;
1979 address
->m_family
= GSOCK_INET6
;
1981 #endif // wxUSE_IPV6
1984 address
->m_error
= GSOCK_INVOP
;
1989 if (address
->m_addr
)
1990 free(address
->m_addr
);
1992 address
->m_len
= len
;
1993 address
->m_addr
= (struct sockaddr
*)malloc(len
);
1995 if (address
->m_addr
== NULL
)
1997 address
->m_error
= GSOCK_MEMERR
;
1998 return GSOCK_MEMERR
;
2001 memcpy(address
->m_addr
, addr
, len
);
2003 return GSOCK_NOERROR
;
2006 GSocketError
_GAddress_translate_to(GAddress
*address
,
2007 struct sockaddr
**addr
, int *len
)
2009 if (!address
->m_addr
)
2011 address
->m_error
= GSOCK_INVADDR
;
2012 return GSOCK_INVADDR
;
2015 *len
= address
->m_len
;
2016 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
2019 address
->m_error
= GSOCK_MEMERR
;
2020 return GSOCK_MEMERR
;
2023 memcpy(*addr
, address
->m_addr
, address
->m_len
);
2024 return GSOCK_NOERROR
;
2028 * -------------------------------------------------------------------------
2029 * Internet address family
2030 * -------------------------------------------------------------------------
2033 GSocketError
_GAddress_Init_INET(GAddress
*address
)
2035 address
->m_len
= sizeof(struct sockaddr_in
);
2036 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2037 if (address
->m_addr
== NULL
)
2039 address
->m_error
= GSOCK_MEMERR
;
2040 return GSOCK_MEMERR
;
2043 address
->m_family
= GSOCK_INET
;
2044 address
->m_realfamily
= PF_INET
;
2045 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
2046 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
2048 return GSOCK_NOERROR
;
2051 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
2054 struct in_addr
*addr
;
2056 assert(address
!= NULL
);
2058 CHECK_ADDRESS(address
, INET
);
2060 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2062 /* If it is a numeric host name, convert it now */
2063 #if defined(HAVE_INET_ATON)
2064 if (inet_aton(hostname
, addr
) == 0)
2066 #elif defined(HAVE_INET_ADDR)
2067 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
2070 /* Use gethostbyname by default */
2072 int val
= 1; /* VA doesn't like constants in conditional expressions */
2077 struct in_addr
*array_addr
;
2079 /* It is a real name, we solve it */
2081 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2082 struct hostent_data buffer
;
2087 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
2090 /* Reset to invalid address */
2091 addr
->s_addr
= INADDR_NONE
;
2092 address
->m_error
= GSOCK_NOHOST
;
2093 return GSOCK_NOHOST
;
2096 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
2097 addr
->s_addr
= array_addr
[0].s_addr
;
2100 return GSOCK_NOERROR
;
2104 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
2106 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
2109 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
2111 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
2114 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
2115 unsigned long hostaddr
)
2117 struct in_addr
*addr
;
2119 assert(address
!= NULL
);
2121 CHECK_ADDRESS(address
, INET
);
2123 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2124 addr
->s_addr
= htonl(hostaddr
);
2126 return GSOCK_NOERROR
;
2129 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
2130 const char *protocol
)
2133 struct sockaddr_in
*addr
;
2135 assert(address
!= NULL
);
2136 CHECK_ADDRESS(address
, INET
);
2140 address
->m_error
= GSOCK_INVPORT
;
2141 return GSOCK_INVPORT
;
2144 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2145 struct servent_data buffer
;
2149 struct servent serv
;
2150 se
= wxGetservbyname_r(port
, protocol
, &serv
,
2151 (void*)&buffer
, sizeof(buffer
));
2154 /* the cast to int suppresses compiler warnings about subscript having the
2156 if (isdigit((int)port
[0]))
2160 port_int
= atoi(port
);
2161 addr
= (struct sockaddr_in
*)address
->m_addr
;
2162 addr
->sin_port
= htons(port_int
);
2163 return GSOCK_NOERROR
;
2166 address
->m_error
= GSOCK_INVPORT
;
2167 return GSOCK_INVPORT
;
2170 addr
= (struct sockaddr_in
*)address
->m_addr
;
2171 addr
->sin_port
= se
->s_port
;
2173 return GSOCK_NOERROR
;
2176 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
2178 struct sockaddr_in
*addr
;
2180 assert(address
!= NULL
);
2181 CHECK_ADDRESS(address
, INET
);
2183 addr
= (struct sockaddr_in
*)address
->m_addr
;
2184 addr
->sin_port
= htons(port
);
2186 return GSOCK_NOERROR
;
2189 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2193 struct sockaddr_in
*addr
;
2195 assert(address
!= NULL
);
2196 CHECK_ADDRESS(address
, INET
);
2198 addr
= (struct sockaddr_in
*)address
->m_addr
;
2199 addr_buf
= (char *)&(addr
->sin_addr
);
2201 struct hostent temphost
;
2202 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2203 struct hostent_data buffer
;
2208 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
2209 (void*)&buffer
, sizeof(buffer
), &err
);
2212 address
->m_error
= GSOCK_NOHOST
;
2213 return GSOCK_NOHOST
;
2216 strncpy(hostname
, he
->h_name
, sbuf
);
2218 return GSOCK_NOERROR
;
2221 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
2223 struct sockaddr_in
*addr
;
2225 assert(address
!= NULL
);
2226 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2228 addr
= (struct sockaddr_in
*)address
->m_addr
;
2230 return ntohl(addr
->sin_addr
.s_addr
);
2233 unsigned short GAddress_INET_GetPort(GAddress
*address
)
2235 struct sockaddr_in
*addr
;
2237 assert(address
!= NULL
);
2238 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2240 addr
= (struct sockaddr_in
*)address
->m_addr
;
2241 return ntohs(addr
->sin_port
);
2246 * -------------------------------------------------------------------------
2247 * Internet IPv6 address family
2248 * -------------------------------------------------------------------------
2251 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
2253 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
2254 address
->m_len
= sizeof(struct sockaddr_in6
);
2255 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2256 if (address
->m_addr
== NULL
)
2258 address
->m_error
= GSOCK_MEMERR
;
2259 return GSOCK_MEMERR
;
2261 memset(address
->m_addr
,0,address
->m_len
);
2263 address
->m_family
= GSOCK_INET6
;
2264 address
->m_realfamily
= AF_INET6
;
2265 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
2266 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
2268 return GSOCK_NOERROR
;
2271 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
2273 assert(address
!= NULL
);
2274 CHECK_ADDRESS(address
, INET6
);
2277 memset( & hints
, 0, sizeof( hints
) );
2278 hints
.ai_family
= AF_INET6
;
2279 addrinfo
* info
= 0;
2280 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
2282 address
->m_error
= GSOCK_NOHOST
;
2283 return GSOCK_NOHOST
;
2286 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
2287 freeaddrinfo( info
);
2288 return GSOCK_NOERROR
;
2291 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
2293 assert(address
!= NULL
);
2295 CHECK_ADDRESS(address
, INET6
);
2297 struct in6_addr addr
;
2298 memset( & addr
, 0, sizeof( addr
) );
2299 return GAddress_INET6_SetHostAddress(address
, addr
);
2301 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
2302 struct in6_addr hostaddr
)
2304 assert(address
!= NULL
);
2306 CHECK_ADDRESS(address
, INET6
);
2308 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
2310 return GSOCK_NOERROR
;
2313 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
2314 const char *protocol
)
2317 struct sockaddr_in6
*addr
;
2319 assert(address
!= NULL
);
2320 CHECK_ADDRESS(address
, INET6
);
2324 address
->m_error
= GSOCK_INVPORT
;
2325 return GSOCK_INVPORT
;
2328 se
= getservbyname(port
, protocol
);
2331 if (isdigit(port
[0]))
2335 port_int
= atoi(port
);
2336 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2337 addr
->sin6_port
= htons((u_short
) port_int
);
2338 return GSOCK_NOERROR
;
2341 address
->m_error
= GSOCK_INVPORT
;
2342 return GSOCK_INVPORT
;
2345 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2346 addr
->sin6_port
= se
->s_port
;
2348 return GSOCK_NOERROR
;
2351 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
2353 struct sockaddr_in6
*addr
;
2355 assert(address
!= NULL
);
2356 CHECK_ADDRESS(address
, INET6
);
2358 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2359 addr
->sin6_port
= htons(port
);
2361 return GSOCK_NOERROR
;
2364 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2368 struct sockaddr_in6
*addr
;
2370 assert(address
!= NULL
);
2371 CHECK_ADDRESS(address
, INET6
);
2373 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2374 addr_buf
= (char *)&(addr
->sin6_addr
);
2376 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
2379 address
->m_error
= GSOCK_NOHOST
;
2380 return GSOCK_NOHOST
;
2383 strncpy(hostname
, he
->h_name
, sbuf
);
2385 return GSOCK_NOERROR
;
2388 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
2390 assert(address
!= NULL
);
2391 assert(hostaddr
!= NULL
);
2392 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
2393 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
2394 return GSOCK_NOERROR
;
2397 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2399 assert(address
!= NULL
);
2400 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2402 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2405 #endif // wxUSE_IPV6
2408 * -------------------------------------------------------------------------
2409 * Unix address family
2410 * -------------------------------------------------------------------------
2413 #ifndef __VISAGECPP__
2414 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2416 address
->m_len
= sizeof(struct sockaddr_un
);
2417 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2418 if (address
->m_addr
== NULL
)
2420 address
->m_error
= GSOCK_MEMERR
;
2421 return GSOCK_MEMERR
;
2424 address
->m_family
= GSOCK_UNIX
;
2425 address
->m_realfamily
= PF_UNIX
;
2426 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2427 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2429 return GSOCK_NOERROR
;
2432 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2434 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2436 struct sockaddr_un
*addr
;
2438 assert(address
!= NULL
);
2440 CHECK_ADDRESS(address
, UNIX
);
2442 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2443 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2444 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2446 return GSOCK_NOERROR
;
2449 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2451 struct sockaddr_un
*addr
;
2453 assert(address
!= NULL
);
2454 CHECK_ADDRESS(address
, UNIX
);
2456 addr
= (struct sockaddr_un
*)address
->m_addr
;
2458 strncpy(path
, addr
->sun_path
, sbuf
);
2460 return GSOCK_NOERROR
;
2462 #endif /* !defined(__VISAGECPP__) */
2463 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */