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__)
32 #include "wx/private/socket.h"
35 #include <sys/types.h>
40 #include <netinet/in.h>
43 #include <sys/ioctl.h>
45 #ifdef HAVE_SYS_SELECT_H
46 # include <sys/select.h>
53 u_char sun_len
; /* sockaddr len including null */
54 u_char sun_family
; /* AF_UNIX */
55 char sun_path
[108]; /* path name (gag) */
58 #include <sys/socket.h>
64 #include <netinet/in.h>
65 #include <arpa/inet.h>
72 #include <machine/endian.h>
78 #define EBADF SOCEBADF
84 #include <sys/socket.h>
85 #include <sys/ioctl.h>
86 #include <sys/select.h>
88 #define close(a) soclose(a)
89 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
90 int _System
bsdselect(int,
95 int _System
soclose(int);
99 #include <sys/select.h>
107 # include <sys/filio.h>
110 # include <bstring.h>
113 # include <strings.h>
120 # define WX_SOCKLEN_T unsigned int
124 # define WX_SOCKLEN_T socklen_t
126 # elif defined(__WXMAC__)
127 # define WX_SOCKLEN_T socklen_t
129 # define WX_SOCKLEN_T int
133 #endif /* SOCKLEN_T */
136 #define SOCKOPTLEN_T WX_SOCKLEN_T
139 /* UnixWare reportedly needs this for FIONBIO definition */
141 #include <sys/filio.h>
145 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
146 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
149 #define INADDR_NONE INADDR_BROADCAST
152 #if defined(__VISAGECPP__) || defined(__WATCOMC__)
154 #define MASK_SIGNAL() {
155 #define UNMASK_SIGNAL() }
158 extern "C" { typedef void (*wxSigHandler
)(int); }
160 #define MASK_SIGNAL() \
162 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
164 #define UNMASK_SIGNAL() \
165 signal(SIGPIPE, old_handler); \
170 /* If a SIGPIPE is issued by a socket call on a remotely closed socket,
171 the program will "crash" unless it explicitly handles the SIGPIPE.
172 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
173 use SO_NOSIGPIPE (if available), the BSD equivalent. */
175 # define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
176 #else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
177 # define GSOCKET_MSG_NOSIGNAL 0
178 #endif /* MSG_NOSIGNAL */
180 #ifndef __GSOCKET_STANDALONE__
181 # include "wx/unix/gsockunx.h"
182 # include "wx/unix/private.h"
183 # include "wx/gsocket.h"
184 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
185 # include "wx/thread.h"
188 # include "gsockunx.h"
189 # include "gsocket.h"
193 #endif /* __GSOCKET_STANDALONE__ */
195 #if defined(HAVE_GETHOSTBYNAME)
196 static struct hostent
* deepCopyHostent(struct hostent
*h
,
197 const struct hostent
*he
,
198 char *buffer
, int size
, int *err
)
200 /* copy old structure */
201 memcpy(h
, he
, sizeof(struct hostent
));
204 int len
= strlen(h
->h_name
);
210 memcpy(buffer
, h
->h_name
, len
);
214 /* track position in the buffer */
217 /* reuse len to store address length */
220 /* ensure pointer alignment */
221 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
222 if(misalign
< sizeof(char *))
225 /* leave space for pointer list */
226 char **p
= h
->h_addr_list
, **q
;
227 char **h_addr_list
= (char **)(buffer
+ pos
);
229 pos
+= sizeof(char *);
231 /* copy addresses and fill new pointer list */
232 for (p
= h
->h_addr_list
, q
= h_addr_list
; *p
!= 0; p
++, q
++)
234 if (size
< pos
+ len
)
239 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
240 *q
= buffer
+ pos
; /* set copied pointer to copied content */
243 *++q
= 0; /* null terminate the pointer list */
244 h
->h_addr_list
= h_addr_list
; /* copy pointer to pointers */
246 /* ensure word alignment of pointers */
247 misalign
= sizeof(char *) - pos%sizeof
(char *);
248 if(misalign
< sizeof(char *))
251 /* leave space for pointer list */
253 char **h_aliases
= (char **)(buffer
+ pos
);
255 pos
+= sizeof(char *);
257 /* copy aliases and fill new pointer list */
258 for (p
= h
->h_aliases
, q
= h_aliases
; *p
!= 0; p
++, q
++)
261 if (size
<= pos
+ len
)
266 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
267 buffer
[pos
+ len
] = '\0';
268 *q
= buffer
+ pos
; /* set copied pointer to copied content */
271 *++q
= 0; /* null terminate the pointer list */
272 h
->h_aliases
= h_aliases
; /* copy pointer to pointers */
278 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
279 static wxMutex nameLock
;
281 struct hostent
* wxGethostbyname_r(const char *hostname
, struct hostent
*h
,
282 void *buffer
, int size
, int *err
)
285 struct hostent
*he
= NULL
;
287 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
288 if (gethostbyname_r(hostname
, h
, (char*)buffer
, size
, &he
, err
))
290 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
291 he
= gethostbyname_r(hostname
, h
, (char*)buffer
, size
, err
);
292 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
293 if (gethostbyname_r(hostname
, h
, (struct hostent_data
*) buffer
))
300 #elif defined(HAVE_GETHOSTBYNAME)
302 wxMutexLocker
locker(nameLock
);
304 he
= gethostbyname(hostname
);
308 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
313 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
314 static wxMutex addrLock
;
316 struct hostent
* wxGethostbyaddr_r(const char *addr_buf
, int buf_size
,
317 int proto
, struct hostent
*h
,
318 void *buffer
, int size
, int *err
)
320 struct hostent
*he
= NULL
;
322 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
323 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
324 (char*)buffer
, size
, &he
, err
))
326 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
327 he
= gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
, (char*)buffer
, size
, err
);
328 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
329 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
330 (struct hostent_data
*) buffer
))
337 #elif defined(HAVE_GETHOSTBYNAME)
339 wxMutexLocker
locker(addrLock
);
341 he
= gethostbyaddr(addr_buf
, buf_size
, proto
);
345 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
350 #if defined(HAVE_GETSERVBYNAME)
351 static struct servent
* deepCopyServent(struct servent
*s
,
352 const struct servent
*se
,
353 char *buffer
, int size
)
355 /* copy plain old structure */
356 memcpy(s
, se
, sizeof(struct servent
));
359 int len
= strlen(s
->s_name
);
364 memcpy(buffer
, s
->s_name
, len
);
368 /* track position in the buffer */
372 len
= strlen(s
->s_proto
);
373 if (pos
+ len
>= size
)
377 memcpy(buffer
+ pos
, s
->s_proto
, len
);
378 buffer
[pos
+ len
] = '\0';
379 s
->s_proto
= buffer
+ pos
;
381 /* track position in the buffer */
384 /* ensure pointer alignment */
385 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
386 if(misalign
< sizeof(char *))
389 /* leave space for pointer list */
390 char **p
= s
->s_aliases
, **q
;
391 char **s_aliases
= (char **)(buffer
+ pos
);
393 pos
+= sizeof(char *);
395 /* copy addresses and fill new pointer list */
396 for (p
= s
->s_aliases
, q
= s_aliases
; *p
!= 0; p
++, q
++){
398 if (size
<= pos
+ len
)
402 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
403 buffer
[pos
+ len
] = '\0';
404 *q
= buffer
+ pos
; /* set copied pointer to copied content */
407 *++q
= 0; /* null terminate the pointer list */
408 s
->s_aliases
= s_aliases
; /* copy pointer to pointers */
413 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
414 static wxMutex servLock
;
416 struct servent
*wxGetservbyname_r(const char *port
, const char *protocol
,
417 struct servent
*serv
, void *buffer
, int size
)
419 struct servent
*se
= NULL
;
420 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
421 if (getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
, &se
))
423 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
424 se
= getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
);
425 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
426 if (getservbyname_r(port
, protocol
, serv
, (struct servent_data
*) buffer
))
430 #elif defined(HAVE_GETSERVBYNAME)
432 wxMutexLocker
locker(servLock
);
434 se
= getservbyname(port
, protocol
);
436 se
= deepCopyServent(serv
, se
, (char*)buffer
, size
);
441 /* debugging helpers */
442 #ifdef __GSOCKET_DEBUG__
443 # define GSocket_Debug(args) printf args
445 # define GSocket_Debug(args)
446 #endif /* __GSOCKET_DEBUG__ */
448 /* Table of GUI-related functions. We must call them indirectly because
449 * of wxBase and GUI separation: */
453 GSocketManager
* const manager
= GSocketManager::Get();
454 return manager
&& manager
->OnInit();
457 void GSocket_Cleanup()
459 GSocketManager
* const manager
= GSocketManager::Get();
464 /* Constructors / Destructors for GSocket */
466 GSocket::GSocket(wxSocketBase
& wxsocket
)
467 : GSocketBase(wxsocket
)
471 m_gui_dependent
= NULL
;
472 m_use_events
= false;
475 void GSocket::Close()
480 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
481 will close the socket during Disable_Events. However, it will only do this
482 if it is being used. That is, it won't do it in a console program. To
483 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
484 if it has closed the socket which indicates to us (at runtime, instead of
485 at compile time as this had been before) that the socket has already
488 if(m_fd
!= INVALID_SOCKET
)
490 m_fd
= INVALID_SOCKET
;
499 * Disallow further read/write operations on this socket, close
500 * the fd and disable all callbacks.
502 void GSocket::Shutdown()
504 /* Don't allow events to fire after socket has been closed */
508 GSocketBase::Shutdown();
511 /* Server specific parts */
513 /* GSocket_SetServer:
514 * Sets up this socket as a server. The local address must have been
515 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
516 * Returns GSOCK_NOERROR on success, one of the following otherwise:
519 * GSOCK_INVSOCK - the socket is in use.
520 * GSOCK_INVADDR - the local address has not been set.
521 * GSOCK_IOERR - low-level error.
523 GSocketError
GSocket::SetServer()
529 /* must not be in use */
530 if (m_fd
!= INVALID_SOCKET
)
532 m_error
= GSOCK_INVSOCK
;
533 return GSOCK_INVSOCK
;
536 /* the local addr must have been set */
539 m_error
= GSOCK_INVADDR
;
540 return GSOCK_INVADDR
;
543 /* Initialize all fields */
547 /* Create the socket */
548 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
550 if (m_fd
== INVALID_SOCKET
)
552 m_error
= GSOCK_IOERR
;
556 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
558 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
561 ioctl(m_fd
, FIONBIO
, &arg
);
565 /* allow a socket to re-bind if the socket is in the TIME_WAIT
566 state after being previously closed.
570 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
572 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
576 /* Bind to the local address,
577 * retrieve the actual address bound,
578 * and listen up to 5 connections.
580 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
583 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
584 (listen(m_fd
, 5) != 0))
587 m_error
= GSOCK_IOERR
;
591 return GSOCK_NOERROR
;
594 /* GSocket_WaitConnection:
595 * Waits for an incoming client connection. Returns a pointer to
596 * a GSocket object, or NULL if there was an error, in which case
597 * the last error field will be updated for the calling GSocket.
599 * Error codes (set in the calling GSocket)
600 * GSOCK_INVSOCK - the socket is not valid or not a server.
601 * GSOCK_TIMEDOUT - timeout, no incoming connections.
602 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
603 * GSOCK_MEMERR - couldn't allocate memory.
604 * GSOCK_IOERR - low-level error.
606 GSocket
*GSocket::WaitConnection(wxSocketBase
& wxsocket
)
609 WX_SOCKLEN_T fromlen
= sizeof(from
);
616 /* If the socket has already been created, we exit immediately */
617 if (m_fd
== INVALID_SOCKET
|| !m_server
)
619 m_error
= GSOCK_INVSOCK
;
623 /* Create a GSocket object for the new connection */
624 connection
= GSocket::Create(wxsocket
);
628 m_error
= GSOCK_MEMERR
;
632 /* Wait for a connection (with timeout) */
633 if (Input_Timeout() == GSOCK_TIMEDOUT
)
636 /* m_error set by _GSocket_Input_Timeout */
640 connection
->m_fd
= accept(m_fd
, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
642 /* Reenable CONNECTION events */
643 Enable(GSOCK_CONNECTION
);
645 if (connection
->m_fd
== INVALID_SOCKET
)
647 if (errno
== EWOULDBLOCK
)
648 m_error
= GSOCK_WOULDBLOCK
;
650 m_error
= GSOCK_IOERR
;
656 /* Initialize all fields */
657 connection
->m_server
= false;
658 connection
->m_stream
= true;
660 /* Setup the peer address field */
661 connection
->m_peer
= GAddress_new();
662 if (!connection
->m_peer
)
665 m_error
= GSOCK_MEMERR
;
669 err
= _GAddress_translate_from(connection
->m_peer
, (sockaddr
*)&from
, fromlen
);
670 if (err
!= GSOCK_NOERROR
)
677 #if defined(__EMX__) || defined(__VISAGECPP__)
678 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
680 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
683 connection
->Notify(true);
688 void GSocket::Notify(bool flag
)
690 if (flag
== m_use_events
)
696 void GSocket::EnableEvents(bool flag
)
699 GSocketManager::Get()->Enable_Events(this);
701 GSocketManager::Get()->Disable_Events(this);
704 bool GSocket::SetReusable()
706 /* socket must not be null, and must not be in use/already bound */
707 if (this && m_fd
== INVALID_SOCKET
)
717 bool GSocket::SetBroadcast()
719 /* socket must not be in use/already bound */
720 if (m_fd
== INVALID_SOCKET
) {
727 bool GSocket::DontDoBind()
729 /* socket must not be in use/already bound */
730 if (m_fd
== INVALID_SOCKET
) {
737 /* Client specific parts */
740 * For stream (connection oriented) sockets, GSocket_Connect() tries
741 * to establish a client connection to a server using the peer address
742 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
743 * connection has been successfully established, or one of the error
744 * codes listed below. Note that for nonblocking sockets, a return
745 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
746 * request can be completed later; you should use GSocket_Select()
747 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
748 * corresponding asynchronous events.
750 * For datagram (non connection oriented) sockets, GSocket_Connect()
751 * just sets the peer address established with GSocket_SetPeer() as
752 * default destination.
755 * GSOCK_INVSOCK - the socket is in use or not valid.
756 * GSOCK_INVADDR - the peer address has not been established.
757 * GSOCK_TIMEDOUT - timeout, the connection failed.
758 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
759 * GSOCK_MEMERR - couldn't allocate memory.
760 * GSOCK_IOERR - low-level error.
762 GSocketError
GSocket::Connect(GSocketStream stream
)
769 /* Enable CONNECTION events (needed for nonblocking connections) */
770 Enable(GSOCK_CONNECTION
);
772 if (m_fd
!= INVALID_SOCKET
)
774 m_error
= GSOCK_INVSOCK
;
775 return GSOCK_INVSOCK
;
780 m_error
= GSOCK_INVADDR
;
781 return GSOCK_INVADDR
;
784 /* Streamed or dgram socket? */
785 m_stream
= (stream
== GSOCK_STREAMED
);
787 m_establishing
= false;
789 /* Create the socket */
790 m_fd
= socket(m_peer
->m_realfamily
,
791 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
793 if (m_fd
== INVALID_SOCKET
)
795 m_error
= GSOCK_IOERR
;
799 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
801 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
804 #if defined(__EMX__) || defined(__VISAGECPP__)
805 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
807 ioctl(m_fd
, FIONBIO
, &arg
);
810 // If the reuse flag is set, use the applicable socket reuse flags(s)
813 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
815 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
819 if (m_initialRecvBufferSize
>= 0)
820 setsockopt(m_fd
, SOL_SOCKET
, SO_RCVBUF
, (const char*)&m_initialRecvBufferSize
, sizeof(m_initialRecvBufferSize
));
821 if (m_initialSendBufferSize
>= 0)
822 setsockopt(m_fd
, SOL_SOCKET
, SO_SNDBUF
, (const char*)&m_initialSendBufferSize
, sizeof(m_initialSendBufferSize
));
824 // If a local address has been set, then we need to bind to it before calling connect
825 if (m_local
&& m_local
->m_addr
)
827 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
830 /* Connect it to the peer address, with a timeout (see below) */
831 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
833 /* We only call Enable_Events if we know we aren't shutting down the socket.
834 * NB: Enable_Events needs to be called whether the socket is blocking or
835 * non-blocking, it just shouldn't be called prior to knowing there is a
836 * connection _if_ blocking sockets are being used.
837 * If connect above returns 0, we are already connected and need to make the
838 * call to Enable_Events now.
841 if (m_use_events
&& (m_non_blocking
|| ret
== 0))
848 /* If connect failed with EINPROGRESS and the GSocket object
849 * is in blocking mode, we select() for the specified timeout
850 * checking for writability to see if the connection request
853 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
855 if (Output_Timeout() == GSOCK_TIMEDOUT
)
858 /* m_error is set in _GSocket_Output_Timeout */
859 return GSOCK_TIMEDOUT
;
864 SOCKOPTLEN_T len
= sizeof(error
);
866 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
871 return GSOCK_NOERROR
;
875 /* If connect failed with EINPROGRESS and the GSocket object
876 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
877 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
878 * this way if the connection completes, a GSOCK_CONNECTION
879 * event will be generated, if enabled.
881 if ((err
== EINPROGRESS
) && (m_non_blocking
))
883 m_establishing
= true;
884 m_error
= GSOCK_WOULDBLOCK
;
885 return GSOCK_WOULDBLOCK
;
888 /* If connect failed with an error other than EINPROGRESS,
889 * then the call to GSocket_Connect has failed.
892 m_error
= GSOCK_IOERR
;
897 return GSOCK_NOERROR
;
900 /* Datagram sockets */
902 /* GSocket_SetNonOriented:
903 * Sets up this socket as a non-connection oriented (datagram) socket.
904 * Before using this function, the local address must have been set
905 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
906 * on success, or one of the following otherwise.
909 * GSOCK_INVSOCK - the socket is in use.
910 * GSOCK_INVADDR - the local address has not been set.
911 * GSOCK_IOERR - low-level error.
913 GSocketError
GSocket::SetNonOriented()
919 if (m_fd
!= INVALID_SOCKET
)
921 m_error
= GSOCK_INVSOCK
;
922 return GSOCK_INVSOCK
;
927 m_error
= GSOCK_INVADDR
;
928 return GSOCK_INVADDR
;
931 /* Initialize all fields */
935 /* Create the socket */
936 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
938 if (m_fd
== INVALID_SOCKET
)
940 m_error
= GSOCK_IOERR
;
943 #if defined(__EMX__) || defined(__VISAGECPP__)
944 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
946 ioctl(m_fd
, FIONBIO
, &arg
);
953 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
955 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
961 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
965 /* Bind to the local address,
966 * and retrieve the actual address bound.
968 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
971 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
974 m_error
= GSOCK_IOERR
;
978 return GSOCK_NOERROR
;
983 /* Like recv(), send(), ... */
984 int GSocket::Read(char *buffer
, int size
)
990 if (m_fd
== INVALID_SOCKET
|| m_server
)
992 m_error
= GSOCK_INVSOCK
;
996 /* Disable events during query of socket status */
997 Disable(GSOCK_INPUT
);
999 /* If the socket is blocking, wait for data (with a timeout) */
1000 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
1001 m_error
= GSOCK_TIMEDOUT
;
1002 /* Don't return here immediately, otherwise socket events would not be
1010 ret
= Recv_Stream(buffer
, size
);
1012 ret
= Recv_Dgram(buffer
, size
);
1015 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1016 * socket and empty datagrams are possible), then the connection has been
1017 * gracefully closed.
1019 * Otherwise, recv has returned an error (-1), in which case we have lost
1020 * the socket only if errno does _not_ indicate that there may be more data
1023 if ((ret
== 0) && m_stream
)
1025 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1028 m_detected
= GSOCK_LOST_FLAG
;
1035 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1036 m_error
= GSOCK_WOULDBLOCK
;
1038 m_error
= GSOCK_IOERR
;
1042 /* Enable events again now that we are done processing */
1043 Enable(GSOCK_INPUT
);
1048 int GSocket::Write(const char *buffer
, int size
)
1054 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1056 if (m_fd
== INVALID_SOCKET
|| m_server
)
1058 m_error
= GSOCK_INVSOCK
;
1062 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1064 /* If the socket is blocking, wait for writability (with a timeout) */
1065 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1068 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1070 /* Write the data */
1072 ret
= Send_Stream(buffer
, size
);
1074 ret
= Send_Dgram(buffer
, size
);
1076 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1080 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1082 m_error
= GSOCK_WOULDBLOCK
;
1083 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1087 m_error
= GSOCK_IOERR
;
1088 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1091 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1092 * in MSW). Once the first OUTPUT event is received, users can assume
1093 * that the socket is writable until a read operation fails. Only then
1094 * will further OUTPUT events be posted.
1096 Enable(GSOCK_OUTPUT
);
1101 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1108 /* GSocket_SetNonBlocking:
1109 * Sets the socket to non-blocking mode. All IO calls will return
1112 void GSocket::SetNonBlocking(bool non_block
)
1116 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1118 m_non_blocking
= non_block
;
1121 /* GSocket_GetError:
1122 * Returns the last error occurred for this socket. Note that successful
1123 * operations do not clear this back to GSOCK_NOERROR, so use it only
1126 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1133 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1134 void *optval
, int *optlen
)
1136 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1137 return GSOCK_NOERROR
;
1139 return GSOCK_OPTERR
;
1142 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1143 const void *optval
, int optlen
)
1145 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1146 return GSOCK_NOERROR
;
1148 return GSOCK_OPTERR
;
1151 void GSocket::Enable(GSocketEvent event
)
1155 m_detected
&= ~(1 << event
);
1156 GSocketManager::Get()->Install_Callback(this, event
);
1160 void GSocket::Disable(GSocketEvent event
)
1164 m_detected
|= (1 << event
);
1165 GSocketManager::Get()->Uninstall_Callback(this, event
);
1169 /* _GSocket_Input_Timeout:
1170 * For blocking sockets, wait until data is available or
1171 * until timeout ellapses.
1173 GSocketError
GSocket::Input_Timeout()
1179 /* Linux select() will overwrite the struct on return */
1180 tv
.tv_sec
= (m_timeout
/ 1000);
1181 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1183 if (!m_non_blocking
)
1185 wxFD_ZERO(&readfds
);
1186 wxFD_SET(m_fd
, &readfds
);
1187 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1190 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1191 m_error
= GSOCK_TIMEDOUT
;
1192 return GSOCK_TIMEDOUT
;
1197 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1198 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1199 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1200 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1201 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1202 m_error
= GSOCK_TIMEDOUT
;
1203 return GSOCK_TIMEDOUT
;
1207 return GSOCK_NOERROR
;
1210 /* _GSocket_Output_Timeout:
1211 * For blocking sockets, wait until data can be sent without
1212 * blocking or until timeout ellapses.
1214 GSocketError
GSocket::Output_Timeout()
1220 /* Linux select() will overwrite the struct on return */
1221 tv
.tv_sec
= (m_timeout
/ 1000);
1222 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1224 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1226 if (!m_non_blocking
)
1228 wxFD_ZERO(&writefds
);
1229 wxFD_SET(m_fd
, &writefds
);
1230 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1233 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1234 m_error
= GSOCK_TIMEDOUT
;
1235 return GSOCK_TIMEDOUT
;
1240 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1241 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1242 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1243 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1244 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1245 m_error
= GSOCK_TIMEDOUT
;
1246 return GSOCK_TIMEDOUT
;
1249 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1251 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1255 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1260 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1263 return GSOCK_NOERROR
;
1266 int GSocket::Recv_Stream(char *buffer
, int size
)
1271 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1273 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1278 int GSocket::Recv_Dgram(char *buffer
, int size
)
1281 WX_SOCKLEN_T fromlen
= sizeof(from
);
1285 fromlen
= sizeof(from
);
1289 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1291 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1296 /* Translate a system address into a GSocket address */
1299 m_peer
= GAddress_new();
1302 m_error
= GSOCK_MEMERR
;
1307 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1308 if (err
!= GSOCK_NOERROR
)
1310 GAddress_destroy(m_peer
);
1319 int GSocket::Send_Stream(const char *buffer
, int size
)
1327 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1329 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1336 int GSocket::Send_Dgram(const char *buffer
, int size
)
1338 struct sockaddr
*addr
;
1344 m_error
= GSOCK_INVADDR
;
1348 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1349 if (err
!= GSOCK_NOERROR
)
1359 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1361 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1365 /* Frees memory allocated from _GAddress_translate_to */
1371 void GSocket::OnStateChange(GSocketEvent event
)
1374 NotifyOnStateChange(event
);
1376 if ( event
== GSOCK_LOST
)
1380 void GSocket::Detected_Read()
1384 /* Safeguard against straggling call to Detected_Read */
1385 if (m_fd
== INVALID_SOCKET
)
1390 /* If we have already detected a LOST event, then don't try
1391 * to do any further processing.
1393 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1395 m_establishing
= false;
1397 OnStateChange(GSOCK_LOST
);
1401 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1405 OnStateChange(GSOCK_INPUT
);
1409 if (m_server
&& m_stream
)
1411 OnStateChange(GSOCK_CONNECTION
);
1417 /* graceful shutdown */
1418 OnStateChange(GSOCK_LOST
);
1422 /* Empty datagram received */
1423 OnStateChange(GSOCK_INPUT
);
1428 /* Do not throw a lost event in cases where the socket isn't really lost */
1429 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1431 OnStateChange(GSOCK_INPUT
);
1435 OnStateChange(GSOCK_LOST
);
1441 void GSocket::Detected_Write()
1443 /* If we have already detected a LOST event, then don't try
1444 * to do any further processing.
1446 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1448 m_establishing
= false;
1450 OnStateChange(GSOCK_LOST
);
1454 if (m_establishing
&& !m_server
)
1457 SOCKOPTLEN_T len
= sizeof(error
);
1459 m_establishing
= false;
1461 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1465 OnStateChange(GSOCK_LOST
);
1469 OnStateChange(GSOCK_CONNECTION
);
1470 /* We have to fire this event by hand because CONNECTION (for clients)
1471 * and OUTPUT are internally the same and we just disabled CONNECTION
1472 * events with the above macro.
1474 OnStateChange(GSOCK_OUTPUT
);
1479 OnStateChange(GSOCK_OUTPUT
);
1484 * -------------------------------------------------------------------------
1486 * -------------------------------------------------------------------------
1489 /* CHECK_ADDRESS verifies that the current address family is either
1490 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1491 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1492 * an appropiate error code.
1494 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1496 #define CHECK_ADDRESS(address, family) \
1498 if (address->m_family == GSOCK_NOFAMILY) \
1499 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1500 return address->m_error; \
1501 if (address->m_family != GSOCK_##family) \
1503 address->m_error = GSOCK_INVADDR; \
1504 return GSOCK_INVADDR; \
1508 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1510 if (address->m_family == GSOCK_NOFAMILY) \
1511 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1513 if (address->m_family != GSOCK_##family) \
1515 address->m_error = GSOCK_INVADDR; \
1521 GAddress
*GAddress_new(void)
1525 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1528 address
->m_family
= GSOCK_NOFAMILY
;
1529 address
->m_addr
= NULL
;
1535 GAddress
*GAddress_copy(GAddress
*address
)
1539 assert(address
!= NULL
);
1541 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1544 memcpy(addr2
, address
, sizeof(GAddress
));
1546 if (address
->m_addr
&& address
->m_len
> 0)
1548 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1549 if (addr2
->m_addr
== NULL
)
1554 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1560 void GAddress_destroy(GAddress
*address
)
1562 assert(address
!= NULL
);
1564 if (address
->m_addr
)
1565 free(address
->m_addr
);
1570 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1572 assert(address
!= NULL
);
1574 address
->m_family
= type
;
1577 GAddressType
GAddress_GetFamily(GAddress
*address
)
1579 assert(address
!= NULL
);
1581 return address
->m_family
;
1584 GSocketError
_GAddress_translate_from(GAddress
*address
,
1585 struct sockaddr
*addr
, int len
)
1587 address
->m_realfamily
= addr
->sa_family
;
1588 switch (addr
->sa_family
)
1591 address
->m_family
= GSOCK_INET
;
1594 address
->m_family
= GSOCK_UNIX
;
1598 address
->m_family
= GSOCK_INET6
;
1600 #endif // wxUSE_IPV6
1603 address
->m_error
= GSOCK_INVOP
;
1608 if (address
->m_addr
)
1609 free(address
->m_addr
);
1611 address
->m_len
= len
;
1612 address
->m_addr
= (struct sockaddr
*)malloc(len
);
1614 if (address
->m_addr
== NULL
)
1616 address
->m_error
= GSOCK_MEMERR
;
1617 return GSOCK_MEMERR
;
1620 memcpy(address
->m_addr
, addr
, len
);
1622 return GSOCK_NOERROR
;
1625 GSocketError
_GAddress_translate_to(GAddress
*address
,
1626 struct sockaddr
**addr
, int *len
)
1628 if (!address
->m_addr
)
1630 address
->m_error
= GSOCK_INVADDR
;
1631 return GSOCK_INVADDR
;
1634 *len
= address
->m_len
;
1635 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
1638 address
->m_error
= GSOCK_MEMERR
;
1639 return GSOCK_MEMERR
;
1642 memcpy(*addr
, address
->m_addr
, address
->m_len
);
1643 return GSOCK_NOERROR
;
1647 * -------------------------------------------------------------------------
1648 * Internet address family
1649 * -------------------------------------------------------------------------
1652 GSocketError
_GAddress_Init_INET(GAddress
*address
)
1654 address
->m_len
= sizeof(struct sockaddr_in
);
1655 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1656 if (address
->m_addr
== NULL
)
1658 address
->m_error
= GSOCK_MEMERR
;
1659 return GSOCK_MEMERR
;
1662 address
->m_family
= GSOCK_INET
;
1663 address
->m_realfamily
= PF_INET
;
1664 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
1665 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
1667 return GSOCK_NOERROR
;
1670 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
1673 struct in_addr
*addr
;
1675 assert(address
!= NULL
);
1677 CHECK_ADDRESS(address
, INET
);
1679 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1681 /* If it is a numeric host name, convert it now */
1682 #if defined(HAVE_INET_ATON)
1683 if (inet_aton(hostname
, addr
) == 0)
1685 #elif defined(HAVE_INET_ADDR)
1686 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
1689 /* Use gethostbyname by default */
1691 int val
= 1; /* VA doesn't like constants in conditional expressions */
1696 struct in_addr
*array_addr
;
1698 /* It is a real name, we solve it */
1700 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1701 struct hostent_data buffer
;
1706 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
1709 /* Reset to invalid address */
1710 addr
->s_addr
= INADDR_NONE
;
1711 address
->m_error
= GSOCK_NOHOST
;
1712 return GSOCK_NOHOST
;
1715 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
1716 addr
->s_addr
= array_addr
[0].s_addr
;
1719 return GSOCK_NOERROR
;
1723 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
1725 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
1728 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
1730 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
1733 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
1734 unsigned long hostaddr
)
1736 struct in_addr
*addr
;
1738 assert(address
!= NULL
);
1740 CHECK_ADDRESS(address
, INET
);
1742 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1743 addr
->s_addr
= htonl(hostaddr
);
1745 return GSOCK_NOERROR
;
1748 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
1749 const char *protocol
)
1752 struct sockaddr_in
*addr
;
1754 assert(address
!= NULL
);
1755 CHECK_ADDRESS(address
, INET
);
1759 address
->m_error
= GSOCK_INVPORT
;
1760 return GSOCK_INVPORT
;
1763 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
1764 struct servent_data buffer
;
1768 struct servent serv
;
1769 se
= wxGetservbyname_r(port
, protocol
, &serv
,
1770 (void*)&buffer
, sizeof(buffer
));
1773 /* the cast to int suppresses compiler warnings about subscript having the
1775 if (isdigit((int)port
[0]))
1779 port_int
= atoi(port
);
1780 addr
= (struct sockaddr_in
*)address
->m_addr
;
1781 addr
->sin_port
= htons(port_int
);
1782 return GSOCK_NOERROR
;
1785 address
->m_error
= GSOCK_INVPORT
;
1786 return GSOCK_INVPORT
;
1789 addr
= (struct sockaddr_in
*)address
->m_addr
;
1790 addr
->sin_port
= se
->s_port
;
1792 return GSOCK_NOERROR
;
1795 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
1797 struct sockaddr_in
*addr
;
1799 assert(address
!= NULL
);
1800 CHECK_ADDRESS(address
, INET
);
1802 addr
= (struct sockaddr_in
*)address
->m_addr
;
1803 addr
->sin_port
= htons(port
);
1805 return GSOCK_NOERROR
;
1808 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
1812 struct sockaddr_in
*addr
;
1814 assert(address
!= NULL
);
1815 CHECK_ADDRESS(address
, INET
);
1817 addr
= (struct sockaddr_in
*)address
->m_addr
;
1818 addr_buf
= (char *)&(addr
->sin_addr
);
1820 struct hostent temphost
;
1821 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1822 struct hostent_data buffer
;
1827 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
1828 (void*)&buffer
, sizeof(buffer
), &err
);
1831 address
->m_error
= GSOCK_NOHOST
;
1832 return GSOCK_NOHOST
;
1835 strncpy(hostname
, he
->h_name
, sbuf
);
1837 return GSOCK_NOERROR
;
1840 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
1842 struct sockaddr_in
*addr
;
1844 assert(address
!= NULL
);
1845 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1847 addr
= (struct sockaddr_in
*)address
->m_addr
;
1849 return ntohl(addr
->sin_addr
.s_addr
);
1852 unsigned short GAddress_INET_GetPort(GAddress
*address
)
1854 struct sockaddr_in
*addr
;
1856 assert(address
!= NULL
);
1857 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1859 addr
= (struct sockaddr_in
*)address
->m_addr
;
1860 return ntohs(addr
->sin_port
);
1865 * -------------------------------------------------------------------------
1866 * Internet IPv6 address family
1867 * -------------------------------------------------------------------------
1870 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
1872 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
1873 address
->m_len
= sizeof(struct sockaddr_in6
);
1874 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1875 if (address
->m_addr
== NULL
)
1877 address
->m_error
= GSOCK_MEMERR
;
1878 return GSOCK_MEMERR
;
1880 memset(address
->m_addr
,0,address
->m_len
);
1882 address
->m_family
= GSOCK_INET6
;
1883 address
->m_realfamily
= AF_INET6
;
1884 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
1885 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
1887 return GSOCK_NOERROR
;
1890 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
1892 assert(address
!= NULL
);
1893 CHECK_ADDRESS(address
, INET6
);
1896 memset( & hints
, 0, sizeof( hints
) );
1897 hints
.ai_family
= AF_INET6
;
1898 addrinfo
* info
= 0;
1899 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
1901 address
->m_error
= GSOCK_NOHOST
;
1902 return GSOCK_NOHOST
;
1905 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
1906 freeaddrinfo( info
);
1907 return GSOCK_NOERROR
;
1910 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
1912 assert(address
!= NULL
);
1914 CHECK_ADDRESS(address
, INET6
);
1916 struct in6_addr addr
;
1917 memset( & addr
, 0, sizeof( addr
) );
1918 return GAddress_INET6_SetHostAddress(address
, addr
);
1920 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
1921 struct in6_addr hostaddr
)
1923 assert(address
!= NULL
);
1925 CHECK_ADDRESS(address
, INET6
);
1927 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
1929 return GSOCK_NOERROR
;
1932 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
1933 const char *protocol
)
1936 struct sockaddr_in6
*addr
;
1938 assert(address
!= NULL
);
1939 CHECK_ADDRESS(address
, INET6
);
1943 address
->m_error
= GSOCK_INVPORT
;
1944 return GSOCK_INVPORT
;
1947 se
= getservbyname(port
, protocol
);
1950 if (isdigit(port
[0]))
1954 port_int
= atoi(port
);
1955 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1956 addr
->sin6_port
= htons((u_short
) port_int
);
1957 return GSOCK_NOERROR
;
1960 address
->m_error
= GSOCK_INVPORT
;
1961 return GSOCK_INVPORT
;
1964 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1965 addr
->sin6_port
= se
->s_port
;
1967 return GSOCK_NOERROR
;
1970 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
1972 struct sockaddr_in6
*addr
;
1974 assert(address
!= NULL
);
1975 CHECK_ADDRESS(address
, INET6
);
1977 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1978 addr
->sin6_port
= htons(port
);
1980 return GSOCK_NOERROR
;
1983 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
1987 struct sockaddr_in6
*addr
;
1989 assert(address
!= NULL
);
1990 CHECK_ADDRESS(address
, INET6
);
1992 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1993 addr_buf
= (char *)&(addr
->sin6_addr
);
1995 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
1998 address
->m_error
= GSOCK_NOHOST
;
1999 return GSOCK_NOHOST
;
2002 strncpy(hostname
, he
->h_name
, sbuf
);
2004 return GSOCK_NOERROR
;
2007 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
2009 assert(address
!= NULL
);
2010 assert(hostaddr
!= NULL
);
2011 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
2012 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
2013 return GSOCK_NOERROR
;
2016 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2018 assert(address
!= NULL
);
2019 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2021 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2024 #endif // wxUSE_IPV6
2027 * -------------------------------------------------------------------------
2028 * Unix address family
2029 * -------------------------------------------------------------------------
2032 #ifndef __VISAGECPP__
2033 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2035 address
->m_len
= sizeof(struct sockaddr_un
);
2036 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2037 if (address
->m_addr
== NULL
)
2039 address
->m_error
= GSOCK_MEMERR
;
2040 return GSOCK_MEMERR
;
2043 address
->m_family
= GSOCK_UNIX
;
2044 address
->m_realfamily
= PF_UNIX
;
2045 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2046 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2048 return GSOCK_NOERROR
;
2051 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2053 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2055 struct sockaddr_un
*addr
;
2057 assert(address
!= NULL
);
2059 CHECK_ADDRESS(address
, UNIX
);
2061 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2062 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2063 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2065 return GSOCK_NOERROR
;
2068 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2070 struct sockaddr_un
*addr
;
2072 assert(address
!= NULL
);
2073 CHECK_ADDRESS(address
, UNIX
);
2075 addr
= (struct sockaddr_un
*)address
->m_addr
;
2077 strncpy(path
, addr
->sun_path
, sbuf
);
2079 return GSOCK_NOERROR
;
2081 #endif /* !defined(__VISAGECPP__) */
2082 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */