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
));
1290 /* GSocket_SetNonBlocking:
1291 * Sets the socket to non-blocking mode. All IO calls will return
1294 void GSocket::SetNonBlocking(bool non_block
)
1298 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1300 m_non_blocking
= non_block
;
1303 /* GSocket_SetTimeout:
1304 * Sets the timeout for blocking calls. Time is expressed in
1307 void GSocket::SetTimeout(unsigned long millisec
)
1311 m_timeout
= millisec
;
1314 /* GSocket_GetError:
1315 * Returns the last error occurred for this socket. Note that successful
1316 * operations do not clear this back to GSOCK_NOERROR, so use it only
1319 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1329 * There is data to be read in the input buffer. If, after a read
1330 * operation, there is still data available, the callback function will
1333 * The socket is available for writing. That is, the next write call
1334 * won't block. This event is generated only once, when the connection is
1335 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1336 * when the output buffer empties again. This means that the app should
1337 * assume that it can write since the first OUTPUT event, and no more
1338 * OUTPUT events will be generated unless an error occurs.
1340 * Connection successfully established, for client sockets, or incoming
1341 * client connection, for server sockets. Wait for this event (also watch
1342 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1344 * The connection is lost (or a connection request failed); this could
1345 * be due to a failure, or due to the peer closing it gracefully.
1348 /* GSocket_SetCallback:
1349 * Enables the callbacks specified by 'flags'. Note that 'flags'
1350 * may be a combination of flags OR'ed toghether, so the same
1351 * callback function can be made to accept different events.
1352 * The callback function must have the following prototype:
1354 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1356 void GSocket::SetCallback(GSocketEventFlags flags
,
1357 GSocketCallback callback
, char *cdata
)
1363 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1365 if ((flags
& (1 << count
)) != 0)
1367 m_cbacks
[count
] = callback
;
1368 m_data
[count
] = cdata
;
1373 /* GSocket_UnsetCallback:
1374 * Disables all callbacks specified by 'flags', which may be a
1375 * combination of flags OR'ed toghether.
1377 void GSocket::UnsetCallback(GSocketEventFlags flags
)
1383 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1385 if ((flags
& (1 << count
)) != 0)
1387 m_cbacks
[count
] = NULL
;
1388 m_data
[count
] = NULL
;
1393 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1394 void *optval
, int *optlen
)
1396 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1397 return GSOCK_NOERROR
;
1399 return GSOCK_OPTERR
;
1402 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1403 const void *optval
, int optlen
)
1405 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1406 return GSOCK_NOERROR
;
1408 return GSOCK_OPTERR
;
1411 #define CALL_CALLBACK(socket, event) { \
1412 socket->Disable(event); \
1413 if (socket->m_cbacks[event]) \
1414 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1418 void GSocket::Enable(GSocketEvent event
)
1422 m_detected
&= ~(1 << event
);
1423 GSocketManager::Get()->Install_Callback(this, event
);
1427 void GSocket::Disable(GSocketEvent event
)
1431 m_detected
|= (1 << event
);
1432 GSocketManager::Get()->Uninstall_Callback(this, event
);
1436 /* _GSocket_Input_Timeout:
1437 * For blocking sockets, wait until data is available or
1438 * until timeout ellapses.
1440 GSocketError
GSocket::Input_Timeout()
1446 /* Linux select() will overwrite the struct on return */
1447 tv
.tv_sec
= (m_timeout
/ 1000);
1448 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1450 if (!m_non_blocking
)
1452 wxFD_ZERO(&readfds
);
1453 wxFD_SET(m_fd
, &readfds
);
1454 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1457 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1458 m_error
= GSOCK_TIMEDOUT
;
1459 return GSOCK_TIMEDOUT
;
1464 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1465 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1466 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1467 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1468 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1469 m_error
= GSOCK_TIMEDOUT
;
1470 return GSOCK_TIMEDOUT
;
1474 return GSOCK_NOERROR
;
1477 /* _GSocket_Output_Timeout:
1478 * For blocking sockets, wait until data can be sent without
1479 * blocking or until timeout ellapses.
1481 GSocketError
GSocket::Output_Timeout()
1487 /* Linux select() will overwrite the struct on return */
1488 tv
.tv_sec
= (m_timeout
/ 1000);
1489 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1491 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1493 if (!m_non_blocking
)
1495 wxFD_ZERO(&writefds
);
1496 wxFD_SET(m_fd
, &writefds
);
1497 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1500 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1501 m_error
= GSOCK_TIMEDOUT
;
1502 return GSOCK_TIMEDOUT
;
1507 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1508 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1509 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1510 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1511 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1512 m_error
= GSOCK_TIMEDOUT
;
1513 return GSOCK_TIMEDOUT
;
1516 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1518 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1522 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1527 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1530 return GSOCK_NOERROR
;
1533 int GSocket::Recv_Stream(char *buffer
, int size
)
1538 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1540 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1545 int GSocket::Recv_Dgram(char *buffer
, int size
)
1548 WX_SOCKLEN_T fromlen
= sizeof(from
);
1552 fromlen
= sizeof(from
);
1556 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1558 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1563 /* Translate a system address into a GSocket address */
1566 m_peer
= GAddress_new();
1569 m_error
= GSOCK_MEMERR
;
1574 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1575 if (err
!= GSOCK_NOERROR
)
1577 GAddress_destroy(m_peer
);
1586 int GSocket::Send_Stream(const char *buffer
, int size
)
1594 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1596 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1603 int GSocket::Send_Dgram(const char *buffer
, int size
)
1605 struct sockaddr
*addr
;
1611 m_error
= GSOCK_INVADDR
;
1615 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1616 if (err
!= GSOCK_NOERROR
)
1626 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1628 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1632 /* Frees memory allocated from _GAddress_translate_to */
1638 void GSocket::Detected_Read()
1642 /* Safeguard against straggling call to Detected_Read */
1643 if (m_fd
== INVALID_SOCKET
)
1648 /* If we have already detected a LOST event, then don't try
1649 * to do any further processing.
1651 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1653 m_establishing
= false;
1655 CALL_CALLBACK(this, GSOCK_LOST
);
1660 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1664 CALL_CALLBACK(this, GSOCK_INPUT
);
1668 if (m_server
&& m_stream
)
1670 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1676 /* graceful shutdown */
1677 CALL_CALLBACK(this, GSOCK_LOST
);
1682 /* Empty datagram received */
1683 CALL_CALLBACK(this, GSOCK_INPUT
);
1688 /* Do not throw a lost event in cases where the socket isn't really lost */
1689 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1691 CALL_CALLBACK(this, GSOCK_INPUT
);
1695 CALL_CALLBACK(this, GSOCK_LOST
);
1702 void GSocket::Detected_Write()
1704 /* If we have already detected a LOST event, then don't try
1705 * to do any further processing.
1707 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1709 m_establishing
= false;
1711 CALL_CALLBACK(this, GSOCK_LOST
);
1716 if (m_establishing
&& !m_server
)
1719 SOCKOPTLEN_T len
= sizeof(error
);
1721 m_establishing
= false;
1723 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1727 CALL_CALLBACK(this, GSOCK_LOST
);
1732 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1733 /* We have to fire this event by hand because CONNECTION (for clients)
1734 * and OUTPUT are internally the same and we just disabled CONNECTION
1735 * events with the above macro.
1737 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1742 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1746 /* Compatibility functions for GSocket */
1747 GSocket
*GSocket_new(void)
1749 GSocket
*newsocket
= new GSocket();
1750 if (newsocket
->IsOk())
1759 * -------------------------------------------------------------------------
1761 * -------------------------------------------------------------------------
1764 /* CHECK_ADDRESS verifies that the current address family is either
1765 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1766 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1767 * an appropiate error code.
1769 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1771 #define CHECK_ADDRESS(address, family) \
1773 if (address->m_family == GSOCK_NOFAMILY) \
1774 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1775 return address->m_error; \
1776 if (address->m_family != GSOCK_##family) \
1778 address->m_error = GSOCK_INVADDR; \
1779 return GSOCK_INVADDR; \
1783 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1785 if (address->m_family == GSOCK_NOFAMILY) \
1786 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1788 if (address->m_family != GSOCK_##family) \
1790 address->m_error = GSOCK_INVADDR; \
1796 GAddress
*GAddress_new(void)
1800 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1803 address
->m_family
= GSOCK_NOFAMILY
;
1804 address
->m_addr
= NULL
;
1810 GAddress
*GAddress_copy(GAddress
*address
)
1814 assert(address
!= NULL
);
1816 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1819 memcpy(addr2
, address
, sizeof(GAddress
));
1821 if (address
->m_addr
&& address
->m_len
> 0)
1823 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1824 if (addr2
->m_addr
== NULL
)
1829 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1835 void GAddress_destroy(GAddress
*address
)
1837 assert(address
!= NULL
);
1839 if (address
->m_addr
)
1840 free(address
->m_addr
);
1845 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1847 assert(address
!= NULL
);
1849 address
->m_family
= type
;
1852 GAddressType
GAddress_GetFamily(GAddress
*address
)
1854 assert(address
!= NULL
);
1856 return address
->m_family
;
1859 GSocketError
_GAddress_translate_from(GAddress
*address
,
1860 struct sockaddr
*addr
, int len
)
1862 address
->m_realfamily
= addr
->sa_family
;
1863 switch (addr
->sa_family
)
1866 address
->m_family
= GSOCK_INET
;
1869 address
->m_family
= GSOCK_UNIX
;
1873 address
->m_family
= GSOCK_INET6
;
1875 #endif // wxUSE_IPV6
1878 address
->m_error
= GSOCK_INVOP
;
1883 if (address
->m_addr
)
1884 free(address
->m_addr
);
1886 address
->m_len
= len
;
1887 address
->m_addr
= (struct sockaddr
*)malloc(len
);
1889 if (address
->m_addr
== NULL
)
1891 address
->m_error
= GSOCK_MEMERR
;
1892 return GSOCK_MEMERR
;
1895 memcpy(address
->m_addr
, addr
, len
);
1897 return GSOCK_NOERROR
;
1900 GSocketError
_GAddress_translate_to(GAddress
*address
,
1901 struct sockaddr
**addr
, int *len
)
1903 if (!address
->m_addr
)
1905 address
->m_error
= GSOCK_INVADDR
;
1906 return GSOCK_INVADDR
;
1909 *len
= address
->m_len
;
1910 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
1913 address
->m_error
= GSOCK_MEMERR
;
1914 return GSOCK_MEMERR
;
1917 memcpy(*addr
, address
->m_addr
, address
->m_len
);
1918 return GSOCK_NOERROR
;
1922 * -------------------------------------------------------------------------
1923 * Internet address family
1924 * -------------------------------------------------------------------------
1927 GSocketError
_GAddress_Init_INET(GAddress
*address
)
1929 address
->m_len
= sizeof(struct sockaddr_in
);
1930 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1931 if (address
->m_addr
== NULL
)
1933 address
->m_error
= GSOCK_MEMERR
;
1934 return GSOCK_MEMERR
;
1937 address
->m_family
= GSOCK_INET
;
1938 address
->m_realfamily
= PF_INET
;
1939 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
1940 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
1942 return GSOCK_NOERROR
;
1945 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
1948 struct in_addr
*addr
;
1950 assert(address
!= NULL
);
1952 CHECK_ADDRESS(address
, INET
);
1954 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1956 /* If it is a numeric host name, convert it now */
1957 #if defined(HAVE_INET_ATON)
1958 if (inet_aton(hostname
, addr
) == 0)
1960 #elif defined(HAVE_INET_ADDR)
1961 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
1964 /* Use gethostbyname by default */
1966 int val
= 1; /* VA doesn't like constants in conditional expressions */
1971 struct in_addr
*array_addr
;
1973 /* It is a real name, we solve it */
1975 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1976 struct hostent_data buffer
;
1981 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
1984 /* Reset to invalid address */
1985 addr
->s_addr
= INADDR_NONE
;
1986 address
->m_error
= GSOCK_NOHOST
;
1987 return GSOCK_NOHOST
;
1990 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
1991 addr
->s_addr
= array_addr
[0].s_addr
;
1994 return GSOCK_NOERROR
;
1998 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
2000 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
2003 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
2005 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
2008 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
2009 unsigned long hostaddr
)
2011 struct in_addr
*addr
;
2013 assert(address
!= NULL
);
2015 CHECK_ADDRESS(address
, INET
);
2017 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2018 addr
->s_addr
= htonl(hostaddr
);
2020 return GSOCK_NOERROR
;
2023 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
2024 const char *protocol
)
2027 struct sockaddr_in
*addr
;
2029 assert(address
!= NULL
);
2030 CHECK_ADDRESS(address
, INET
);
2034 address
->m_error
= GSOCK_INVPORT
;
2035 return GSOCK_INVPORT
;
2038 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2039 struct servent_data buffer
;
2043 struct servent serv
;
2044 se
= wxGetservbyname_r(port
, protocol
, &serv
,
2045 (void*)&buffer
, sizeof(buffer
));
2048 /* the cast to int suppresses compiler warnings about subscript having the
2050 if (isdigit((int)port
[0]))
2054 port_int
= atoi(port
);
2055 addr
= (struct sockaddr_in
*)address
->m_addr
;
2056 addr
->sin_port
= htons(port_int
);
2057 return GSOCK_NOERROR
;
2060 address
->m_error
= GSOCK_INVPORT
;
2061 return GSOCK_INVPORT
;
2064 addr
= (struct sockaddr_in
*)address
->m_addr
;
2065 addr
->sin_port
= se
->s_port
;
2067 return GSOCK_NOERROR
;
2070 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
2072 struct sockaddr_in
*addr
;
2074 assert(address
!= NULL
);
2075 CHECK_ADDRESS(address
, INET
);
2077 addr
= (struct sockaddr_in
*)address
->m_addr
;
2078 addr
->sin_port
= htons(port
);
2080 return GSOCK_NOERROR
;
2083 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2087 struct sockaddr_in
*addr
;
2089 assert(address
!= NULL
);
2090 CHECK_ADDRESS(address
, INET
);
2092 addr
= (struct sockaddr_in
*)address
->m_addr
;
2093 addr_buf
= (char *)&(addr
->sin_addr
);
2095 struct hostent temphost
;
2096 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2097 struct hostent_data buffer
;
2102 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
2103 (void*)&buffer
, sizeof(buffer
), &err
);
2106 address
->m_error
= GSOCK_NOHOST
;
2107 return GSOCK_NOHOST
;
2110 strncpy(hostname
, he
->h_name
, sbuf
);
2112 return GSOCK_NOERROR
;
2115 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
2117 struct sockaddr_in
*addr
;
2119 assert(address
!= NULL
);
2120 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2122 addr
= (struct sockaddr_in
*)address
->m_addr
;
2124 return ntohl(addr
->sin_addr
.s_addr
);
2127 unsigned short GAddress_INET_GetPort(GAddress
*address
)
2129 struct sockaddr_in
*addr
;
2131 assert(address
!= NULL
);
2132 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2134 addr
= (struct sockaddr_in
*)address
->m_addr
;
2135 return ntohs(addr
->sin_port
);
2140 * -------------------------------------------------------------------------
2141 * Internet IPv6 address family
2142 * -------------------------------------------------------------------------
2145 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
2147 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
2148 address
->m_len
= sizeof(struct sockaddr_in6
);
2149 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2150 if (address
->m_addr
== NULL
)
2152 address
->m_error
= GSOCK_MEMERR
;
2153 return GSOCK_MEMERR
;
2155 memset(address
->m_addr
,0,address
->m_len
);
2157 address
->m_family
= GSOCK_INET6
;
2158 address
->m_realfamily
= AF_INET6
;
2159 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
2160 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
2162 return GSOCK_NOERROR
;
2165 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
2167 assert(address
!= NULL
);
2168 CHECK_ADDRESS(address
, INET6
);
2171 memset( & hints
, 0, sizeof( hints
) );
2172 hints
.ai_family
= AF_INET6
;
2173 addrinfo
* info
= 0;
2174 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
2176 address
->m_error
= GSOCK_NOHOST
;
2177 return GSOCK_NOHOST
;
2180 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
2181 freeaddrinfo( info
);
2182 return GSOCK_NOERROR
;
2185 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
2187 assert(address
!= NULL
);
2189 CHECK_ADDRESS(address
, INET6
);
2191 struct in6_addr addr
;
2192 memset( & addr
, 0, sizeof( addr
) );
2193 return GAddress_INET6_SetHostAddress(address
, addr
);
2195 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
2196 struct in6_addr hostaddr
)
2198 assert(address
!= NULL
);
2200 CHECK_ADDRESS(address
, INET6
);
2202 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
2204 return GSOCK_NOERROR
;
2207 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
2208 const char *protocol
)
2211 struct sockaddr_in6
*addr
;
2213 assert(address
!= NULL
);
2214 CHECK_ADDRESS(address
, INET6
);
2218 address
->m_error
= GSOCK_INVPORT
;
2219 return GSOCK_INVPORT
;
2222 se
= getservbyname(port
, protocol
);
2225 if (isdigit(port
[0]))
2229 port_int
= atoi(port
);
2230 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2231 addr
->sin6_port
= htons((u_short
) port_int
);
2232 return GSOCK_NOERROR
;
2235 address
->m_error
= GSOCK_INVPORT
;
2236 return GSOCK_INVPORT
;
2239 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2240 addr
->sin6_port
= se
->s_port
;
2242 return GSOCK_NOERROR
;
2245 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
2247 struct sockaddr_in6
*addr
;
2249 assert(address
!= NULL
);
2250 CHECK_ADDRESS(address
, INET6
);
2252 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2253 addr
->sin6_port
= htons(port
);
2255 return GSOCK_NOERROR
;
2258 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2262 struct sockaddr_in6
*addr
;
2264 assert(address
!= NULL
);
2265 CHECK_ADDRESS(address
, INET6
);
2267 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2268 addr_buf
= (char *)&(addr
->sin6_addr
);
2270 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
2273 address
->m_error
= GSOCK_NOHOST
;
2274 return GSOCK_NOHOST
;
2277 strncpy(hostname
, he
->h_name
, sbuf
);
2279 return GSOCK_NOERROR
;
2282 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
2284 assert(address
!= NULL
);
2285 assert(hostaddr
!= NULL
);
2286 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
2287 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
2288 return GSOCK_NOERROR
;
2291 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2293 assert(address
!= NULL
);
2294 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2296 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2299 #endif // wxUSE_IPV6
2302 * -------------------------------------------------------------------------
2303 * Unix address family
2304 * -------------------------------------------------------------------------
2307 #ifndef __VISAGECPP__
2308 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2310 address
->m_len
= sizeof(struct sockaddr_un
);
2311 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2312 if (address
->m_addr
== NULL
)
2314 address
->m_error
= GSOCK_MEMERR
;
2315 return GSOCK_MEMERR
;
2318 address
->m_family
= GSOCK_UNIX
;
2319 address
->m_realfamily
= PF_UNIX
;
2320 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2321 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2323 return GSOCK_NOERROR
;
2326 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2328 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2330 struct sockaddr_un
*addr
;
2332 assert(address
!= NULL
);
2334 CHECK_ADDRESS(address
, UNIX
);
2336 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2337 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2338 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2340 return GSOCK_NOERROR
;
2343 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2345 struct sockaddr_un
*addr
;
2347 assert(address
!= NULL
);
2348 CHECK_ADDRESS(address
, UNIX
);
2350 addr
= (struct sockaddr_un
*)address
->m_addr
;
2352 strncpy(path
, addr
->sun_path
, sbuf
);
2354 return GSOCK_NOERROR
;
2356 #endif /* !defined(__VISAGECPP__) */
2357 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */