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 #include "wx/wxprec.h"
19 #include "wx/gsocket.h"
21 #include "wx/private/fd.h"
22 #include "wx/private/socket.h"
23 #include "wx/private/gsocketiohandler.h"
25 #if defined(__VISAGECPP__)
26 #define BSD_SELECT /* use Berkeley Sockets select */
29 #if defined(__WATCOMC__)
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 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
181 # include "wx/thread.h"
184 #if defined(HAVE_GETHOSTBYNAME)
185 static struct hostent
* deepCopyHostent(struct hostent
*h
,
186 const struct hostent
*he
,
187 char *buffer
, int size
, int *err
)
189 /* copy old structure */
190 memcpy(h
, he
, sizeof(struct hostent
));
193 int len
= strlen(h
->h_name
);
199 memcpy(buffer
, h
->h_name
, len
);
203 /* track position in the buffer */
206 /* reuse len to store address length */
209 /* ensure pointer alignment */
210 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
211 if(misalign
< sizeof(char *))
214 /* leave space for pointer list */
215 char **p
= h
->h_addr_list
, **q
;
216 char **h_addr_list
= (char **)(buffer
+ pos
);
218 pos
+= sizeof(char *);
220 /* copy addresses and fill new pointer list */
221 for (p
= h
->h_addr_list
, q
= h_addr_list
; *p
!= 0; p
++, q
++)
223 if (size
< pos
+ len
)
228 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
229 *q
= buffer
+ pos
; /* set copied pointer to copied content */
232 *++q
= 0; /* null terminate the pointer list */
233 h
->h_addr_list
= h_addr_list
; /* copy pointer to pointers */
235 /* ensure word alignment of pointers */
236 misalign
= sizeof(char *) - pos%sizeof
(char *);
237 if(misalign
< sizeof(char *))
240 /* leave space for pointer list */
242 char **h_aliases
= (char **)(buffer
+ pos
);
244 pos
+= sizeof(char *);
246 /* copy aliases and fill new pointer list */
247 for (p
= h
->h_aliases
, q
= h_aliases
; *p
!= 0; p
++, q
++)
250 if (size
<= pos
+ len
)
255 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
256 buffer
[pos
+ len
] = '\0';
257 *q
= buffer
+ pos
; /* set copied pointer to copied content */
260 *++q
= 0; /* null terminate the pointer list */
261 h
->h_aliases
= h_aliases
; /* copy pointer to pointers */
267 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
268 static wxMutex nameLock
;
270 struct hostent
* wxGethostbyname_r(const char *hostname
, struct hostent
*h
,
271 void *buffer
, int size
, int *err
)
274 struct hostent
*he
= NULL
;
276 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
277 if (gethostbyname_r(hostname
, h
, (char*)buffer
, size
, &he
, err
))
279 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
280 he
= gethostbyname_r(hostname
, h
, (char*)buffer
, size
, err
);
281 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
282 if (gethostbyname_r(hostname
, h
, (struct hostent_data
*) buffer
))
289 #elif defined(HAVE_GETHOSTBYNAME)
291 wxMutexLocker
locker(nameLock
);
293 he
= gethostbyname(hostname
);
297 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
302 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
303 static wxMutex addrLock
;
305 struct hostent
* wxGethostbyaddr_r(const char *addr_buf
, int buf_size
,
306 int proto
, struct hostent
*h
,
307 void *buffer
, int size
, int *err
)
309 struct hostent
*he
= NULL
;
311 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
312 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
313 (char*)buffer
, size
, &he
, err
))
315 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
316 he
= gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
, (char*)buffer
, size
, err
);
317 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
318 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
319 (struct hostent_data
*) buffer
))
326 #elif defined(HAVE_GETHOSTBYNAME)
328 wxMutexLocker
locker(addrLock
);
330 he
= gethostbyaddr(addr_buf
, buf_size
, proto
);
334 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
339 #if defined(HAVE_GETSERVBYNAME)
340 static struct servent
* deepCopyServent(struct servent
*s
,
341 const struct servent
*se
,
342 char *buffer
, int size
)
344 /* copy plain old structure */
345 memcpy(s
, se
, sizeof(struct servent
));
348 int len
= strlen(s
->s_name
);
353 memcpy(buffer
, s
->s_name
, len
);
357 /* track position in the buffer */
361 len
= strlen(s
->s_proto
);
362 if (pos
+ len
>= size
)
366 memcpy(buffer
+ pos
, s
->s_proto
, len
);
367 buffer
[pos
+ len
] = '\0';
368 s
->s_proto
= buffer
+ pos
;
370 /* track position in the buffer */
373 /* ensure pointer alignment */
374 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
375 if(misalign
< sizeof(char *))
378 /* leave space for pointer list */
379 char **p
= s
->s_aliases
, **q
;
380 char **s_aliases
= (char **)(buffer
+ pos
);
382 pos
+= sizeof(char *);
384 /* copy addresses and fill new pointer list */
385 for (p
= s
->s_aliases
, q
= s_aliases
; *p
!= 0; p
++, q
++){
387 if (size
<= pos
+ len
)
391 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
392 buffer
[pos
+ len
] = '\0';
393 *q
= buffer
+ pos
; /* set copied pointer to copied content */
396 *++q
= 0; /* null terminate the pointer list */
397 s
->s_aliases
= s_aliases
; /* copy pointer to pointers */
402 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
403 static wxMutex servLock
;
405 struct servent
*wxGetservbyname_r(const char *port
, const char *protocol
,
406 struct servent
*serv
, void *buffer
, int size
)
408 struct servent
*se
= NULL
;
409 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
410 if (getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
, &se
))
412 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
413 se
= getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
);
414 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
415 if (getservbyname_r(port
, protocol
, serv
, (struct servent_data
*) buffer
))
419 #elif defined(HAVE_GETSERVBYNAME)
421 wxMutexLocker
locker(servLock
);
423 se
= getservbyname(port
, protocol
);
425 se
= deepCopyServent(serv
, se
, (char*)buffer
, size
);
430 /* debugging helpers */
431 #ifdef __GSOCKET_DEBUG__
432 # define GSocket_Debug(args) printf args
434 # define GSocket_Debug(args)
435 #endif /* __GSOCKET_DEBUG__ */
437 /* Table of GUI-related functions. We must call them indirectly because
438 * of wxBase and GUI separation: */
442 GSocketManager
* const manager
= GSocketManager::Get();
443 return manager
&& manager
->OnInit();
446 void GSocket_Cleanup()
448 GSocketManager
* const manager
= GSocketManager::Get();
453 /* Constructors / Destructors for GSocket */
455 GSocket::GSocket(wxSocketBase
& wxsocket
)
456 : GSocketBase(wxsocket
)
460 m_gui_dependent
= NULL
;
461 m_use_events
= false;
464 void GSocket::Close()
469 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
470 will close the socket during Disable_Events. However, it will only do this
471 if it is being used. That is, it won't do it in a console program. To
472 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
473 if it has closed the socket which indicates to us (at runtime, instead of
474 at compile time as this had been before) that the socket has already
477 if(m_fd
!= INVALID_SOCKET
)
479 m_fd
= INVALID_SOCKET
;
488 * Disallow further read/write operations on this socket, close
489 * the fd and disable all callbacks.
491 void GSocket::Shutdown()
493 /* Don't allow events to fire after socket has been closed */
497 GSocketBase::Shutdown();
500 /* Server specific parts */
502 /* GSocket_SetServer:
503 * Sets up this socket as a server. The local address must have been
504 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
505 * Returns GSOCK_NOERROR on success, one of the following otherwise:
508 * GSOCK_INVSOCK - the socket is in use.
509 * GSOCK_INVADDR - the local address has not been set.
510 * GSOCK_IOERR - low-level error.
512 GSocketError
GSocket::SetServer()
518 /* must not be in use */
519 if (m_fd
!= INVALID_SOCKET
)
521 m_error
= GSOCK_INVSOCK
;
522 return GSOCK_INVSOCK
;
525 /* the local addr must have been set */
528 m_error
= GSOCK_INVADDR
;
529 return GSOCK_INVADDR
;
532 /* Initialize all fields */
536 /* Create the socket */
537 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
539 if (m_fd
== INVALID_SOCKET
)
541 m_error
= GSOCK_IOERR
;
545 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
547 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
550 ioctl(m_fd
, FIONBIO
, &arg
);
554 /* allow a socket to re-bind if the socket is in the TIME_WAIT
555 state after being previously closed.
559 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
561 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
565 /* Bind to the local address,
566 * retrieve the actual address bound,
567 * and listen up to 5 connections.
569 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
572 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
573 (listen(m_fd
, 5) != 0))
576 m_error
= GSOCK_IOERR
;
580 return GSOCK_NOERROR
;
583 /* GSocket_WaitConnection:
584 * Waits for an incoming client connection. Returns a pointer to
585 * a GSocket object, or NULL if there was an error, in which case
586 * the last error field will be updated for the calling GSocket.
588 * Error codes (set in the calling GSocket)
589 * GSOCK_INVSOCK - the socket is not valid or not a server.
590 * GSOCK_TIMEDOUT - timeout, no incoming connections.
591 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
592 * GSOCK_MEMERR - couldn't allocate memory.
593 * GSOCK_IOERR - low-level error.
595 GSocket
*GSocket::WaitConnection(wxSocketBase
& wxsocket
)
598 WX_SOCKLEN_T fromlen
= sizeof(from
);
605 /* If the socket has already been created, we exit immediately */
606 if (m_fd
== INVALID_SOCKET
|| !m_server
)
608 m_error
= GSOCK_INVSOCK
;
612 /* Create a GSocket object for the new connection */
613 connection
= GSocket::Create(wxsocket
);
617 m_error
= GSOCK_MEMERR
;
621 /* Wait for a connection (with timeout) */
622 if (Input_Timeout() == GSOCK_TIMEDOUT
)
625 /* m_error set by _GSocket_Input_Timeout */
629 connection
->m_fd
= accept(m_fd
, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
631 /* Reenable CONNECTION events */
632 Enable(GSOCK_CONNECTION
);
634 if (connection
->m_fd
== INVALID_SOCKET
)
636 if (errno
== EWOULDBLOCK
)
637 m_error
= GSOCK_WOULDBLOCK
;
639 m_error
= GSOCK_IOERR
;
645 /* Initialize all fields */
646 connection
->m_server
= false;
647 connection
->m_stream
= true;
649 /* Setup the peer address field */
650 connection
->m_peer
= GAddress_new();
651 if (!connection
->m_peer
)
654 m_error
= GSOCK_MEMERR
;
658 err
= _GAddress_translate_from(connection
->m_peer
, (sockaddr
*)&from
, fromlen
);
659 if (err
!= GSOCK_NOERROR
)
666 #if defined(__EMX__) || defined(__VISAGECPP__)
667 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
669 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
672 connection
->Notify(true);
677 void GSocket::Notify(bool flag
)
679 if (flag
== m_use_events
)
685 void GSocket::EnableEvents(bool flag
)
688 GSocketManager::Get()->Enable_Events(this);
690 GSocketManager::Get()->Disable_Events(this);
693 bool GSocket::SetReusable()
695 /* socket must not be null, and must not be in use/already bound */
696 if (this && m_fd
== INVALID_SOCKET
)
706 bool GSocket::SetBroadcast()
708 /* socket must not be in use/already bound */
709 if (m_fd
== INVALID_SOCKET
) {
716 bool GSocket::DontDoBind()
718 /* socket must not be in use/already bound */
719 if (m_fd
== INVALID_SOCKET
) {
726 /* Client specific parts */
729 * For stream (connection oriented) sockets, GSocket_Connect() tries
730 * to establish a client connection to a server using the peer address
731 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
732 * connection has been successfully established, or one of the error
733 * codes listed below. Note that for nonblocking sockets, a return
734 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
735 * request can be completed later; you should use GSocket_Select()
736 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
737 * corresponding asynchronous events.
739 * For datagram (non connection oriented) sockets, GSocket_Connect()
740 * just sets the peer address established with GSocket_SetPeer() as
741 * default destination.
744 * GSOCK_INVSOCK - the socket is in use or not valid.
745 * GSOCK_INVADDR - the peer address has not been established.
746 * GSOCK_TIMEDOUT - timeout, the connection failed.
747 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
748 * GSOCK_MEMERR - couldn't allocate memory.
749 * GSOCK_IOERR - low-level error.
751 GSocketError
GSocket::Connect(GSocketStream stream
)
758 /* Enable CONNECTION events (needed for nonblocking connections) */
759 Enable(GSOCK_CONNECTION
);
761 if (m_fd
!= INVALID_SOCKET
)
763 m_error
= GSOCK_INVSOCK
;
764 return GSOCK_INVSOCK
;
769 m_error
= GSOCK_INVADDR
;
770 return GSOCK_INVADDR
;
773 /* Streamed or dgram socket? */
774 m_stream
= (stream
== GSOCK_STREAMED
);
776 m_establishing
= false;
778 /* Create the socket */
779 m_fd
= socket(m_peer
->m_realfamily
,
780 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
782 if (m_fd
== INVALID_SOCKET
)
784 m_error
= GSOCK_IOERR
;
788 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
790 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
793 #if defined(__EMX__) || defined(__VISAGECPP__)
794 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
796 ioctl(m_fd
, FIONBIO
, &arg
);
799 // If the reuse flag is set, use the applicable socket reuse flags(s)
802 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
804 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
808 if (m_initialRecvBufferSize
>= 0)
809 setsockopt(m_fd
, SOL_SOCKET
, SO_RCVBUF
, (const char*)&m_initialRecvBufferSize
, sizeof(m_initialRecvBufferSize
));
810 if (m_initialSendBufferSize
>= 0)
811 setsockopt(m_fd
, SOL_SOCKET
, SO_SNDBUF
, (const char*)&m_initialSendBufferSize
, sizeof(m_initialSendBufferSize
));
813 // If a local address has been set, then we need to bind to it before calling connect
814 if (m_local
&& m_local
->m_addr
)
816 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
819 /* Connect it to the peer address, with a timeout (see below) */
820 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
822 /* We only call Enable_Events if we know we aren't shutting down the socket.
823 * NB: Enable_Events needs to be called whether the socket is blocking or
824 * non-blocking, it just shouldn't be called prior to knowing there is a
825 * connection _if_ blocking sockets are being used.
826 * If connect above returns 0, we are already connected and need to make the
827 * call to Enable_Events now.
830 if (m_use_events
&& (m_non_blocking
|| ret
== 0))
837 /* If connect failed with EINPROGRESS and the GSocket object
838 * is in blocking mode, we select() for the specified timeout
839 * checking for writability to see if the connection request
842 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
844 if (Output_Timeout() == GSOCK_TIMEDOUT
)
847 /* m_error is set in _GSocket_Output_Timeout */
848 return GSOCK_TIMEDOUT
;
853 SOCKOPTLEN_T len
= sizeof(error
);
855 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
860 return GSOCK_NOERROR
;
864 /* If connect failed with EINPROGRESS and the GSocket object
865 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
866 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
867 * this way if the connection completes, a GSOCK_CONNECTION
868 * event will be generated, if enabled.
870 if ((err
== EINPROGRESS
) && (m_non_blocking
))
872 m_establishing
= true;
873 m_error
= GSOCK_WOULDBLOCK
;
874 return GSOCK_WOULDBLOCK
;
877 /* If connect failed with an error other than EINPROGRESS,
878 * then the call to GSocket_Connect has failed.
881 m_error
= GSOCK_IOERR
;
886 return GSOCK_NOERROR
;
889 /* Datagram sockets */
891 /* GSocket_SetNonOriented:
892 * Sets up this socket as a non-connection oriented (datagram) socket.
893 * Before using this function, the local address must have been set
894 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
895 * on success, or one of the following otherwise.
898 * GSOCK_INVSOCK - the socket is in use.
899 * GSOCK_INVADDR - the local address has not been set.
900 * GSOCK_IOERR - low-level error.
902 GSocketError
GSocket::SetNonOriented()
908 if (m_fd
!= INVALID_SOCKET
)
910 m_error
= GSOCK_INVSOCK
;
911 return GSOCK_INVSOCK
;
916 m_error
= GSOCK_INVADDR
;
917 return GSOCK_INVADDR
;
920 /* Initialize all fields */
924 /* Create the socket */
925 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
927 if (m_fd
== INVALID_SOCKET
)
929 m_error
= GSOCK_IOERR
;
932 #if defined(__EMX__) || defined(__VISAGECPP__)
933 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
935 ioctl(m_fd
, FIONBIO
, &arg
);
942 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
944 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
950 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
954 /* Bind to the local address,
955 * and retrieve the actual address bound.
957 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
960 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
963 m_error
= GSOCK_IOERR
;
967 return GSOCK_NOERROR
;
972 /* Like recv(), send(), ... */
973 int GSocket::Read(char *buffer
, int size
)
979 if (m_fd
== INVALID_SOCKET
|| m_server
)
981 m_error
= GSOCK_INVSOCK
;
985 /* Disable events during query of socket status */
986 Disable(GSOCK_INPUT
);
988 /* If the socket is blocking, wait for data (with a timeout) */
989 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
990 m_error
= GSOCK_TIMEDOUT
;
991 /* Don't return here immediately, otherwise socket events would not be
999 ret
= Recv_Stream(buffer
, size
);
1001 ret
= Recv_Dgram(buffer
, size
);
1004 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1005 * socket and empty datagrams are possible), then the connection has been
1006 * gracefully closed.
1008 * Otherwise, recv has returned an error (-1), in which case we have lost
1009 * the socket only if errno does _not_ indicate that there may be more data
1012 if ((ret
== 0) && m_stream
)
1014 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1017 m_detected
= GSOCK_LOST_FLAG
;
1024 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1025 m_error
= GSOCK_WOULDBLOCK
;
1027 m_error
= GSOCK_IOERR
;
1031 /* Enable events again now that we are done processing */
1032 Enable(GSOCK_INPUT
);
1037 int GSocket::Write(const char *buffer
, int size
)
1043 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1045 if (m_fd
== INVALID_SOCKET
|| m_server
)
1047 m_error
= GSOCK_INVSOCK
;
1051 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1053 /* If the socket is blocking, wait for writability (with a timeout) */
1054 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1057 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1059 /* Write the data */
1061 ret
= Send_Stream(buffer
, size
);
1063 ret
= Send_Dgram(buffer
, size
);
1065 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1069 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1071 m_error
= GSOCK_WOULDBLOCK
;
1072 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1076 m_error
= GSOCK_IOERR
;
1077 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1080 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1081 * in MSW). Once the first OUTPUT event is received, users can assume
1082 * that the socket is writable until a read operation fails. Only then
1083 * will further OUTPUT events be posted.
1085 Enable(GSOCK_OUTPUT
);
1090 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1097 /* GSocket_SetNonBlocking:
1098 * Sets the socket to non-blocking mode. All IO calls will return
1101 void GSocket::SetNonBlocking(bool non_block
)
1105 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1107 m_non_blocking
= non_block
;
1110 /* GSocket_GetError:
1111 * Returns the last error occurred for this socket. Note that successful
1112 * operations do not clear this back to GSOCK_NOERROR, so use it only
1115 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1122 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1123 void *optval
, int *optlen
)
1125 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1126 return GSOCK_NOERROR
;
1128 return GSOCK_OPTERR
;
1131 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1132 const void *optval
, int optlen
)
1134 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1135 return GSOCK_NOERROR
;
1137 return GSOCK_OPTERR
;
1140 void GSocket::Enable(GSocketEvent event
)
1144 m_detected
&= ~(1 << event
);
1145 GSocketManager::Get()->Install_Callback(this, event
);
1149 void GSocket::Disable(GSocketEvent event
)
1153 m_detected
|= (1 << event
);
1154 GSocketManager::Get()->Uninstall_Callback(this, event
);
1158 /* _GSocket_Input_Timeout:
1159 * For blocking sockets, wait until data is available or
1160 * until timeout ellapses.
1162 GSocketError
GSocket::Input_Timeout()
1168 /* Linux select() will overwrite the struct on return */
1169 tv
.tv_sec
= (m_timeout
/ 1000);
1170 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1172 if (!m_non_blocking
)
1174 wxFD_ZERO(&readfds
);
1175 wxFD_SET(m_fd
, &readfds
);
1176 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1179 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1180 m_error
= GSOCK_TIMEDOUT
;
1181 return GSOCK_TIMEDOUT
;
1186 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1187 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1188 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1189 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1190 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1191 m_error
= GSOCK_TIMEDOUT
;
1192 return GSOCK_TIMEDOUT
;
1196 return GSOCK_NOERROR
;
1199 /* _GSocket_Output_Timeout:
1200 * For blocking sockets, wait until data can be sent without
1201 * blocking or until timeout ellapses.
1203 GSocketError
GSocket::Output_Timeout()
1209 /* Linux select() will overwrite the struct on return */
1210 tv
.tv_sec
= (m_timeout
/ 1000);
1211 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1213 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1215 if (!m_non_blocking
)
1217 wxFD_ZERO(&writefds
);
1218 wxFD_SET(m_fd
, &writefds
);
1219 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1222 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1223 m_error
= GSOCK_TIMEDOUT
;
1224 return GSOCK_TIMEDOUT
;
1229 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1230 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1231 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1232 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1233 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1234 m_error
= GSOCK_TIMEDOUT
;
1235 return GSOCK_TIMEDOUT
;
1238 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1240 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1244 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1249 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1252 return GSOCK_NOERROR
;
1255 int GSocket::Recv_Stream(char *buffer
, int size
)
1260 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1262 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1267 int GSocket::Recv_Dgram(char *buffer
, int size
)
1270 WX_SOCKLEN_T fromlen
= sizeof(from
);
1274 fromlen
= sizeof(from
);
1278 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1280 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1285 /* Translate a system address into a GSocket address */
1288 m_peer
= GAddress_new();
1291 m_error
= GSOCK_MEMERR
;
1296 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1297 if (err
!= GSOCK_NOERROR
)
1299 GAddress_destroy(m_peer
);
1308 int GSocket::Send_Stream(const char *buffer
, int size
)
1316 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1318 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1325 int GSocket::Send_Dgram(const char *buffer
, int size
)
1327 struct sockaddr
*addr
;
1333 m_error
= GSOCK_INVADDR
;
1337 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1338 if (err
!= GSOCK_NOERROR
)
1348 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1350 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1354 /* Frees memory allocated from _GAddress_translate_to */
1360 void GSocket::OnStateChange(GSocketEvent event
)
1363 NotifyOnStateChange(event
);
1365 if ( event
== GSOCK_LOST
)
1369 void GSocket::Detected_Read()
1373 /* Safeguard against straggling call to Detected_Read */
1374 if (m_fd
== INVALID_SOCKET
)
1379 /* If we have already detected a LOST event, then don't try
1380 * to do any further processing.
1382 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1384 m_establishing
= false;
1386 OnStateChange(GSOCK_LOST
);
1390 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1394 OnStateChange(GSOCK_INPUT
);
1398 if (m_server
&& m_stream
)
1400 OnStateChange(GSOCK_CONNECTION
);
1406 /* graceful shutdown */
1407 OnStateChange(GSOCK_LOST
);
1411 /* Empty datagram received */
1412 OnStateChange(GSOCK_INPUT
);
1417 /* Do not throw a lost event in cases where the socket isn't really lost */
1418 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1420 OnStateChange(GSOCK_INPUT
);
1424 OnStateChange(GSOCK_LOST
);
1430 void GSocket::Detected_Write()
1432 /* If we have already detected a LOST event, then don't try
1433 * to do any further processing.
1435 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1437 m_establishing
= false;
1439 OnStateChange(GSOCK_LOST
);
1443 if (m_establishing
&& !m_server
)
1446 SOCKOPTLEN_T len
= sizeof(error
);
1448 m_establishing
= false;
1450 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1454 OnStateChange(GSOCK_LOST
);
1458 OnStateChange(GSOCK_CONNECTION
);
1459 /* We have to fire this event by hand because CONNECTION (for clients)
1460 * and OUTPUT are internally the same and we just disabled CONNECTION
1461 * events with the above macro.
1463 OnStateChange(GSOCK_OUTPUT
);
1468 OnStateChange(GSOCK_OUTPUT
);
1473 * -------------------------------------------------------------------------
1475 * -------------------------------------------------------------------------
1478 /* CHECK_ADDRESS verifies that the current address family is either
1479 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1480 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1481 * an appropiate error code.
1483 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1485 #define CHECK_ADDRESS(address, family) \
1487 if (address->m_family == GSOCK_NOFAMILY) \
1488 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1489 return address->m_error; \
1490 if (address->m_family != GSOCK_##family) \
1492 address->m_error = GSOCK_INVADDR; \
1493 return GSOCK_INVADDR; \
1497 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1499 if (address->m_family == GSOCK_NOFAMILY) \
1500 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1502 if (address->m_family != GSOCK_##family) \
1504 address->m_error = GSOCK_INVADDR; \
1510 GAddress
*GAddress_new(void)
1514 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1517 address
->m_family
= GSOCK_NOFAMILY
;
1518 address
->m_addr
= NULL
;
1524 GAddress
*GAddress_copy(GAddress
*address
)
1528 assert(address
!= NULL
);
1530 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1533 memcpy(addr2
, address
, sizeof(GAddress
));
1535 if (address
->m_addr
&& address
->m_len
> 0)
1537 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1538 if (addr2
->m_addr
== NULL
)
1543 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1549 void GAddress_destroy(GAddress
*address
)
1551 assert(address
!= NULL
);
1553 if (address
->m_addr
)
1554 free(address
->m_addr
);
1559 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1561 assert(address
!= NULL
);
1563 address
->m_family
= type
;
1566 GAddressType
GAddress_GetFamily(GAddress
*address
)
1568 assert(address
!= NULL
);
1570 return address
->m_family
;
1573 GSocketError
_GAddress_translate_from(GAddress
*address
,
1574 struct sockaddr
*addr
, int len
)
1576 address
->m_realfamily
= addr
->sa_family
;
1577 switch (addr
->sa_family
)
1580 address
->m_family
= GSOCK_INET
;
1583 address
->m_family
= GSOCK_UNIX
;
1587 address
->m_family
= GSOCK_INET6
;
1589 #endif // wxUSE_IPV6
1592 address
->m_error
= GSOCK_INVOP
;
1597 if (address
->m_addr
)
1598 free(address
->m_addr
);
1600 address
->m_len
= len
;
1601 address
->m_addr
= (struct sockaddr
*)malloc(len
);
1603 if (address
->m_addr
== NULL
)
1605 address
->m_error
= GSOCK_MEMERR
;
1606 return GSOCK_MEMERR
;
1609 memcpy(address
->m_addr
, addr
, len
);
1611 return GSOCK_NOERROR
;
1614 GSocketError
_GAddress_translate_to(GAddress
*address
,
1615 struct sockaddr
**addr
, int *len
)
1617 if (!address
->m_addr
)
1619 address
->m_error
= GSOCK_INVADDR
;
1620 return GSOCK_INVADDR
;
1623 *len
= address
->m_len
;
1624 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
1627 address
->m_error
= GSOCK_MEMERR
;
1628 return GSOCK_MEMERR
;
1631 memcpy(*addr
, address
->m_addr
, address
->m_len
);
1632 return GSOCK_NOERROR
;
1636 * -------------------------------------------------------------------------
1637 * Internet address family
1638 * -------------------------------------------------------------------------
1641 GSocketError
_GAddress_Init_INET(GAddress
*address
)
1643 address
->m_len
= sizeof(struct sockaddr_in
);
1644 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1645 if (address
->m_addr
== NULL
)
1647 address
->m_error
= GSOCK_MEMERR
;
1648 return GSOCK_MEMERR
;
1651 address
->m_family
= GSOCK_INET
;
1652 address
->m_realfamily
= PF_INET
;
1653 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
1654 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
1656 return GSOCK_NOERROR
;
1659 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
1662 struct in_addr
*addr
;
1664 assert(address
!= NULL
);
1666 CHECK_ADDRESS(address
, INET
);
1668 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1670 /* If it is a numeric host name, convert it now */
1671 #if defined(HAVE_INET_ATON)
1672 if (inet_aton(hostname
, addr
) == 0)
1674 #elif defined(HAVE_INET_ADDR)
1675 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
1678 /* Use gethostbyname by default */
1680 int val
= 1; /* VA doesn't like constants in conditional expressions */
1685 struct in_addr
*array_addr
;
1687 /* It is a real name, we solve it */
1689 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1690 struct hostent_data buffer
;
1695 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
1698 /* Reset to invalid address */
1699 addr
->s_addr
= INADDR_NONE
;
1700 address
->m_error
= GSOCK_NOHOST
;
1701 return GSOCK_NOHOST
;
1704 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
1705 addr
->s_addr
= array_addr
[0].s_addr
;
1708 return GSOCK_NOERROR
;
1712 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
1714 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
1717 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
1719 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
1722 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
1723 unsigned long hostaddr
)
1725 struct in_addr
*addr
;
1727 assert(address
!= NULL
);
1729 CHECK_ADDRESS(address
, INET
);
1731 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1732 addr
->s_addr
= htonl(hostaddr
);
1734 return GSOCK_NOERROR
;
1737 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
1738 const char *protocol
)
1741 struct sockaddr_in
*addr
;
1743 assert(address
!= NULL
);
1744 CHECK_ADDRESS(address
, INET
);
1748 address
->m_error
= GSOCK_INVPORT
;
1749 return GSOCK_INVPORT
;
1752 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
1753 struct servent_data buffer
;
1757 struct servent serv
;
1758 se
= wxGetservbyname_r(port
, protocol
, &serv
,
1759 (void*)&buffer
, sizeof(buffer
));
1762 /* the cast to int suppresses compiler warnings about subscript having the
1764 if (isdigit((int)port
[0]))
1768 port_int
= atoi(port
);
1769 addr
= (struct sockaddr_in
*)address
->m_addr
;
1770 addr
->sin_port
= htons(port_int
);
1771 return GSOCK_NOERROR
;
1774 address
->m_error
= GSOCK_INVPORT
;
1775 return GSOCK_INVPORT
;
1778 addr
= (struct sockaddr_in
*)address
->m_addr
;
1779 addr
->sin_port
= se
->s_port
;
1781 return GSOCK_NOERROR
;
1784 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
1786 struct sockaddr_in
*addr
;
1788 assert(address
!= NULL
);
1789 CHECK_ADDRESS(address
, INET
);
1791 addr
= (struct sockaddr_in
*)address
->m_addr
;
1792 addr
->sin_port
= htons(port
);
1794 return GSOCK_NOERROR
;
1797 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
1801 struct sockaddr_in
*addr
;
1803 assert(address
!= NULL
);
1804 CHECK_ADDRESS(address
, INET
);
1806 addr
= (struct sockaddr_in
*)address
->m_addr
;
1807 addr_buf
= (char *)&(addr
->sin_addr
);
1809 struct hostent temphost
;
1810 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1811 struct hostent_data buffer
;
1816 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
1817 (void*)&buffer
, sizeof(buffer
), &err
);
1820 address
->m_error
= GSOCK_NOHOST
;
1821 return GSOCK_NOHOST
;
1824 strncpy(hostname
, he
->h_name
, sbuf
);
1826 return GSOCK_NOERROR
;
1829 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
1831 struct sockaddr_in
*addr
;
1833 assert(address
!= NULL
);
1834 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1836 addr
= (struct sockaddr_in
*)address
->m_addr
;
1838 return ntohl(addr
->sin_addr
.s_addr
);
1841 unsigned short GAddress_INET_GetPort(GAddress
*address
)
1843 struct sockaddr_in
*addr
;
1845 assert(address
!= NULL
);
1846 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1848 addr
= (struct sockaddr_in
*)address
->m_addr
;
1849 return ntohs(addr
->sin_port
);
1854 * -------------------------------------------------------------------------
1855 * Internet IPv6 address family
1856 * -------------------------------------------------------------------------
1859 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
1861 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
1862 address
->m_len
= sizeof(struct sockaddr_in6
);
1863 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1864 if (address
->m_addr
== NULL
)
1866 address
->m_error
= GSOCK_MEMERR
;
1867 return GSOCK_MEMERR
;
1869 memset(address
->m_addr
,0,address
->m_len
);
1871 address
->m_family
= GSOCK_INET6
;
1872 address
->m_realfamily
= AF_INET6
;
1873 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
1874 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
1876 return GSOCK_NOERROR
;
1879 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
1881 assert(address
!= NULL
);
1882 CHECK_ADDRESS(address
, INET6
);
1885 memset( & hints
, 0, sizeof( hints
) );
1886 hints
.ai_family
= AF_INET6
;
1887 addrinfo
* info
= 0;
1888 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
1890 address
->m_error
= GSOCK_NOHOST
;
1891 return GSOCK_NOHOST
;
1894 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
1895 freeaddrinfo( info
);
1896 return GSOCK_NOERROR
;
1899 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
1901 assert(address
!= NULL
);
1903 CHECK_ADDRESS(address
, INET6
);
1905 struct in6_addr addr
;
1906 memset( & addr
, 0, sizeof( addr
) );
1907 return GAddress_INET6_SetHostAddress(address
, addr
);
1909 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
1910 struct in6_addr hostaddr
)
1912 assert(address
!= NULL
);
1914 CHECK_ADDRESS(address
, INET6
);
1916 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
1918 return GSOCK_NOERROR
;
1921 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
1922 const char *protocol
)
1925 struct sockaddr_in6
*addr
;
1927 assert(address
!= NULL
);
1928 CHECK_ADDRESS(address
, INET6
);
1932 address
->m_error
= GSOCK_INVPORT
;
1933 return GSOCK_INVPORT
;
1936 se
= getservbyname(port
, protocol
);
1939 if (isdigit(port
[0]))
1943 port_int
= atoi(port
);
1944 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1945 addr
->sin6_port
= htons((u_short
) port_int
);
1946 return GSOCK_NOERROR
;
1949 address
->m_error
= GSOCK_INVPORT
;
1950 return GSOCK_INVPORT
;
1953 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1954 addr
->sin6_port
= se
->s_port
;
1956 return GSOCK_NOERROR
;
1959 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
1961 struct sockaddr_in6
*addr
;
1963 assert(address
!= NULL
);
1964 CHECK_ADDRESS(address
, INET6
);
1966 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1967 addr
->sin6_port
= htons(port
);
1969 return GSOCK_NOERROR
;
1972 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
1976 struct sockaddr_in6
*addr
;
1978 assert(address
!= NULL
);
1979 CHECK_ADDRESS(address
, INET6
);
1981 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1982 addr_buf
= (char *)&(addr
->sin6_addr
);
1984 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
1987 address
->m_error
= GSOCK_NOHOST
;
1988 return GSOCK_NOHOST
;
1991 strncpy(hostname
, he
->h_name
, sbuf
);
1993 return GSOCK_NOERROR
;
1996 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
1998 assert(address
!= NULL
);
1999 assert(hostaddr
!= NULL
);
2000 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
2001 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
2002 return GSOCK_NOERROR
;
2005 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2007 assert(address
!= NULL
);
2008 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2010 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2013 #endif // wxUSE_IPV6
2016 * -------------------------------------------------------------------------
2017 * Unix address family
2018 * -------------------------------------------------------------------------
2021 #ifndef __VISAGECPP__
2022 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2024 address
->m_len
= sizeof(struct sockaddr_un
);
2025 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2026 if (address
->m_addr
== NULL
)
2028 address
->m_error
= GSOCK_MEMERR
;
2029 return GSOCK_MEMERR
;
2032 address
->m_family
= GSOCK_UNIX
;
2033 address
->m_realfamily
= PF_UNIX
;
2034 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2035 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2037 return GSOCK_NOERROR
;
2040 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2042 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2044 struct sockaddr_un
*addr
;
2046 assert(address
!= NULL
);
2048 CHECK_ADDRESS(address
, UNIX
);
2050 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2051 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2052 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2054 return GSOCK_NOERROR
;
2057 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2059 struct sockaddr_un
*addr
;
2061 assert(address
!= NULL
);
2062 CHECK_ADDRESS(address
, UNIX
);
2064 addr
= (struct sockaddr_un
*)address
->m_addr
;
2066 strncpy(path
, addr
->sun_path
, sbuf
);
2068 return GSOCK_NOERROR
;
2070 #endif /* !defined(__VISAGECPP__) */
2071 #endif /* wxUSE_SOCKETS */