1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Authors: David Elliott (C++ conversion, maintainer)
8 * Guillermo Rodriguez Garcia <guille@iies.es>
9 * Purpose: GSocket main Unix and OS/2 file
10 * Licence: The wxWindows licence
12 * -------------------------------------------------------------------------
15 #if defined(__WATCOMC__)
16 #include "wx/wxprec.h"
21 #ifndef __GSOCKET_STANDALONE__
23 #include "wx/private/gsocketiohandler.h"
24 #include "wx/thread.h" // for wxThread::IsMain() used in assert
27 #if defined(__VISAGECPP__)
28 #define BSD_SELECT /* use Berkeley Sockets select */
31 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
34 #include <sys/types.h>
39 #include <netinet/in.h>
42 #include <sys/ioctl.h>
44 #ifdef HAVE_SYS_SELECT_H
45 # include <sys/select.h>
52 u_char sun_len
; /* sockaddr len including null */
53 u_char sun_family
; /* AF_UNIX */
54 char sun_path
[108]; /* path name (gag) */
57 #include <sys/socket.h>
63 #include <netinet/in.h>
64 #include <arpa/inet.h>
71 #include <machine/endian.h>
77 #define EBADF SOCEBADF
83 #include <sys/socket.h>
84 #include <sys/ioctl.h>
85 #include <sys/select.h>
87 #define close(a) soclose(a)
88 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
89 int _System
bsdselect(int,
94 int _System
soclose(int);
98 #include <sys/select.h>
106 # include <sys/filio.h>
109 # include <bstring.h>
112 # include <strings.h>
119 # define WX_SOCKLEN_T unsigned int
123 # define WX_SOCKLEN_T socklen_t
125 # elif defined(__WXMAC__)
126 # define WX_SOCKLEN_T socklen_t
128 # define WX_SOCKLEN_T int
132 #endif /* SOCKLEN_T */
135 #define SOCKOPTLEN_T WX_SOCKLEN_T
139 * MSW defines this, Unices don't.
141 #ifndef INVALID_SOCKET
142 #define INVALID_SOCKET -1
145 /* UnixWare reportedly needs this for FIONBIO definition */
147 #include <sys/filio.h>
151 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
152 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
155 #define INADDR_NONE INADDR_BROADCAST
158 #if defined(__VISAGECPP__) || defined(__WATCOMC__)
160 #define MASK_SIGNAL() {
161 #define UNMASK_SIGNAL() }
164 extern "C" { typedef void (*wxSigHandler
)(int); }
166 #define MASK_SIGNAL() \
168 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
170 #define UNMASK_SIGNAL() \
171 signal(SIGPIPE, old_handler); \
176 /* If a SIGPIPE is issued by a socket call on a remotely closed socket,
177 the program will "crash" unless it explicitly handles the SIGPIPE.
178 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
179 use SO_NOSIGPIPE (if available), the BSD equivalent. */
181 # define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
182 #else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
183 # define GSOCKET_MSG_NOSIGNAL 0
184 #endif /* MSG_NOSIGNAL */
186 #ifndef __GSOCKET_STANDALONE__
187 # include "wx/unix/gsockunx.h"
188 # include "wx/unix/private.h"
189 # include "wx/gsocket.h"
190 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
191 # include "wx/thread.h"
194 # include "gsockunx.h"
195 # include "gsocket.h"
199 #endif /* __GSOCKET_STANDALONE__ */
201 #if defined(HAVE_GETHOSTBYNAME)
202 static struct hostent
* deepCopyHostent(struct hostent
*h
,
203 const struct hostent
*he
,
204 char *buffer
, int size
, int *err
)
206 /* copy old structure */
207 memcpy(h
, he
, sizeof(struct hostent
));
210 int len
= strlen(h
->h_name
);
216 memcpy(buffer
, h
->h_name
, len
);
220 /* track position in the buffer */
223 /* reuse len to store address length */
226 /* ensure pointer alignment */
227 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
228 if(misalign
< sizeof(char *))
231 /* leave space for pointer list */
232 char **p
= h
->h_addr_list
, **q
;
233 char **h_addr_list
= (char **)(buffer
+ pos
);
235 pos
+= sizeof(char *);
237 /* copy addresses and fill new pointer list */
238 for (p
= h
->h_addr_list
, q
= h_addr_list
; *p
!= 0; p
++, q
++)
240 if (size
< pos
+ len
)
245 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
246 *q
= buffer
+ pos
; /* set copied pointer to copied content */
249 *++q
= 0; /* null terminate the pointer list */
250 h
->h_addr_list
= h_addr_list
; /* copy pointer to pointers */
252 /* ensure word alignment of pointers */
253 misalign
= sizeof(char *) - pos%sizeof
(char *);
254 if(misalign
< sizeof(char *))
257 /* leave space for pointer list */
259 char **h_aliases
= (char **)(buffer
+ pos
);
261 pos
+= sizeof(char *);
263 /* copy aliases and fill new pointer list */
264 for (p
= h
->h_aliases
, q
= h_aliases
; *p
!= 0; p
++, q
++)
267 if (size
<= pos
+ len
)
272 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
273 buffer
[pos
+ len
] = '\0';
274 *q
= buffer
+ pos
; /* set copied pointer to copied content */
277 *++q
= 0; /* null terminate the pointer list */
278 h
->h_aliases
= h_aliases
; /* copy pointer to pointers */
284 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
285 static wxMutex nameLock
;
287 struct hostent
* wxGethostbyname_r(const char *hostname
, struct hostent
*h
,
288 void *buffer
, int size
, int *err
)
291 struct hostent
*he
= NULL
;
293 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
294 if (gethostbyname_r(hostname
, h
, (char*)buffer
, size
, &he
, err
))
296 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
297 he
= gethostbyname_r(hostname
, h
, (char*)buffer
, size
, err
);
298 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
299 if (gethostbyname_r(hostname
, h
, (struct hostent_data
*) buffer
))
306 #elif defined(HAVE_GETHOSTBYNAME)
308 wxMutexLocker
locker(nameLock
);
310 he
= gethostbyname(hostname
);
314 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
319 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
320 static wxMutex addrLock
;
322 struct hostent
* wxGethostbyaddr_r(const char *addr_buf
, int buf_size
,
323 int proto
, struct hostent
*h
,
324 void *buffer
, int size
, int *err
)
326 struct hostent
*he
= NULL
;
328 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
329 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
330 (char*)buffer
, size
, &he
, err
))
332 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
333 he
= gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
, (char*)buffer
, size
, err
);
334 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
335 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
336 (struct hostent_data
*) buffer
))
343 #elif defined(HAVE_GETHOSTBYNAME)
345 wxMutexLocker
locker(addrLock
);
347 he
= gethostbyaddr(addr_buf
, buf_size
, proto
);
351 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
356 #if defined(HAVE_GETSERVBYNAME)
357 static struct servent
* deepCopyServent(struct servent
*s
,
358 const struct servent
*se
,
359 char *buffer
, int size
)
361 /* copy plain old structure */
362 memcpy(s
, se
, sizeof(struct servent
));
365 int len
= strlen(s
->s_name
);
370 memcpy(buffer
, s
->s_name
, len
);
374 /* track position in the buffer */
378 len
= strlen(s
->s_proto
);
379 if (pos
+ len
>= size
)
383 memcpy(buffer
+ pos
, s
->s_proto
, len
);
384 buffer
[pos
+ len
] = '\0';
385 s
->s_proto
= buffer
+ pos
;
387 /* track position in the buffer */
390 /* ensure pointer alignment */
391 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
392 if(misalign
< sizeof(char *))
395 /* leave space for pointer list */
396 char **p
= s
->s_aliases
, **q
;
397 char **s_aliases
= (char **)(buffer
+ pos
);
399 pos
+= sizeof(char *);
401 /* copy addresses and fill new pointer list */
402 for (p
= s
->s_aliases
, q
= s_aliases
; *p
!= 0; p
++, q
++){
404 if (size
<= pos
+ len
)
408 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
409 buffer
[pos
+ len
] = '\0';
410 *q
= buffer
+ pos
; /* set copied pointer to copied content */
413 *++q
= 0; /* null terminate the pointer list */
414 s
->s_aliases
= s_aliases
; /* copy pointer to pointers */
419 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
420 static wxMutex servLock
;
422 struct servent
*wxGetservbyname_r(const char *port
, const char *protocol
,
423 struct servent
*serv
, void *buffer
, int size
)
425 struct servent
*se
= NULL
;
426 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
427 if (getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
, &se
))
429 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
430 se
= getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
);
431 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
432 if (getservbyname_r(port
, protocol
, serv
, (struct servent_data
*) buffer
))
436 #elif defined(HAVE_GETSERVBYNAME)
438 wxMutexLocker
locker(servLock
);
440 se
= getservbyname(port
, protocol
);
442 se
= deepCopyServent(serv
, se
, (char*)buffer
, size
);
447 /* debugging helpers */
448 #ifdef __GSOCKET_DEBUG__
449 # define GSocket_Debug(args) printf args
451 # define GSocket_Debug(args)
452 #endif /* __GSOCKET_DEBUG__ */
455 typedef struct sockaddr_storage wxSockAddr
;
457 typedef struct sockaddr wxSockAddr
;
460 /* Table of GUI-related functions. We must call them indirectly because
461 * of wxBase and GUI separation: */
465 GSocketManager
* const manager
= GSocketManager::Get();
466 return manager
&& manager
->OnInit();
469 void GSocket_Cleanup()
471 GSocketManager
* const manager
= GSocketManager::Get();
476 /* Constructors / Destructors for GSocket */
482 m_fd
= INVALID_SOCKET
;
485 for (i
=0;i
<GSOCK_MAX_EVENT
;i
++)
492 m_error
= GSOCK_NOERROR
;
495 m_gui_dependent
= NULL
;
496 m_non_blocking
= false;
500 m_timeout
= 10*60*1000;
501 /* 10 minutes * 60 sec * 1000 millisec */
502 m_establishing
= false;
503 m_use_events
= false;
504 m_initialRecvBufferSize
= -1;
505 m_initialSendBufferSize
= -1;
507 m_ok
= GSocketManager::Get()->Init_Socket(this);
510 void GSocket::Close()
515 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
516 will close the socket during Disable_Events. However, it will only do this
517 if it is being used. That is, it won't do it in a console program. To
518 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
519 if it has closed the socket which indicates to us (at runtime, instead of
520 at compile time as this had been before) that the socket has already
523 if(m_fd
!= INVALID_SOCKET
)
525 m_fd
= INVALID_SOCKET
;
532 /* Check that the socket is really shutdowned */
533 if (m_fd
!= INVALID_SOCKET
)
536 GSocketManager::Get()->Destroy_Socket(this);
540 /* Destroy private addresses */
542 GAddress_destroy(m_local
);
545 GAddress_destroy(m_peer
);
550 * Disallow further read/write operations on this socket, close
551 * the fd and disable all callbacks.
553 void GSocket::Shutdown()
559 /* Don't allow events to fire after socket has been closed */
563 /* If socket has been created, shutdown it */
564 if (m_fd
!= INVALID_SOCKET
)
570 /* Disable GUI callbacks */
571 for (evt
= 0; evt
< GSOCK_MAX_EVENT
; evt
++)
572 m_cbacks
[evt
] = NULL
;
574 m_detected
= GSOCK_LOST_FLAG
;
577 /* Address handling */
583 * Set or get the local or peer address for this socket. The 'set'
584 * functions return GSOCK_NOERROR on success, an error code otherwise.
585 * The 'get' functions return a pointer to a GAddress object on success,
586 * or NULL otherwise, in which case they set the error code of the
587 * corresponding GSocket.
590 * GSOCK_INVSOCK - the socket is not valid.
591 * GSOCK_INVADDR - the address is not valid.
593 GSocketError
GSocket::SetLocal(GAddress
*address
)
597 /* the socket must be initialized, or it must be a server */
598 if ((m_fd
!= INVALID_SOCKET
&& !m_server
))
600 m_error
= GSOCK_INVSOCK
;
601 return GSOCK_INVSOCK
;
605 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
607 m_error
= GSOCK_INVADDR
;
608 return GSOCK_INVADDR
;
612 GAddress_destroy(m_local
);
614 m_local
= GAddress_copy(address
);
616 return GSOCK_NOERROR
;
619 GSocketError
GSocket::SetPeer(GAddress
*address
)
624 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
626 m_error
= GSOCK_INVADDR
;
627 return GSOCK_INVADDR
;
631 GAddress_destroy(m_peer
);
633 m_peer
= GAddress_copy(address
);
635 return GSOCK_NOERROR
;
638 GAddress
*GSocket::GetLocal()
642 WX_SOCKLEN_T size
= sizeof(addr
);
647 /* try to get it from the m_local var first */
649 return GAddress_copy(m_local
);
651 /* else, if the socket is initialized, try getsockname */
652 if (m_fd
== INVALID_SOCKET
)
654 m_error
= GSOCK_INVSOCK
;
658 if (getsockname(m_fd
, (sockaddr
*)&addr
, (WX_SOCKLEN_T
*) &size
) < 0)
660 m_error
= GSOCK_IOERR
;
664 /* got a valid address from getsockname, create a GAddress object */
665 address
= GAddress_new();
668 m_error
= GSOCK_MEMERR
;
672 err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
);
673 if (err
!= GSOCK_NOERROR
)
675 GAddress_destroy(address
);
683 GAddress
*GSocket::GetPeer()
687 /* try to get it from the m_peer var */
689 return GAddress_copy(m_peer
);
694 /* Server specific parts */
696 /* GSocket_SetServer:
697 * Sets up this socket as a server. The local address must have been
698 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
699 * Returns GSOCK_NOERROR on success, one of the following otherwise:
702 * GSOCK_INVSOCK - the socket is in use.
703 * GSOCK_INVADDR - the local address has not been set.
704 * GSOCK_IOERR - low-level error.
706 GSocketError
GSocket::SetServer()
712 /* must not be in use */
713 if (m_fd
!= INVALID_SOCKET
)
715 m_error
= GSOCK_INVSOCK
;
716 return GSOCK_INVSOCK
;
719 /* the local addr must have been set */
722 m_error
= GSOCK_INVADDR
;
723 return GSOCK_INVADDR
;
726 /* Initialize all fields */
730 /* Create the socket */
731 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
733 if (m_fd
== INVALID_SOCKET
)
735 m_error
= GSOCK_IOERR
;
739 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
741 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
744 ioctl(m_fd
, FIONBIO
, &arg
);
748 /* allow a socket to re-bind if the socket is in the TIME_WAIT
749 state after being previously closed.
753 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
755 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
759 /* Bind to the local address,
760 * retrieve the actual address bound,
761 * and listen up to 5 connections.
763 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
766 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
767 (listen(m_fd
, 5) != 0))
770 m_error
= GSOCK_IOERR
;
774 return GSOCK_NOERROR
;
777 /* GSocket_WaitConnection:
778 * Waits for an incoming client connection. Returns a pointer to
779 * a GSocket object, or NULL if there was an error, in which case
780 * the last error field will be updated for the calling GSocket.
782 * Error codes (set in the calling GSocket)
783 * GSOCK_INVSOCK - the socket is not valid or not a server.
784 * GSOCK_TIMEDOUT - timeout, no incoming connections.
785 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
786 * GSOCK_MEMERR - couldn't allocate memory.
787 * GSOCK_IOERR - low-level error.
789 GSocket
*GSocket::WaitConnection()
792 WX_SOCKLEN_T fromlen
= sizeof(from
);
799 /* If the socket has already been created, we exit immediately */
800 if (m_fd
== INVALID_SOCKET
|| !m_server
)
802 m_error
= GSOCK_INVSOCK
;
806 /* Create a GSocket object for the new connection */
807 connection
= GSocket_new();
811 m_error
= GSOCK_MEMERR
;
815 /* Wait for a connection (with timeout) */
816 if (Input_Timeout() == GSOCK_TIMEDOUT
)
819 /* m_error set by _GSocket_Input_Timeout */
823 connection
->m_fd
= accept(m_fd
, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
825 /* Reenable CONNECTION events */
826 Enable(GSOCK_CONNECTION
);
828 if (connection
->m_fd
== INVALID_SOCKET
)
830 if (errno
== EWOULDBLOCK
)
831 m_error
= GSOCK_WOULDBLOCK
;
833 m_error
= GSOCK_IOERR
;
839 /* Initialize all fields */
840 connection
->m_server
= false;
841 connection
->m_stream
= true;
843 /* Setup the peer address field */
844 connection
->m_peer
= GAddress_new();
845 if (!connection
->m_peer
)
848 m_error
= GSOCK_MEMERR
;
852 err
= _GAddress_translate_from(connection
->m_peer
, (sockaddr
*)&from
, fromlen
);
853 if (err
!= GSOCK_NOERROR
)
860 #if defined(__EMX__) || defined(__VISAGECPP__)
861 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
863 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
866 connection
->Notify(true);
871 void GSocket::Notify(bool flag
)
873 if (flag
== m_use_events
)
875 // it is not safe to attach or detach i/o descriptor in child thread
876 wxASSERT_MSG( wxThread::IsMain(), "should be called in main thread only" );
881 void GSocket::EnableEvents(bool flag
)
884 GSocketManager::Get()->Enable_Events(this);
886 GSocketManager::Get()->Disable_Events(this);
889 bool GSocket::SetReusable()
891 /* socket must not be null, and must not be in use/already bound */
892 if (this && m_fd
== INVALID_SOCKET
)
902 bool GSocket::SetBroadcast()
904 /* socket must not be in use/already bound */
905 if (m_fd
== INVALID_SOCKET
) {
912 bool GSocket::DontDoBind()
914 /* socket must not be in use/already bound */
915 if (m_fd
== INVALID_SOCKET
) {
922 /* Client specific parts */
925 * For stream (connection oriented) sockets, GSocket_Connect() tries
926 * to establish a client connection to a server using the peer address
927 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
928 * connection has been successfully established, or one of the error
929 * codes listed below. Note that for nonblocking sockets, a return
930 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
931 * request can be completed later; you should use GSocket_Select()
932 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
933 * corresponding asynchronous events.
935 * For datagram (non connection oriented) sockets, GSocket_Connect()
936 * just sets the peer address established with GSocket_SetPeer() as
937 * default destination.
940 * GSOCK_INVSOCK - the socket is in use or not valid.
941 * GSOCK_INVADDR - the peer address has not been established.
942 * GSOCK_TIMEDOUT - timeout, the connection failed.
943 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
944 * GSOCK_MEMERR - couldn't allocate memory.
945 * GSOCK_IOERR - low-level error.
947 GSocketError
GSocket::Connect(GSocketStream stream
)
954 /* Enable CONNECTION events (needed for nonblocking connections) */
955 Enable(GSOCK_CONNECTION
);
957 if (m_fd
!= INVALID_SOCKET
)
959 m_error
= GSOCK_INVSOCK
;
960 return GSOCK_INVSOCK
;
965 m_error
= GSOCK_INVADDR
;
966 return GSOCK_INVADDR
;
969 /* Streamed or dgram socket? */
970 m_stream
= (stream
== GSOCK_STREAMED
);
972 m_establishing
= false;
974 /* Create the socket */
975 m_fd
= socket(m_peer
->m_realfamily
,
976 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
978 if (m_fd
== INVALID_SOCKET
)
980 m_error
= GSOCK_IOERR
;
984 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
986 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
989 #if defined(__EMX__) || defined(__VISAGECPP__)
990 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
992 ioctl(m_fd
, FIONBIO
, &arg
);
995 // If the reuse flag is set, use the applicable socket reuse flags(s)
998 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1000 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1004 if (m_initialRecvBufferSize
>= 0)
1005 setsockopt(m_fd
, SOL_SOCKET
, SO_RCVBUF
, (const char*)&m_initialRecvBufferSize
, sizeof(m_initialRecvBufferSize
));
1006 if (m_initialSendBufferSize
>= 0)
1007 setsockopt(m_fd
, SOL_SOCKET
, SO_SNDBUF
, (const char*)&m_initialSendBufferSize
, sizeof(m_initialSendBufferSize
));
1009 // If a local address has been set, then we need to bind to it before calling connect
1010 if (m_local
&& m_local
->m_addr
)
1012 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
1015 /* Connect it to the peer address, with a timeout (see below) */
1016 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
1018 /* We only call Enable_Events if we know we aren't shutting down the socket.
1019 * NB: Enable_Events needs to be called whether the socket is blocking or
1020 * non-blocking, it just shouldn't be called prior to knowing there is a
1021 * connection _if_ blocking sockets are being used.
1022 * If connect above returns 0, we are already connected and need to make the
1023 * call to Enable_Events now.
1026 if (m_use_events
&& (m_non_blocking
|| ret
== 0))
1033 /* If connect failed with EINPROGRESS and the GSocket object
1034 * is in blocking mode, we select() for the specified timeout
1035 * checking for writability to see if the connection request
1038 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
1040 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1043 /* m_error is set in _GSocket_Output_Timeout */
1044 return GSOCK_TIMEDOUT
;
1049 SOCKOPTLEN_T len
= sizeof(error
);
1051 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
1056 return GSOCK_NOERROR
;
1060 /* If connect failed with EINPROGRESS and the GSocket object
1061 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
1062 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
1063 * this way if the connection completes, a GSOCK_CONNECTION
1064 * event will be generated, if enabled.
1066 if ((err
== EINPROGRESS
) && (m_non_blocking
))
1068 m_establishing
= true;
1069 m_error
= GSOCK_WOULDBLOCK
;
1070 return GSOCK_WOULDBLOCK
;
1073 /* If connect failed with an error other than EINPROGRESS,
1074 * then the call to GSocket_Connect has failed.
1077 m_error
= GSOCK_IOERR
;
1082 return GSOCK_NOERROR
;
1085 /* Datagram sockets */
1087 /* GSocket_SetNonOriented:
1088 * Sets up this socket as a non-connection oriented (datagram) socket.
1089 * Before using this function, the local address must have been set
1090 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1091 * on success, or one of the following otherwise.
1094 * GSOCK_INVSOCK - the socket is in use.
1095 * GSOCK_INVADDR - the local address has not been set.
1096 * GSOCK_IOERR - low-level error.
1098 GSocketError
GSocket::SetNonOriented()
1104 if (m_fd
!= INVALID_SOCKET
)
1106 m_error
= GSOCK_INVSOCK
;
1107 return GSOCK_INVSOCK
;
1112 m_error
= GSOCK_INVADDR
;
1113 return GSOCK_INVADDR
;
1116 /* Initialize all fields */
1120 /* Create the socket */
1121 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
1123 if (m_fd
== INVALID_SOCKET
)
1125 m_error
= GSOCK_IOERR
;
1128 #if defined(__EMX__) || defined(__VISAGECPP__)
1129 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1131 ioctl(m_fd
, FIONBIO
, &arg
);
1138 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1140 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1146 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
1150 /* Bind to the local address,
1151 * and retrieve the actual address bound.
1153 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
1156 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
1159 m_error
= GSOCK_IOERR
;
1163 return GSOCK_NOERROR
;
1168 /* Like recv(), send(), ... */
1169 int GSocket::Read(char *buffer
, int size
)
1175 if (m_fd
== INVALID_SOCKET
|| m_server
)
1177 m_error
= GSOCK_INVSOCK
;
1181 /* Disable events during query of socket status */
1182 Disable(GSOCK_INPUT
);
1184 /* If the socket is blocking, wait for data (with a timeout) */
1185 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
1186 m_error
= GSOCK_TIMEDOUT
;
1187 /* Don't return here immediately, otherwise socket events would not be
1195 ret
= Recv_Stream(buffer
, size
);
1197 ret
= Recv_Dgram(buffer
, size
);
1199 /* If recv returned zero, then the connection has been gracefully closed.
1200 * Otherwise, recv has returned an error (-1), in which case we have lost the
1201 * socket only if errno does _not_ indicate that there may be more data to read.
1205 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1208 m_detected
= GSOCK_LOST_FLAG
;
1215 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1216 m_error
= GSOCK_WOULDBLOCK
;
1218 m_error
= GSOCK_IOERR
;
1222 /* Enable events again now that we are done processing */
1223 Enable(GSOCK_INPUT
);
1228 int GSocket::Write(const char *buffer
, int size
)
1234 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1236 if (m_fd
== INVALID_SOCKET
|| m_server
)
1238 m_error
= GSOCK_INVSOCK
;
1242 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1244 /* If the socket is blocking, wait for writability (with a timeout) */
1245 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1248 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1250 /* Write the data */
1252 ret
= Send_Stream(buffer
, size
);
1254 ret
= Send_Dgram(buffer
, size
);
1256 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1260 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1262 m_error
= GSOCK_WOULDBLOCK
;
1263 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1267 m_error
= GSOCK_IOERR
;
1268 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1271 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1272 * in MSW). Once the first OUTPUT event is received, users can assume
1273 * that the socket is writable until a read operation fails. Only then
1274 * will further OUTPUT events be posted.
1276 Enable(GSOCK_OUTPUT
);
1281 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1287 * Polls the socket to determine its status. This function will
1288 * check for the events specified in the 'flags' parameter, and
1289 * it will return a mask indicating which operations can be
1290 * performed. This function won't block, regardless of the
1291 * mode (blocking | nonblocking) of the socket.
1293 GSocketEventFlags
GSocket::Select(GSocketEventFlags flags
)
1297 return flags
& m_detected
;
1302 /* GSocket_SetNonBlocking:
1303 * Sets the socket to non-blocking mode. All IO calls will return
1306 void GSocket::SetNonBlocking(bool non_block
)
1310 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1312 m_non_blocking
= non_block
;
1315 /* GSocket_SetTimeout:
1316 * Sets the timeout for blocking calls. Time is expressed in
1319 void GSocket::SetTimeout(unsigned long millisec
)
1323 m_timeout
= millisec
;
1326 /* GSocket_GetError:
1327 * Returns the last error occurred for this socket. Note that successful
1328 * operations do not clear this back to GSOCK_NOERROR, so use it only
1331 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1341 * There is data to be read in the input buffer. If, after a read
1342 * operation, there is still data available, the callback function will
1345 * The socket is available for writing. That is, the next write call
1346 * won't block. This event is generated only once, when the connection is
1347 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1348 * when the output buffer empties again. This means that the app should
1349 * assume that it can write since the first OUTPUT event, and no more
1350 * OUTPUT events will be generated unless an error occurs.
1352 * Connection successfully established, for client sockets, or incoming
1353 * client connection, for server sockets. Wait for this event (also watch
1354 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1356 * The connection is lost (or a connection request failed); this could
1357 * be due to a failure, or due to the peer closing it gracefully.
1360 /* GSocket_SetCallback:
1361 * Enables the callbacks specified by 'flags'. Note that 'flags'
1362 * may be a combination of flags OR'ed toghether, so the same
1363 * callback function can be made to accept different events.
1364 * The callback function must have the following prototype:
1366 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1368 void GSocket::SetCallback(GSocketEventFlags flags
,
1369 GSocketCallback callback
, char *cdata
)
1375 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1377 if ((flags
& (1 << count
)) != 0)
1379 m_cbacks
[count
] = callback
;
1380 m_data
[count
] = cdata
;
1385 /* GSocket_UnsetCallback:
1386 * Disables all callbacks specified by 'flags', which may be a
1387 * combination of flags OR'ed toghether.
1389 void GSocket::UnsetCallback(GSocketEventFlags flags
)
1395 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1397 if ((flags
& (1 << count
)) != 0)
1399 m_cbacks
[count
] = NULL
;
1400 m_data
[count
] = NULL
;
1405 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1406 void *optval
, int *optlen
)
1408 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1409 return GSOCK_NOERROR
;
1411 return GSOCK_OPTERR
;
1414 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1415 const void *optval
, int optlen
)
1417 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1418 return GSOCK_NOERROR
;
1420 return GSOCK_OPTERR
;
1423 #define CALL_CALLBACK(socket, event) { \
1424 socket->Disable(event); \
1425 if (socket->m_cbacks[event]) \
1426 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1430 void GSocket::Enable(GSocketEvent event
)
1434 m_detected
&= ~(1 << event
);
1435 GSocketManager::Get()->Install_Callback(this, event
);
1439 void GSocket::Disable(GSocketEvent event
)
1443 m_detected
|= (1 << event
);
1444 GSocketManager::Get()->Uninstall_Callback(this, event
);
1448 /* _GSocket_Input_Timeout:
1449 * For blocking sockets, wait until data is available or
1450 * until timeout ellapses.
1452 GSocketError
GSocket::Input_Timeout()
1458 /* Linux select() will overwrite the struct on return */
1459 tv
.tv_sec
= (m_timeout
/ 1000);
1460 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1462 if (!m_non_blocking
)
1464 wxFD_ZERO(&readfds
);
1465 wxFD_SET(m_fd
, &readfds
);
1466 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1469 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1470 m_error
= GSOCK_TIMEDOUT
;
1471 return GSOCK_TIMEDOUT
;
1476 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1477 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1478 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1479 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1480 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1481 m_error
= GSOCK_TIMEDOUT
;
1482 return GSOCK_TIMEDOUT
;
1486 return GSOCK_NOERROR
;
1489 /* _GSocket_Output_Timeout:
1490 * For blocking sockets, wait until data can be sent without
1491 * blocking or until timeout ellapses.
1493 GSocketError
GSocket::Output_Timeout()
1499 /* Linux select() will overwrite the struct on return */
1500 tv
.tv_sec
= (m_timeout
/ 1000);
1501 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1503 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1505 if (!m_non_blocking
)
1507 wxFD_ZERO(&writefds
);
1508 wxFD_SET(m_fd
, &writefds
);
1509 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1512 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1513 m_error
= GSOCK_TIMEDOUT
;
1514 return GSOCK_TIMEDOUT
;
1519 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1520 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1521 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1522 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1523 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1524 m_error
= GSOCK_TIMEDOUT
;
1525 return GSOCK_TIMEDOUT
;
1528 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1530 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1534 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1539 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1542 return GSOCK_NOERROR
;
1545 int GSocket::Recv_Stream(char *buffer
, int size
)
1550 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1552 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1557 int GSocket::Recv_Dgram(char *buffer
, int size
)
1560 WX_SOCKLEN_T fromlen
= sizeof(from
);
1564 fromlen
= sizeof(from
);
1568 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1570 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1575 /* Translate a system address into a GSocket address */
1578 m_peer
= GAddress_new();
1581 m_error
= GSOCK_MEMERR
;
1586 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1587 if (err
!= GSOCK_NOERROR
)
1589 GAddress_destroy(m_peer
);
1598 int GSocket::Send_Stream(const char *buffer
, int size
)
1606 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1608 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1615 int GSocket::Send_Dgram(const char *buffer
, int size
)
1617 struct sockaddr
*addr
;
1623 m_error
= GSOCK_INVADDR
;
1627 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1628 if (err
!= GSOCK_NOERROR
)
1638 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1640 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1644 /* Frees memory allocated from _GAddress_translate_to */
1650 void GSocket::Detected_Read()
1654 /* Safeguard against straggling call to Detected_Read */
1655 if (m_fd
== INVALID_SOCKET
)
1660 /* If we have already detected a LOST event, then don't try
1661 * to do any further processing.
1663 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1665 m_establishing
= false;
1667 CALL_CALLBACK(this, GSOCK_LOST
);
1672 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1676 CALL_CALLBACK(this, GSOCK_INPUT
);
1680 if (m_server
&& m_stream
)
1682 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1686 /* graceful shutdown */
1687 CALL_CALLBACK(this, GSOCK_LOST
);
1692 /* Do not throw a lost event in cases where the socket isn't really lost */
1693 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1695 CALL_CALLBACK(this, GSOCK_INPUT
);
1699 CALL_CALLBACK(this, GSOCK_LOST
);
1706 void GSocket::Detected_Write()
1708 /* If we have already detected a LOST event, then don't try
1709 * to do any further processing.
1711 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1713 m_establishing
= false;
1715 CALL_CALLBACK(this, GSOCK_LOST
);
1720 if (m_establishing
&& !m_server
)
1723 SOCKOPTLEN_T len
= sizeof(error
);
1725 m_establishing
= false;
1727 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1731 CALL_CALLBACK(this, GSOCK_LOST
);
1736 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1737 /* We have to fire this event by hand because CONNECTION (for clients)
1738 * and OUTPUT are internally the same and we just disabled CONNECTION
1739 * events with the above macro.
1741 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1746 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1750 /* Compatibility functions for GSocket */
1751 GSocket
*GSocket_new(void)
1753 GSocket
*newsocket
= new GSocket();
1754 if (newsocket
->IsOk())
1763 * -------------------------------------------------------------------------
1765 * -------------------------------------------------------------------------
1768 /* CHECK_ADDRESS verifies that the current address family is either
1769 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1770 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1771 * an appropiate error code.
1773 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1775 #define CHECK_ADDRESS(address, family) \
1777 if (address->m_family == GSOCK_NOFAMILY) \
1778 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1779 return address->m_error; \
1780 if (address->m_family != GSOCK_##family) \
1782 address->m_error = GSOCK_INVADDR; \
1783 return GSOCK_INVADDR; \
1787 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1789 if (address->m_family == GSOCK_NOFAMILY) \
1790 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1792 if (address->m_family != GSOCK_##family) \
1794 address->m_error = GSOCK_INVADDR; \
1800 GAddress
*GAddress_new(void)
1804 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1807 address
->m_family
= GSOCK_NOFAMILY
;
1808 address
->m_addr
= NULL
;
1814 GAddress
*GAddress_copy(GAddress
*address
)
1818 assert(address
!= NULL
);
1820 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1823 memcpy(addr2
, address
, sizeof(GAddress
));
1825 if (address
->m_addr
&& address
->m_len
> 0)
1827 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1828 if (addr2
->m_addr
== NULL
)
1833 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1839 void GAddress_destroy(GAddress
*address
)
1841 assert(address
!= NULL
);
1843 if (address
->m_addr
)
1844 free(address
->m_addr
);
1849 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1851 assert(address
!= NULL
);
1853 address
->m_family
= type
;
1856 GAddressType
GAddress_GetFamily(GAddress
*address
)
1858 assert(address
!= NULL
);
1860 return address
->m_family
;
1863 GSocketError
_GAddress_translate_from(GAddress
*address
,
1864 struct sockaddr
*addr
, int len
)
1866 address
->m_realfamily
= addr
->sa_family
;
1867 switch (addr
->sa_family
)
1870 address
->m_family
= GSOCK_INET
;
1873 address
->m_family
= GSOCK_UNIX
;
1877 address
->m_family
= GSOCK_INET6
;
1879 #endif // wxUSE_IPV6
1882 address
->m_error
= GSOCK_INVOP
;
1887 if (address
->m_addr
)
1888 free(address
->m_addr
);
1890 address
->m_len
= len
;
1891 address
->m_addr
= (struct sockaddr
*)malloc(len
);
1893 if (address
->m_addr
== NULL
)
1895 address
->m_error
= GSOCK_MEMERR
;
1896 return GSOCK_MEMERR
;
1899 memcpy(address
->m_addr
, addr
, len
);
1901 return GSOCK_NOERROR
;
1904 GSocketError
_GAddress_translate_to(GAddress
*address
,
1905 struct sockaddr
**addr
, int *len
)
1907 if (!address
->m_addr
)
1909 address
->m_error
= GSOCK_INVADDR
;
1910 return GSOCK_INVADDR
;
1913 *len
= address
->m_len
;
1914 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
1917 address
->m_error
= GSOCK_MEMERR
;
1918 return GSOCK_MEMERR
;
1921 memcpy(*addr
, address
->m_addr
, address
->m_len
);
1922 return GSOCK_NOERROR
;
1926 * -------------------------------------------------------------------------
1927 * Internet address family
1928 * -------------------------------------------------------------------------
1931 GSocketError
_GAddress_Init_INET(GAddress
*address
)
1933 address
->m_len
= sizeof(struct sockaddr_in
);
1934 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1935 if (address
->m_addr
== NULL
)
1937 address
->m_error
= GSOCK_MEMERR
;
1938 return GSOCK_MEMERR
;
1941 address
->m_family
= GSOCK_INET
;
1942 address
->m_realfamily
= PF_INET
;
1943 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
1944 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
1946 return GSOCK_NOERROR
;
1949 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
1952 struct in_addr
*addr
;
1954 assert(address
!= NULL
);
1956 CHECK_ADDRESS(address
, INET
);
1958 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1960 /* If it is a numeric host name, convert it now */
1961 #if defined(HAVE_INET_ATON)
1962 if (inet_aton(hostname
, addr
) == 0)
1964 #elif defined(HAVE_INET_ADDR)
1965 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
1968 /* Use gethostbyname by default */
1970 int val
= 1; /* VA doesn't like constants in conditional expressions */
1975 struct in_addr
*array_addr
;
1977 /* It is a real name, we solve it */
1979 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1980 struct hostent_data buffer
;
1985 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
1988 /* Reset to invalid address */
1989 addr
->s_addr
= INADDR_NONE
;
1990 address
->m_error
= GSOCK_NOHOST
;
1991 return GSOCK_NOHOST
;
1994 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
1995 addr
->s_addr
= array_addr
[0].s_addr
;
1998 return GSOCK_NOERROR
;
2002 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
2004 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
2007 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
2009 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
2012 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
2013 unsigned long hostaddr
)
2015 struct in_addr
*addr
;
2017 assert(address
!= NULL
);
2019 CHECK_ADDRESS(address
, INET
);
2021 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
2022 addr
->s_addr
= htonl(hostaddr
);
2024 return GSOCK_NOERROR
;
2027 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
2028 const char *protocol
)
2031 struct sockaddr_in
*addr
;
2033 assert(address
!= NULL
);
2034 CHECK_ADDRESS(address
, INET
);
2038 address
->m_error
= GSOCK_INVPORT
;
2039 return GSOCK_INVPORT
;
2042 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
2043 struct servent_data buffer
;
2047 struct servent serv
;
2048 se
= wxGetservbyname_r(port
, protocol
, &serv
,
2049 (void*)&buffer
, sizeof(buffer
));
2052 /* the cast to int suppresses compiler warnings about subscript having the
2054 if (isdigit((int)port
[0]))
2058 port_int
= atoi(port
);
2059 addr
= (struct sockaddr_in
*)address
->m_addr
;
2060 addr
->sin_port
= htons(port_int
);
2061 return GSOCK_NOERROR
;
2064 address
->m_error
= GSOCK_INVPORT
;
2065 return GSOCK_INVPORT
;
2068 addr
= (struct sockaddr_in
*)address
->m_addr
;
2069 addr
->sin_port
= se
->s_port
;
2071 return GSOCK_NOERROR
;
2074 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
2076 struct sockaddr_in
*addr
;
2078 assert(address
!= NULL
);
2079 CHECK_ADDRESS(address
, INET
);
2081 addr
= (struct sockaddr_in
*)address
->m_addr
;
2082 addr
->sin_port
= htons(port
);
2084 return GSOCK_NOERROR
;
2087 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2091 struct sockaddr_in
*addr
;
2093 assert(address
!= NULL
);
2094 CHECK_ADDRESS(address
, INET
);
2096 addr
= (struct sockaddr_in
*)address
->m_addr
;
2097 addr_buf
= (char *)&(addr
->sin_addr
);
2099 struct hostent temphost
;
2100 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2101 struct hostent_data buffer
;
2106 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
2107 (void*)&buffer
, sizeof(buffer
), &err
);
2110 address
->m_error
= GSOCK_NOHOST
;
2111 return GSOCK_NOHOST
;
2114 strncpy(hostname
, he
->h_name
, sbuf
);
2116 return GSOCK_NOERROR
;
2119 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
2121 struct sockaddr_in
*addr
;
2123 assert(address
!= NULL
);
2124 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2126 addr
= (struct sockaddr_in
*)address
->m_addr
;
2128 return ntohl(addr
->sin_addr
.s_addr
);
2131 unsigned short GAddress_INET_GetPort(GAddress
*address
)
2133 struct sockaddr_in
*addr
;
2135 assert(address
!= NULL
);
2136 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2138 addr
= (struct sockaddr_in
*)address
->m_addr
;
2139 return ntohs(addr
->sin_port
);
2144 * -------------------------------------------------------------------------
2145 * Internet IPv6 address family
2146 * -------------------------------------------------------------------------
2149 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
2151 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
2152 address
->m_len
= sizeof(struct sockaddr_in6
);
2153 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2154 if (address
->m_addr
== NULL
)
2156 address
->m_error
= GSOCK_MEMERR
;
2157 return GSOCK_MEMERR
;
2159 memset(address
->m_addr
,0,address
->m_len
);
2161 address
->m_family
= GSOCK_INET6
;
2162 address
->m_realfamily
= AF_INET6
;
2163 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
2164 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
2166 return GSOCK_NOERROR
;
2169 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
2171 assert(address
!= NULL
);
2172 CHECK_ADDRESS(address
, INET6
);
2175 memset( & hints
, 0, sizeof( hints
) );
2176 hints
.ai_family
= AF_INET6
;
2177 addrinfo
* info
= 0;
2178 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
2180 address
->m_error
= GSOCK_NOHOST
;
2181 return GSOCK_NOHOST
;
2184 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
2185 freeaddrinfo( info
);
2186 return GSOCK_NOERROR
;
2189 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
2191 assert(address
!= NULL
);
2193 CHECK_ADDRESS(address
, INET6
);
2195 struct in6_addr addr
;
2196 memset( & addr
, 0, sizeof( addr
) );
2197 return GAddress_INET6_SetHostAddress(address
, addr
);
2199 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
2200 struct in6_addr hostaddr
)
2202 assert(address
!= NULL
);
2204 CHECK_ADDRESS(address
, INET6
);
2206 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
2208 return GSOCK_NOERROR
;
2211 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
2212 const char *protocol
)
2215 struct sockaddr_in6
*addr
;
2217 assert(address
!= NULL
);
2218 CHECK_ADDRESS(address
, INET6
);
2222 address
->m_error
= GSOCK_INVPORT
;
2223 return GSOCK_INVPORT
;
2226 se
= getservbyname(port
, protocol
);
2229 if (isdigit(port
[0]))
2233 port_int
= atoi(port
);
2234 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2235 addr
->sin6_port
= htons((u_short
) port_int
);
2236 return GSOCK_NOERROR
;
2239 address
->m_error
= GSOCK_INVPORT
;
2240 return GSOCK_INVPORT
;
2243 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2244 addr
->sin6_port
= se
->s_port
;
2246 return GSOCK_NOERROR
;
2249 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
2251 struct sockaddr_in6
*addr
;
2253 assert(address
!= NULL
);
2254 CHECK_ADDRESS(address
, INET6
);
2256 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2257 addr
->sin6_port
= htons(port
);
2259 return GSOCK_NOERROR
;
2262 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2266 struct sockaddr_in6
*addr
;
2268 assert(address
!= NULL
);
2269 CHECK_ADDRESS(address
, INET6
);
2271 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2272 addr_buf
= (char *)&(addr
->sin6_addr
);
2274 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
2277 address
->m_error
= GSOCK_NOHOST
;
2278 return GSOCK_NOHOST
;
2281 strncpy(hostname
, he
->h_name
, sbuf
);
2283 return GSOCK_NOERROR
;
2286 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
2288 assert(address
!= NULL
);
2289 assert(hostaddr
!= NULL
);
2290 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
2291 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
2292 return GSOCK_NOERROR
;
2295 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2297 assert(address
!= NULL
);
2298 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2300 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2303 #endif // wxUSE_IPV6
2306 * -------------------------------------------------------------------------
2307 * Unix address family
2308 * -------------------------------------------------------------------------
2311 #ifndef __VISAGECPP__
2312 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2314 address
->m_len
= sizeof(struct sockaddr_un
);
2315 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2316 if (address
->m_addr
== NULL
)
2318 address
->m_error
= GSOCK_MEMERR
;
2319 return GSOCK_MEMERR
;
2322 address
->m_family
= GSOCK_UNIX
;
2323 address
->m_realfamily
= PF_UNIX
;
2324 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2325 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2327 return GSOCK_NOERROR
;
2330 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2332 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2334 struct sockaddr_un
*addr
;
2336 assert(address
!= NULL
);
2338 CHECK_ADDRESS(address
, UNIX
);
2340 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2341 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2342 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2344 return GSOCK_NOERROR
;
2347 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2349 struct sockaddr_un
*addr
;
2351 assert(address
!= NULL
);
2352 CHECK_ADDRESS(address
, UNIX
);
2354 addr
= (struct sockaddr_un
*)address
->m_addr
;
2356 strncpy(path
, addr
->sun_path
, sbuf
);
2358 return GSOCK_NOERROR
;
2360 #endif /* !defined(__VISAGECPP__) */
2361 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */