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()
1167 // Linux select() will overwrite the struct on return so make a copy
1168 struct timeval tv
= m_timeout
;
1170 if (!m_non_blocking
)
1172 wxFD_ZERO(&readfds
);
1173 wxFD_SET(m_fd
, &readfds
);
1174 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1177 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1178 m_error
= GSOCK_TIMEDOUT
;
1179 return GSOCK_TIMEDOUT
;
1184 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1185 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1186 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1187 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1188 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1189 m_error
= GSOCK_TIMEDOUT
;
1190 return GSOCK_TIMEDOUT
;
1194 return GSOCK_NOERROR
;
1197 /* _GSocket_Output_Timeout:
1198 * For blocking sockets, wait until data can be sent without
1199 * blocking or until timeout ellapses.
1201 GSocketError
GSocket::Output_Timeout()
1206 // Linux select() will overwrite the struct on return so make a copy
1207 struct timeval tv
= m_timeout
;
1209 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1211 if (!m_non_blocking
)
1213 wxFD_ZERO(&writefds
);
1214 wxFD_SET(m_fd
, &writefds
);
1215 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1218 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1219 m_error
= GSOCK_TIMEDOUT
;
1220 return GSOCK_TIMEDOUT
;
1225 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1226 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1227 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1228 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1229 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1230 m_error
= GSOCK_TIMEDOUT
;
1231 return GSOCK_TIMEDOUT
;
1234 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1236 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1240 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1245 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1248 return GSOCK_NOERROR
;
1251 int GSocket::Recv_Stream(char *buffer
, int size
)
1256 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1258 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1263 int GSocket::Recv_Dgram(char *buffer
, int size
)
1266 WX_SOCKLEN_T fromlen
= sizeof(from
);
1270 fromlen
= sizeof(from
);
1274 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1276 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1281 /* Translate a system address into a GSocket address */
1284 m_peer
= GAddress_new();
1287 m_error
= GSOCK_MEMERR
;
1292 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1293 if (err
!= GSOCK_NOERROR
)
1295 GAddress_destroy(m_peer
);
1304 int GSocket::Send_Stream(const char *buffer
, int size
)
1312 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1314 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1321 int GSocket::Send_Dgram(const char *buffer
, int size
)
1323 struct sockaddr
*addr
;
1329 m_error
= GSOCK_INVADDR
;
1333 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1334 if (err
!= GSOCK_NOERROR
)
1344 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1346 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1350 /* Frees memory allocated from _GAddress_translate_to */
1356 void GSocket::OnStateChange(GSocketEvent event
)
1359 NotifyOnStateChange(event
);
1361 if ( event
== GSOCK_LOST
)
1365 void GSocket::Detected_Read()
1369 /* Safeguard against straggling call to Detected_Read */
1370 if (m_fd
== INVALID_SOCKET
)
1375 /* If we have already detected a LOST event, then don't try
1376 * to do any further processing.
1378 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1380 m_establishing
= false;
1382 OnStateChange(GSOCK_LOST
);
1386 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1390 OnStateChange(GSOCK_INPUT
);
1394 if (m_server
&& m_stream
)
1396 OnStateChange(GSOCK_CONNECTION
);
1402 /* graceful shutdown */
1403 OnStateChange(GSOCK_LOST
);
1407 /* Empty datagram received */
1408 OnStateChange(GSOCK_INPUT
);
1413 /* Do not throw a lost event in cases where the socket isn't really lost */
1414 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1416 OnStateChange(GSOCK_INPUT
);
1420 OnStateChange(GSOCK_LOST
);
1426 void GSocket::Detected_Write()
1428 /* If we have already detected a LOST event, then don't try
1429 * to do any further processing.
1431 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1433 m_establishing
= false;
1435 OnStateChange(GSOCK_LOST
);
1439 if (m_establishing
&& !m_server
)
1442 SOCKOPTLEN_T len
= sizeof(error
);
1444 m_establishing
= false;
1446 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1450 OnStateChange(GSOCK_LOST
);
1454 OnStateChange(GSOCK_CONNECTION
);
1455 /* We have to fire this event by hand because CONNECTION (for clients)
1456 * and OUTPUT are internally the same and we just disabled CONNECTION
1457 * events with the above macro.
1459 OnStateChange(GSOCK_OUTPUT
);
1464 OnStateChange(GSOCK_OUTPUT
);
1469 * -------------------------------------------------------------------------
1471 * -------------------------------------------------------------------------
1474 /* CHECK_ADDRESS verifies that the current address family is either
1475 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1476 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1477 * an appropiate error code.
1479 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1481 #define CHECK_ADDRESS(address, family) \
1483 if (address->m_family == GSOCK_NOFAMILY) \
1484 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1485 return address->m_error; \
1486 if (address->m_family != GSOCK_##family) \
1488 address->m_error = GSOCK_INVADDR; \
1489 return GSOCK_INVADDR; \
1493 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1495 if (address->m_family == GSOCK_NOFAMILY) \
1496 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1498 if (address->m_family != GSOCK_##family) \
1500 address->m_error = GSOCK_INVADDR; \
1506 GAddress
*GAddress_new(void)
1510 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1513 address
->m_family
= GSOCK_NOFAMILY
;
1514 address
->m_addr
= NULL
;
1520 GAddress
*GAddress_copy(GAddress
*address
)
1524 assert(address
!= NULL
);
1526 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1529 memcpy(addr2
, address
, sizeof(GAddress
));
1531 if (address
->m_addr
&& address
->m_len
> 0)
1533 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1534 if (addr2
->m_addr
== NULL
)
1539 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1545 void GAddress_destroy(GAddress
*address
)
1547 assert(address
!= NULL
);
1549 if (address
->m_addr
)
1550 free(address
->m_addr
);
1555 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1557 assert(address
!= NULL
);
1559 address
->m_family
= type
;
1562 GAddressType
GAddress_GetFamily(GAddress
*address
)
1564 assert(address
!= NULL
);
1566 return address
->m_family
;
1569 GSocketError
_GAddress_translate_from(GAddress
*address
,
1570 struct sockaddr
*addr
, int len
)
1572 address
->m_realfamily
= addr
->sa_family
;
1573 switch (addr
->sa_family
)
1576 address
->m_family
= GSOCK_INET
;
1579 address
->m_family
= GSOCK_UNIX
;
1583 address
->m_family
= GSOCK_INET6
;
1585 #endif // wxUSE_IPV6
1588 address
->m_error
= GSOCK_INVOP
;
1593 if (address
->m_addr
)
1594 free(address
->m_addr
);
1596 address
->m_len
= len
;
1597 address
->m_addr
= (struct sockaddr
*)malloc(len
);
1599 if (address
->m_addr
== NULL
)
1601 address
->m_error
= GSOCK_MEMERR
;
1602 return GSOCK_MEMERR
;
1605 memcpy(address
->m_addr
, addr
, len
);
1607 return GSOCK_NOERROR
;
1610 GSocketError
_GAddress_translate_to(GAddress
*address
,
1611 struct sockaddr
**addr
, int *len
)
1613 if (!address
->m_addr
)
1615 address
->m_error
= GSOCK_INVADDR
;
1616 return GSOCK_INVADDR
;
1619 *len
= address
->m_len
;
1620 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
1623 address
->m_error
= GSOCK_MEMERR
;
1624 return GSOCK_MEMERR
;
1627 memcpy(*addr
, address
->m_addr
, address
->m_len
);
1628 return GSOCK_NOERROR
;
1632 * -------------------------------------------------------------------------
1633 * Internet address family
1634 * -------------------------------------------------------------------------
1637 GSocketError
_GAddress_Init_INET(GAddress
*address
)
1639 address
->m_len
= sizeof(struct sockaddr_in
);
1640 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1641 if (address
->m_addr
== NULL
)
1643 address
->m_error
= GSOCK_MEMERR
;
1644 return GSOCK_MEMERR
;
1647 address
->m_family
= GSOCK_INET
;
1648 address
->m_realfamily
= PF_INET
;
1649 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
1650 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
1652 return GSOCK_NOERROR
;
1655 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
1658 struct in_addr
*addr
;
1660 assert(address
!= NULL
);
1662 CHECK_ADDRESS(address
, INET
);
1664 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1666 /* If it is a numeric host name, convert it now */
1667 #if defined(HAVE_INET_ATON)
1668 if (inet_aton(hostname
, addr
) == 0)
1670 #elif defined(HAVE_INET_ADDR)
1671 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
1674 /* Use gethostbyname by default */
1676 int val
= 1; /* VA doesn't like constants in conditional expressions */
1681 struct in_addr
*array_addr
;
1683 /* It is a real name, we solve it */
1685 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1686 struct hostent_data buffer
;
1691 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
1694 /* Reset to invalid address */
1695 addr
->s_addr
= INADDR_NONE
;
1696 address
->m_error
= GSOCK_NOHOST
;
1697 return GSOCK_NOHOST
;
1700 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
1701 addr
->s_addr
= array_addr
[0].s_addr
;
1704 return GSOCK_NOERROR
;
1708 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
1710 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
1713 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
1715 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
1718 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
1719 unsigned long hostaddr
)
1721 struct in_addr
*addr
;
1723 assert(address
!= NULL
);
1725 CHECK_ADDRESS(address
, INET
);
1727 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1728 addr
->s_addr
= htonl(hostaddr
);
1730 return GSOCK_NOERROR
;
1733 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
1734 const char *protocol
)
1737 struct sockaddr_in
*addr
;
1739 assert(address
!= NULL
);
1740 CHECK_ADDRESS(address
, INET
);
1744 address
->m_error
= GSOCK_INVPORT
;
1745 return GSOCK_INVPORT
;
1748 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
1749 struct servent_data buffer
;
1753 struct servent serv
;
1754 se
= wxGetservbyname_r(port
, protocol
, &serv
,
1755 (void*)&buffer
, sizeof(buffer
));
1758 /* the cast to int suppresses compiler warnings about subscript having the
1760 if (isdigit((int)port
[0]))
1764 port_int
= atoi(port
);
1765 addr
= (struct sockaddr_in
*)address
->m_addr
;
1766 addr
->sin_port
= htons(port_int
);
1767 return GSOCK_NOERROR
;
1770 address
->m_error
= GSOCK_INVPORT
;
1771 return GSOCK_INVPORT
;
1774 addr
= (struct sockaddr_in
*)address
->m_addr
;
1775 addr
->sin_port
= se
->s_port
;
1777 return GSOCK_NOERROR
;
1780 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
1782 struct sockaddr_in
*addr
;
1784 assert(address
!= NULL
);
1785 CHECK_ADDRESS(address
, INET
);
1787 addr
= (struct sockaddr_in
*)address
->m_addr
;
1788 addr
->sin_port
= htons(port
);
1790 return GSOCK_NOERROR
;
1793 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
1797 struct sockaddr_in
*addr
;
1799 assert(address
!= NULL
);
1800 CHECK_ADDRESS(address
, INET
);
1802 addr
= (struct sockaddr_in
*)address
->m_addr
;
1803 addr_buf
= (char *)&(addr
->sin_addr
);
1805 struct hostent temphost
;
1806 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1807 struct hostent_data buffer
;
1812 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
1813 (void*)&buffer
, sizeof(buffer
), &err
);
1816 address
->m_error
= GSOCK_NOHOST
;
1817 return GSOCK_NOHOST
;
1820 strncpy(hostname
, he
->h_name
, sbuf
);
1822 return GSOCK_NOERROR
;
1825 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
1827 struct sockaddr_in
*addr
;
1829 assert(address
!= NULL
);
1830 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1832 addr
= (struct sockaddr_in
*)address
->m_addr
;
1834 return ntohl(addr
->sin_addr
.s_addr
);
1837 unsigned short GAddress_INET_GetPort(GAddress
*address
)
1839 struct sockaddr_in
*addr
;
1841 assert(address
!= NULL
);
1842 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1844 addr
= (struct sockaddr_in
*)address
->m_addr
;
1845 return ntohs(addr
->sin_port
);
1850 * -------------------------------------------------------------------------
1851 * Internet IPv6 address family
1852 * -------------------------------------------------------------------------
1855 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
1857 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
1858 address
->m_len
= sizeof(struct sockaddr_in6
);
1859 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1860 if (address
->m_addr
== NULL
)
1862 address
->m_error
= GSOCK_MEMERR
;
1863 return GSOCK_MEMERR
;
1865 memset(address
->m_addr
,0,address
->m_len
);
1867 address
->m_family
= GSOCK_INET6
;
1868 address
->m_realfamily
= AF_INET6
;
1869 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
1870 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
1872 return GSOCK_NOERROR
;
1875 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
1877 assert(address
!= NULL
);
1878 CHECK_ADDRESS(address
, INET6
);
1881 memset( & hints
, 0, sizeof( hints
) );
1882 hints
.ai_family
= AF_INET6
;
1883 addrinfo
* info
= 0;
1884 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
1886 address
->m_error
= GSOCK_NOHOST
;
1887 return GSOCK_NOHOST
;
1890 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
1891 freeaddrinfo( info
);
1892 return GSOCK_NOERROR
;
1895 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
1897 assert(address
!= NULL
);
1899 CHECK_ADDRESS(address
, INET6
);
1901 struct in6_addr addr
;
1902 memset( & addr
, 0, sizeof( addr
) );
1903 return GAddress_INET6_SetHostAddress(address
, addr
);
1905 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
1906 struct in6_addr hostaddr
)
1908 assert(address
!= NULL
);
1910 CHECK_ADDRESS(address
, INET6
);
1912 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
1914 return GSOCK_NOERROR
;
1917 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
1918 const char *protocol
)
1921 struct sockaddr_in6
*addr
;
1923 assert(address
!= NULL
);
1924 CHECK_ADDRESS(address
, INET6
);
1928 address
->m_error
= GSOCK_INVPORT
;
1929 return GSOCK_INVPORT
;
1932 se
= getservbyname(port
, protocol
);
1935 if (isdigit(port
[0]))
1939 port_int
= atoi(port
);
1940 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1941 addr
->sin6_port
= htons((u_short
) port_int
);
1942 return GSOCK_NOERROR
;
1945 address
->m_error
= GSOCK_INVPORT
;
1946 return GSOCK_INVPORT
;
1949 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1950 addr
->sin6_port
= se
->s_port
;
1952 return GSOCK_NOERROR
;
1955 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
1957 struct sockaddr_in6
*addr
;
1959 assert(address
!= NULL
);
1960 CHECK_ADDRESS(address
, INET6
);
1962 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1963 addr
->sin6_port
= htons(port
);
1965 return GSOCK_NOERROR
;
1968 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
1972 struct sockaddr_in6
*addr
;
1974 assert(address
!= NULL
);
1975 CHECK_ADDRESS(address
, INET6
);
1977 addr
= (struct sockaddr_in6
*)address
->m_addr
;
1978 addr_buf
= (char *)&(addr
->sin6_addr
);
1980 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
1983 address
->m_error
= GSOCK_NOHOST
;
1984 return GSOCK_NOHOST
;
1987 strncpy(hostname
, he
->h_name
, sbuf
);
1989 return GSOCK_NOERROR
;
1992 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
1994 assert(address
!= NULL
);
1995 assert(hostaddr
!= NULL
);
1996 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
1997 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
1998 return GSOCK_NOERROR
;
2001 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2003 assert(address
!= NULL
);
2004 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2006 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2009 #endif // wxUSE_IPV6
2012 * -------------------------------------------------------------------------
2013 * Unix address family
2014 * -------------------------------------------------------------------------
2017 #ifndef __VISAGECPP__
2018 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2020 address
->m_len
= sizeof(struct sockaddr_un
);
2021 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2022 if (address
->m_addr
== NULL
)
2024 address
->m_error
= GSOCK_MEMERR
;
2025 return GSOCK_MEMERR
;
2028 address
->m_family
= GSOCK_UNIX
;
2029 address
->m_realfamily
= PF_UNIX
;
2030 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2031 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2033 return GSOCK_NOERROR
;
2036 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2038 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2040 struct sockaddr_un
*addr
;
2042 assert(address
!= NULL
);
2044 CHECK_ADDRESS(address
, UNIX
);
2046 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2047 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2048 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2050 return GSOCK_NOERROR
;
2053 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2055 struct sockaddr_un
*addr
;
2057 assert(address
!= NULL
);
2058 CHECK_ADDRESS(address
, UNIX
);
2060 addr
= (struct sockaddr_un
*)address
->m_addr
;
2062 strncpy(path
, addr
->sun_path
, sbuf
);
2064 return GSOCK_NOERROR
;
2066 #endif /* !defined(__VISAGECPP__) */
2067 #endif /* wxUSE_SOCKETS */