1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Authors: David Elliott (C++ conversion, maintainer)
8 * Guillermo Rodriguez Garcia <guille@iies.es>
9 * Purpose: GSocket main Unix and OS/2 file
10 * Licence: The wxWindows licence
12 * -------------------------------------------------------------------------
15 #if defined(__WATCOMC__)
16 #include "wx/wxprec.h"
21 #ifndef __GSOCKET_STANDALONE__
23 #include "wx/private/gsocketiohandler.h"
26 #if defined(__VISAGECPP__)
27 #define BSD_SELECT /* use Berkeley Sockets select */
30 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
33 #include <sys/types.h>
38 #include <netinet/in.h>
41 #include <sys/ioctl.h>
43 #ifdef HAVE_SYS_SELECT_H
44 # include <sys/select.h>
51 u_char sun_len
; /* sockaddr len including null */
52 u_char sun_family
; /* AF_UNIX */
53 char sun_path
[108]; /* path name (gag) */
56 #include <sys/socket.h>
62 #include <netinet/in.h>
63 #include <arpa/inet.h>
70 #include <machine/endian.h>
76 #define EBADF SOCEBADF
82 #include <sys/socket.h>
83 #include <sys/ioctl.h>
84 #include <sys/select.h>
86 #define close(a) soclose(a)
87 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
88 int _System
bsdselect(int,
93 int _System
soclose(int);
97 #include <sys/select.h>
105 # include <sys/filio.h>
108 # include <bstring.h>
111 # include <strings.h>
118 # define WX_SOCKLEN_T unsigned int
122 # define WX_SOCKLEN_T socklen_t
124 # elif defined(__WXMAC__)
125 # define WX_SOCKLEN_T socklen_t
127 # define WX_SOCKLEN_T int
131 #endif /* SOCKLEN_T */
134 #define SOCKOPTLEN_T WX_SOCKLEN_T
137 /* UnixWare reportedly needs this for FIONBIO definition */
139 #include <sys/filio.h>
143 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
144 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
147 #define INADDR_NONE INADDR_BROADCAST
150 #if defined(__VISAGECPP__) || defined(__WATCOMC__)
152 #define MASK_SIGNAL() {
153 #define UNMASK_SIGNAL() }
156 extern "C" { typedef void (*wxSigHandler
)(int); }
158 #define MASK_SIGNAL() \
160 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
162 #define UNMASK_SIGNAL() \
163 signal(SIGPIPE, old_handler); \
168 /* If a SIGPIPE is issued by a socket call on a remotely closed socket,
169 the program will "crash" unless it explicitly handles the SIGPIPE.
170 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
171 use SO_NOSIGPIPE (if available), the BSD equivalent. */
173 # define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
174 #else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
175 # define GSOCKET_MSG_NOSIGNAL 0
176 #endif /* MSG_NOSIGNAL */
178 #ifndef __GSOCKET_STANDALONE__
179 # include "wx/unix/gsockunx.h"
180 # include "wx/unix/private.h"
181 # include "wx/gsocket.h"
182 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
183 # include "wx/thread.h"
186 # include "gsockunx.h"
187 # include "gsocket.h"
191 #endif /* __GSOCKET_STANDALONE__ */
193 #if defined(HAVE_GETHOSTBYNAME)
194 static struct hostent
* deepCopyHostent(struct hostent
*h
,
195 const struct hostent
*he
,
196 char *buffer
, int size
, int *err
)
198 /* copy old structure */
199 memcpy(h
, he
, sizeof(struct hostent
));
202 int len
= strlen(h
->h_name
);
208 memcpy(buffer
, h
->h_name
, len
);
212 /* track position in the buffer */
215 /* reuse len to store address length */
218 /* ensure pointer alignment */
219 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
220 if(misalign
< sizeof(char *))
223 /* leave space for pointer list */
224 char **p
= h
->h_addr_list
, **q
;
225 char **h_addr_list
= (char **)(buffer
+ pos
);
227 pos
+= sizeof(char *);
229 /* copy addresses and fill new pointer list */
230 for (p
= h
->h_addr_list
, q
= h_addr_list
; *p
!= 0; p
++, q
++)
232 if (size
< pos
+ len
)
237 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
238 *q
= buffer
+ pos
; /* set copied pointer to copied content */
241 *++q
= 0; /* null terminate the pointer list */
242 h
->h_addr_list
= h_addr_list
; /* copy pointer to pointers */
244 /* ensure word alignment of pointers */
245 misalign
= sizeof(char *) - pos%sizeof
(char *);
246 if(misalign
< sizeof(char *))
249 /* leave space for pointer list */
251 char **h_aliases
= (char **)(buffer
+ pos
);
253 pos
+= sizeof(char *);
255 /* copy aliases and fill new pointer list */
256 for (p
= h
->h_aliases
, q
= h_aliases
; *p
!= 0; p
++, q
++)
259 if (size
<= pos
+ len
)
264 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
265 buffer
[pos
+ len
] = '\0';
266 *q
= buffer
+ pos
; /* set copied pointer to copied content */
269 *++q
= 0; /* null terminate the pointer list */
270 h
->h_aliases
= h_aliases
; /* copy pointer to pointers */
276 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
277 static wxMutex nameLock
;
279 struct hostent
* wxGethostbyname_r(const char *hostname
, struct hostent
*h
,
280 void *buffer
, int size
, int *err
)
283 struct hostent
*he
= NULL
;
285 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
286 if (gethostbyname_r(hostname
, h
, (char*)buffer
, size
, &he
, err
))
288 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
289 he
= gethostbyname_r(hostname
, h
, (char*)buffer
, size
, err
);
290 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
291 if (gethostbyname_r(hostname
, h
, (struct hostent_data
*) buffer
))
298 #elif defined(HAVE_GETHOSTBYNAME)
300 wxMutexLocker
locker(nameLock
);
302 he
= gethostbyname(hostname
);
306 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
311 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
312 static wxMutex addrLock
;
314 struct hostent
* wxGethostbyaddr_r(const char *addr_buf
, int buf_size
,
315 int proto
, struct hostent
*h
,
316 void *buffer
, int size
, int *err
)
318 struct hostent
*he
= NULL
;
320 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
321 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
322 (char*)buffer
, size
, &he
, err
))
324 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
325 he
= gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
, (char*)buffer
, size
, err
);
326 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
327 if (gethostbyaddr_r(addr_buf
, buf_size
, proto
, h
,
328 (struct hostent_data
*) buffer
))
335 #elif defined(HAVE_GETHOSTBYNAME)
337 wxMutexLocker
locker(addrLock
);
339 he
= gethostbyaddr(addr_buf
, buf_size
, proto
);
343 he
= deepCopyHostent(h
, he
, (char*)buffer
, size
, err
);
348 #if defined(HAVE_GETSERVBYNAME)
349 static struct servent
* deepCopyServent(struct servent
*s
,
350 const struct servent
*se
,
351 char *buffer
, int size
)
353 /* copy plain old structure */
354 memcpy(s
, se
, sizeof(struct servent
));
357 int len
= strlen(s
->s_name
);
362 memcpy(buffer
, s
->s_name
, len
);
366 /* track position in the buffer */
370 len
= strlen(s
->s_proto
);
371 if (pos
+ len
>= size
)
375 memcpy(buffer
+ pos
, s
->s_proto
, len
);
376 buffer
[pos
+ len
] = '\0';
377 s
->s_proto
= buffer
+ pos
;
379 /* track position in the buffer */
382 /* ensure pointer alignment */
383 unsigned int misalign
= sizeof(char *) - pos%sizeof
(char *);
384 if(misalign
< sizeof(char *))
387 /* leave space for pointer list */
388 char **p
= s
->s_aliases
, **q
;
389 char **s_aliases
= (char **)(buffer
+ pos
);
391 pos
+= sizeof(char *);
393 /* copy addresses and fill new pointer list */
394 for (p
= s
->s_aliases
, q
= s_aliases
; *p
!= 0; p
++, q
++){
396 if (size
<= pos
+ len
)
400 memcpy(buffer
+ pos
, *p
, len
); /* copy content */
401 buffer
[pos
+ len
] = '\0';
402 *q
= buffer
+ pos
; /* set copied pointer to copied content */
405 *++q
= 0; /* null terminate the pointer list */
406 s
->s_aliases
= s_aliases
; /* copy pointer to pointers */
411 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
412 static wxMutex servLock
;
414 struct servent
*wxGetservbyname_r(const char *port
, const char *protocol
,
415 struct servent
*serv
, void *buffer
, int size
)
417 struct servent
*se
= NULL
;
418 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
419 if (getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
, &se
))
421 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
422 se
= getservbyname_r(port
, protocol
, serv
, (char*)buffer
, size
);
423 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
424 if (getservbyname_r(port
, protocol
, serv
, (struct servent_data
*) buffer
))
428 #elif defined(HAVE_GETSERVBYNAME)
430 wxMutexLocker
locker(servLock
);
432 se
= getservbyname(port
, protocol
);
434 se
= deepCopyServent(serv
, se
, (char*)buffer
, size
);
439 /* debugging helpers */
440 #ifdef __GSOCKET_DEBUG__
441 # define GSocket_Debug(args) printf args
443 # define GSocket_Debug(args)
444 #endif /* __GSOCKET_DEBUG__ */
447 typedef struct sockaddr_storage wxSockAddr
;
449 typedef struct sockaddr wxSockAddr
;
452 /* Table of GUI-related functions. We must call them indirectly because
453 * of wxBase and GUI separation: */
457 GSocketManager
* const manager
= GSocketManager::Get();
458 return manager
&& manager
->OnInit();
461 void GSocket_Cleanup()
463 GSocketManager
* const manager
= GSocketManager::Get();
468 /* Constructors / Destructors for GSocket */
470 GSocket::GSocket(wxSocketBase
& wxsocket
)
471 : GSocketBase(wxsocket
)
475 m_gui_dependent
= NULL
;
476 m_use_events
= false;
479 void GSocket::Close()
484 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
485 will close the socket during Disable_Events. However, it will only do this
486 if it is being used. That is, it won't do it in a console program. To
487 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
488 if it has closed the socket which indicates to us (at runtime, instead of
489 at compile time as this had been before) that the socket has already
492 if(m_fd
!= INVALID_SOCKET
)
494 m_fd
= INVALID_SOCKET
;
503 * Disallow further read/write operations on this socket, close
504 * the fd and disable all callbacks.
506 void GSocket::Shutdown()
508 /* Don't allow events to fire after socket has been closed */
512 GSocketBase::Shutdown();
515 /* Address handling */
521 * Set or get the local or peer address for this socket. The 'set'
522 * functions return GSOCK_NOERROR on success, an error code otherwise.
523 * The 'get' functions return a pointer to a GAddress object on success,
524 * or NULL otherwise, in which case they set the error code of the
525 * corresponding GSocket.
528 * GSOCK_INVSOCK - the socket is not valid.
529 * GSOCK_INVADDR - the address is not valid.
531 GSocketError
GSocket::SetLocal(GAddress
*address
)
535 /* the socket must be initialized, or it must be a server */
536 if ((m_fd
!= INVALID_SOCKET
&& !m_server
))
538 m_error
= GSOCK_INVSOCK
;
539 return GSOCK_INVSOCK
;
543 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
545 m_error
= GSOCK_INVADDR
;
546 return GSOCK_INVADDR
;
550 GAddress_destroy(m_local
);
552 m_local
= GAddress_copy(address
);
554 return GSOCK_NOERROR
;
557 GSocketError
GSocket::SetPeer(GAddress
*address
)
562 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
564 m_error
= GSOCK_INVADDR
;
565 return GSOCK_INVADDR
;
569 GAddress_destroy(m_peer
);
571 m_peer
= GAddress_copy(address
);
573 return GSOCK_NOERROR
;
576 GAddress
*GSocket::GetLocal()
580 WX_SOCKLEN_T size
= sizeof(addr
);
585 /* try to get it from the m_local var first */
587 return GAddress_copy(m_local
);
589 /* else, if the socket is initialized, try getsockname */
590 if (m_fd
== INVALID_SOCKET
)
592 m_error
= GSOCK_INVSOCK
;
596 if (getsockname(m_fd
, (sockaddr
*)&addr
, (WX_SOCKLEN_T
*) &size
) < 0)
598 m_error
= GSOCK_IOERR
;
602 /* got a valid address from getsockname, create a GAddress object */
603 address
= GAddress_new();
606 m_error
= GSOCK_MEMERR
;
610 err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
);
611 if (err
!= GSOCK_NOERROR
)
613 GAddress_destroy(address
);
621 GAddress
*GSocket::GetPeer()
625 /* try to get it from the m_peer var */
627 return GAddress_copy(m_peer
);
632 /* Server specific parts */
634 /* GSocket_SetServer:
635 * Sets up this socket as a server. The local address must have been
636 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
637 * Returns GSOCK_NOERROR on success, one of the following otherwise:
640 * GSOCK_INVSOCK - the socket is in use.
641 * GSOCK_INVADDR - the local address has not been set.
642 * GSOCK_IOERR - low-level error.
644 GSocketError
GSocket::SetServer()
650 /* must not be in use */
651 if (m_fd
!= INVALID_SOCKET
)
653 m_error
= GSOCK_INVSOCK
;
654 return GSOCK_INVSOCK
;
657 /* the local addr must have been set */
660 m_error
= GSOCK_INVADDR
;
661 return GSOCK_INVADDR
;
664 /* Initialize all fields */
668 /* Create the socket */
669 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
671 if (m_fd
== INVALID_SOCKET
)
673 m_error
= GSOCK_IOERR
;
677 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
679 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
682 ioctl(m_fd
, FIONBIO
, &arg
);
686 /* allow a socket to re-bind if the socket is in the TIME_WAIT
687 state after being previously closed.
691 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
693 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
697 /* Bind to the local address,
698 * retrieve the actual address bound,
699 * and listen up to 5 connections.
701 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
704 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
705 (listen(m_fd
, 5) != 0))
708 m_error
= GSOCK_IOERR
;
712 return GSOCK_NOERROR
;
715 /* GSocket_WaitConnection:
716 * Waits for an incoming client connection. Returns a pointer to
717 * a GSocket object, or NULL if there was an error, in which case
718 * the last error field will be updated for the calling GSocket.
720 * Error codes (set in the calling GSocket)
721 * GSOCK_INVSOCK - the socket is not valid or not a server.
722 * GSOCK_TIMEDOUT - timeout, no incoming connections.
723 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
724 * GSOCK_MEMERR - couldn't allocate memory.
725 * GSOCK_IOERR - low-level error.
727 GSocket
*GSocket::WaitConnection(wxSocketBase
& wxsocket
)
730 WX_SOCKLEN_T fromlen
= sizeof(from
);
737 /* If the socket has already been created, we exit immediately */
738 if (m_fd
== INVALID_SOCKET
|| !m_server
)
740 m_error
= GSOCK_INVSOCK
;
744 /* Create a GSocket object for the new connection */
745 connection
= GSocket::Create(wxsocket
);
749 m_error
= GSOCK_MEMERR
;
753 /* Wait for a connection (with timeout) */
754 if (Input_Timeout() == GSOCK_TIMEDOUT
)
757 /* m_error set by _GSocket_Input_Timeout */
761 connection
->m_fd
= accept(m_fd
, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
763 /* Reenable CONNECTION events */
764 Enable(GSOCK_CONNECTION
);
766 if (connection
->m_fd
== INVALID_SOCKET
)
768 if (errno
== EWOULDBLOCK
)
769 m_error
= GSOCK_WOULDBLOCK
;
771 m_error
= GSOCK_IOERR
;
777 /* Initialize all fields */
778 connection
->m_server
= false;
779 connection
->m_stream
= true;
781 /* Setup the peer address field */
782 connection
->m_peer
= GAddress_new();
783 if (!connection
->m_peer
)
786 m_error
= GSOCK_MEMERR
;
790 err
= _GAddress_translate_from(connection
->m_peer
, (sockaddr
*)&from
, fromlen
);
791 if (err
!= GSOCK_NOERROR
)
798 #if defined(__EMX__) || defined(__VISAGECPP__)
799 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
801 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
804 connection
->Notify(true);
809 void GSocket::Notify(bool flag
)
811 if (flag
== m_use_events
)
817 void GSocket::EnableEvents(bool flag
)
820 GSocketManager::Get()->Enable_Events(this);
822 GSocketManager::Get()->Disable_Events(this);
825 bool GSocket::SetReusable()
827 /* socket must not be null, and must not be in use/already bound */
828 if (this && m_fd
== INVALID_SOCKET
)
838 bool GSocket::SetBroadcast()
840 /* socket must not be in use/already bound */
841 if (m_fd
== INVALID_SOCKET
) {
848 bool GSocket::DontDoBind()
850 /* socket must not be in use/already bound */
851 if (m_fd
== INVALID_SOCKET
) {
858 /* Client specific parts */
861 * For stream (connection oriented) sockets, GSocket_Connect() tries
862 * to establish a client connection to a server using the peer address
863 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
864 * connection has been successfully established, or one of the error
865 * codes listed below. Note that for nonblocking sockets, a return
866 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
867 * request can be completed later; you should use GSocket_Select()
868 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
869 * corresponding asynchronous events.
871 * For datagram (non connection oriented) sockets, GSocket_Connect()
872 * just sets the peer address established with GSocket_SetPeer() as
873 * default destination.
876 * GSOCK_INVSOCK - the socket is in use or not valid.
877 * GSOCK_INVADDR - the peer address has not been established.
878 * GSOCK_TIMEDOUT - timeout, the connection failed.
879 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
880 * GSOCK_MEMERR - couldn't allocate memory.
881 * GSOCK_IOERR - low-level error.
883 GSocketError
GSocket::Connect(GSocketStream stream
)
890 /* Enable CONNECTION events (needed for nonblocking connections) */
891 Enable(GSOCK_CONNECTION
);
893 if (m_fd
!= INVALID_SOCKET
)
895 m_error
= GSOCK_INVSOCK
;
896 return GSOCK_INVSOCK
;
901 m_error
= GSOCK_INVADDR
;
902 return GSOCK_INVADDR
;
905 /* Streamed or dgram socket? */
906 m_stream
= (stream
== GSOCK_STREAMED
);
908 m_establishing
= false;
910 /* Create the socket */
911 m_fd
= socket(m_peer
->m_realfamily
,
912 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
914 if (m_fd
== INVALID_SOCKET
)
916 m_error
= GSOCK_IOERR
;
920 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
922 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
925 #if defined(__EMX__) || defined(__VISAGECPP__)
926 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
928 ioctl(m_fd
, FIONBIO
, &arg
);
931 // If the reuse flag is set, use the applicable socket reuse flags(s)
934 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
936 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
940 if (m_initialRecvBufferSize
>= 0)
941 setsockopt(m_fd
, SOL_SOCKET
, SO_RCVBUF
, (const char*)&m_initialRecvBufferSize
, sizeof(m_initialRecvBufferSize
));
942 if (m_initialSendBufferSize
>= 0)
943 setsockopt(m_fd
, SOL_SOCKET
, SO_SNDBUF
, (const char*)&m_initialSendBufferSize
, sizeof(m_initialSendBufferSize
));
945 // If a local address has been set, then we need to bind to it before calling connect
946 if (m_local
&& m_local
->m_addr
)
948 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
951 /* Connect it to the peer address, with a timeout (see below) */
952 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
954 /* We only call Enable_Events if we know we aren't shutting down the socket.
955 * NB: Enable_Events needs to be called whether the socket is blocking or
956 * non-blocking, it just shouldn't be called prior to knowing there is a
957 * connection _if_ blocking sockets are being used.
958 * If connect above returns 0, we are already connected and need to make the
959 * call to Enable_Events now.
962 if (m_use_events
&& (m_non_blocking
|| ret
== 0))
969 /* If connect failed with EINPROGRESS and the GSocket object
970 * is in blocking mode, we select() for the specified timeout
971 * checking for writability to see if the connection request
974 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
976 if (Output_Timeout() == GSOCK_TIMEDOUT
)
979 /* m_error is set in _GSocket_Output_Timeout */
980 return GSOCK_TIMEDOUT
;
985 SOCKOPTLEN_T len
= sizeof(error
);
987 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
992 return GSOCK_NOERROR
;
996 /* If connect failed with EINPROGRESS and the GSocket object
997 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
998 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
999 * this way if the connection completes, a GSOCK_CONNECTION
1000 * event will be generated, if enabled.
1002 if ((err
== EINPROGRESS
) && (m_non_blocking
))
1004 m_establishing
= true;
1005 m_error
= GSOCK_WOULDBLOCK
;
1006 return GSOCK_WOULDBLOCK
;
1009 /* If connect failed with an error other than EINPROGRESS,
1010 * then the call to GSocket_Connect has failed.
1013 m_error
= GSOCK_IOERR
;
1018 return GSOCK_NOERROR
;
1021 /* Datagram sockets */
1023 /* GSocket_SetNonOriented:
1024 * Sets up this socket as a non-connection oriented (datagram) socket.
1025 * Before using this function, the local address must have been set
1026 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1027 * on success, or one of the following otherwise.
1030 * GSOCK_INVSOCK - the socket is in use.
1031 * GSOCK_INVADDR - the local address has not been set.
1032 * GSOCK_IOERR - low-level error.
1034 GSocketError
GSocket::SetNonOriented()
1040 if (m_fd
!= INVALID_SOCKET
)
1042 m_error
= GSOCK_INVSOCK
;
1043 return GSOCK_INVSOCK
;
1048 m_error
= GSOCK_INVADDR
;
1049 return GSOCK_INVADDR
;
1052 /* Initialize all fields */
1056 /* Create the socket */
1057 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
1059 if (m_fd
== INVALID_SOCKET
)
1061 m_error
= GSOCK_IOERR
;
1064 #if defined(__EMX__) || defined(__VISAGECPP__)
1065 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1067 ioctl(m_fd
, FIONBIO
, &arg
);
1074 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1076 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1082 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
1086 /* Bind to the local address,
1087 * and retrieve the actual address bound.
1089 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
1092 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
1095 m_error
= GSOCK_IOERR
;
1099 return GSOCK_NOERROR
;
1104 /* Like recv(), send(), ... */
1105 int GSocket::Read(char *buffer
, int size
)
1111 if (m_fd
== INVALID_SOCKET
|| m_server
)
1113 m_error
= GSOCK_INVSOCK
;
1117 /* Disable events during query of socket status */
1118 Disable(GSOCK_INPUT
);
1120 /* If the socket is blocking, wait for data (with a timeout) */
1121 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
1122 m_error
= GSOCK_TIMEDOUT
;
1123 /* Don't return here immediately, otherwise socket events would not be
1131 ret
= Recv_Stream(buffer
, size
);
1133 ret
= Recv_Dgram(buffer
, size
);
1136 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1137 * socket and empty datagrams are possible), then the connection has been
1138 * gracefully closed.
1140 * Otherwise, recv has returned an error (-1), in which case we have lost
1141 * the socket only if errno does _not_ indicate that there may be more data
1144 if ((ret
== 0) && m_stream
)
1146 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1149 m_detected
= GSOCK_LOST_FLAG
;
1156 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1157 m_error
= GSOCK_WOULDBLOCK
;
1159 m_error
= GSOCK_IOERR
;
1163 /* Enable events again now that we are done processing */
1164 Enable(GSOCK_INPUT
);
1169 int GSocket::Write(const char *buffer
, int size
)
1175 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1177 if (m_fd
== INVALID_SOCKET
|| m_server
)
1179 m_error
= GSOCK_INVSOCK
;
1183 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1185 /* If the socket is blocking, wait for writability (with a timeout) */
1186 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1189 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1191 /* Write the data */
1193 ret
= Send_Stream(buffer
, size
);
1195 ret
= Send_Dgram(buffer
, size
);
1197 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1201 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1203 m_error
= GSOCK_WOULDBLOCK
;
1204 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1208 m_error
= GSOCK_IOERR
;
1209 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1212 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1213 * in MSW). Once the first OUTPUT event is received, users can assume
1214 * that the socket is writable until a read operation fails. Only then
1215 * will further OUTPUT events be posted.
1217 Enable(GSOCK_OUTPUT
);
1222 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1229 /* GSocket_SetNonBlocking:
1230 * Sets the socket to non-blocking mode. All IO calls will return
1233 void GSocket::SetNonBlocking(bool non_block
)
1237 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1239 m_non_blocking
= non_block
;
1242 /* GSocket_GetError:
1243 * Returns the last error occurred for this socket. Note that successful
1244 * operations do not clear this back to GSOCK_NOERROR, so use it only
1247 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1254 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1255 void *optval
, int *optlen
)
1257 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1258 return GSOCK_NOERROR
;
1260 return GSOCK_OPTERR
;
1263 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1264 const void *optval
, int optlen
)
1266 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1267 return GSOCK_NOERROR
;
1269 return GSOCK_OPTERR
;
1272 void GSocket::Enable(GSocketEvent event
)
1276 m_detected
&= ~(1 << event
);
1277 GSocketManager::Get()->Install_Callback(this, event
);
1281 void GSocket::Disable(GSocketEvent event
)
1285 m_detected
|= (1 << event
);
1286 GSocketManager::Get()->Uninstall_Callback(this, event
);
1290 /* _GSocket_Input_Timeout:
1291 * For blocking sockets, wait until data is available or
1292 * until timeout ellapses.
1294 GSocketError
GSocket::Input_Timeout()
1300 /* Linux select() will overwrite the struct on return */
1301 tv
.tv_sec
= (m_timeout
/ 1000);
1302 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1304 if (!m_non_blocking
)
1306 wxFD_ZERO(&readfds
);
1307 wxFD_SET(m_fd
, &readfds
);
1308 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1311 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1312 m_error
= GSOCK_TIMEDOUT
;
1313 return GSOCK_TIMEDOUT
;
1318 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1319 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1320 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1321 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1322 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1323 m_error
= GSOCK_TIMEDOUT
;
1324 return GSOCK_TIMEDOUT
;
1328 return GSOCK_NOERROR
;
1331 /* _GSocket_Output_Timeout:
1332 * For blocking sockets, wait until data can be sent without
1333 * blocking or until timeout ellapses.
1335 GSocketError
GSocket::Output_Timeout()
1341 /* Linux select() will overwrite the struct on return */
1342 tv
.tv_sec
= (m_timeout
/ 1000);
1343 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1345 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1347 if (!m_non_blocking
)
1349 wxFD_ZERO(&writefds
);
1350 wxFD_SET(m_fd
, &writefds
);
1351 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1354 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1355 m_error
= GSOCK_TIMEDOUT
;
1356 return GSOCK_TIMEDOUT
;
1361 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1362 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1363 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1364 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1365 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1366 m_error
= GSOCK_TIMEDOUT
;
1367 return GSOCK_TIMEDOUT
;
1370 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1372 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1376 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1381 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1384 return GSOCK_NOERROR
;
1387 int GSocket::Recv_Stream(char *buffer
, int size
)
1392 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1394 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1399 int GSocket::Recv_Dgram(char *buffer
, int size
)
1402 WX_SOCKLEN_T fromlen
= sizeof(from
);
1406 fromlen
= sizeof(from
);
1410 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1412 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1417 /* Translate a system address into a GSocket address */
1420 m_peer
= GAddress_new();
1423 m_error
= GSOCK_MEMERR
;
1428 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1429 if (err
!= GSOCK_NOERROR
)
1431 GAddress_destroy(m_peer
);
1440 int GSocket::Send_Stream(const char *buffer
, int size
)
1448 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1450 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1457 int GSocket::Send_Dgram(const char *buffer
, int size
)
1459 struct sockaddr
*addr
;
1465 m_error
= GSOCK_INVADDR
;
1469 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1470 if (err
!= GSOCK_NOERROR
)
1480 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1482 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1486 /* Frees memory allocated from _GAddress_translate_to */
1492 void GSocket::OnStateChange(GSocketEvent event
)
1495 NotifyOnStateChange(event
);
1497 if ( event
== GSOCK_LOST
)
1501 void GSocket::Detected_Read()
1505 /* Safeguard against straggling call to Detected_Read */
1506 if (m_fd
== INVALID_SOCKET
)
1511 /* If we have already detected a LOST event, then don't try
1512 * to do any further processing.
1514 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1516 m_establishing
= false;
1518 OnStateChange(GSOCK_LOST
);
1522 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1526 OnStateChange(GSOCK_INPUT
);
1530 if (m_server
&& m_stream
)
1532 OnStateChange(GSOCK_CONNECTION
);
1538 /* graceful shutdown */
1539 OnStateChange(GSOCK_LOST
);
1543 /* Empty datagram received */
1544 OnStateChange(GSOCK_INPUT
);
1549 /* Do not throw a lost event in cases where the socket isn't really lost */
1550 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1552 OnStateChange(GSOCK_INPUT
);
1556 OnStateChange(GSOCK_LOST
);
1562 void GSocket::Detected_Write()
1564 /* If we have already detected a LOST event, then don't try
1565 * to do any further processing.
1567 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1569 m_establishing
= false;
1571 OnStateChange(GSOCK_LOST
);
1575 if (m_establishing
&& !m_server
)
1578 SOCKOPTLEN_T len
= sizeof(error
);
1580 m_establishing
= false;
1582 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1586 OnStateChange(GSOCK_LOST
);
1590 OnStateChange(GSOCK_CONNECTION
);
1591 /* We have to fire this event by hand because CONNECTION (for clients)
1592 * and OUTPUT are internally the same and we just disabled CONNECTION
1593 * events with the above macro.
1595 OnStateChange(GSOCK_OUTPUT
);
1600 OnStateChange(GSOCK_OUTPUT
);
1605 * -------------------------------------------------------------------------
1607 * -------------------------------------------------------------------------
1610 /* CHECK_ADDRESS verifies that the current address family is either
1611 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1612 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1613 * an appropiate error code.
1615 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1617 #define CHECK_ADDRESS(address, family) \
1619 if (address->m_family == GSOCK_NOFAMILY) \
1620 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1621 return address->m_error; \
1622 if (address->m_family != GSOCK_##family) \
1624 address->m_error = GSOCK_INVADDR; \
1625 return GSOCK_INVADDR; \
1629 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1631 if (address->m_family == GSOCK_NOFAMILY) \
1632 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1634 if (address->m_family != GSOCK_##family) \
1636 address->m_error = GSOCK_INVADDR; \
1642 GAddress
*GAddress_new(void)
1646 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1649 address
->m_family
= GSOCK_NOFAMILY
;
1650 address
->m_addr
= NULL
;
1656 GAddress
*GAddress_copy(GAddress
*address
)
1660 assert(address
!= NULL
);
1662 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1665 memcpy(addr2
, address
, sizeof(GAddress
));
1667 if (address
->m_addr
&& address
->m_len
> 0)
1669 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1670 if (addr2
->m_addr
== NULL
)
1675 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1681 void GAddress_destroy(GAddress
*address
)
1683 assert(address
!= NULL
);
1685 if (address
->m_addr
)
1686 free(address
->m_addr
);
1691 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1693 assert(address
!= NULL
);
1695 address
->m_family
= type
;
1698 GAddressType
GAddress_GetFamily(GAddress
*address
)
1700 assert(address
!= NULL
);
1702 return address
->m_family
;
1705 GSocketError
_GAddress_translate_from(GAddress
*address
,
1706 struct sockaddr
*addr
, int len
)
1708 address
->m_realfamily
= addr
->sa_family
;
1709 switch (addr
->sa_family
)
1712 address
->m_family
= GSOCK_INET
;
1715 address
->m_family
= GSOCK_UNIX
;
1719 address
->m_family
= GSOCK_INET6
;
1721 #endif // wxUSE_IPV6
1724 address
->m_error
= GSOCK_INVOP
;
1729 if (address
->m_addr
)
1730 free(address
->m_addr
);
1732 address
->m_len
= len
;
1733 address
->m_addr
= (struct sockaddr
*)malloc(len
);
1735 if (address
->m_addr
== NULL
)
1737 address
->m_error
= GSOCK_MEMERR
;
1738 return GSOCK_MEMERR
;
1741 memcpy(address
->m_addr
, addr
, len
);
1743 return GSOCK_NOERROR
;
1746 GSocketError
_GAddress_translate_to(GAddress
*address
,
1747 struct sockaddr
**addr
, int *len
)
1749 if (!address
->m_addr
)
1751 address
->m_error
= GSOCK_INVADDR
;
1752 return GSOCK_INVADDR
;
1755 *len
= address
->m_len
;
1756 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
1759 address
->m_error
= GSOCK_MEMERR
;
1760 return GSOCK_MEMERR
;
1763 memcpy(*addr
, address
->m_addr
, address
->m_len
);
1764 return GSOCK_NOERROR
;
1768 * -------------------------------------------------------------------------
1769 * Internet address family
1770 * -------------------------------------------------------------------------
1773 GSocketError
_GAddress_Init_INET(GAddress
*address
)
1775 address
->m_len
= sizeof(struct sockaddr_in
);
1776 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1777 if (address
->m_addr
== NULL
)
1779 address
->m_error
= GSOCK_MEMERR
;
1780 return GSOCK_MEMERR
;
1783 address
->m_family
= GSOCK_INET
;
1784 address
->m_realfamily
= PF_INET
;
1785 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
1786 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
1788 return GSOCK_NOERROR
;
1791 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
1794 struct in_addr
*addr
;
1796 assert(address
!= NULL
);
1798 CHECK_ADDRESS(address
, INET
);
1800 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1802 /* If it is a numeric host name, convert it now */
1803 #if defined(HAVE_INET_ATON)
1804 if (inet_aton(hostname
, addr
) == 0)
1806 #elif defined(HAVE_INET_ADDR)
1807 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
1810 /* Use gethostbyname by default */
1812 int val
= 1; /* VA doesn't like constants in conditional expressions */
1817 struct in_addr
*array_addr
;
1819 /* It is a real name, we solve it */
1821 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1822 struct hostent_data buffer
;
1827 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
1830 /* Reset to invalid address */
1831 addr
->s_addr
= INADDR_NONE
;
1832 address
->m_error
= GSOCK_NOHOST
;
1833 return GSOCK_NOHOST
;
1836 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
1837 addr
->s_addr
= array_addr
[0].s_addr
;
1840 return GSOCK_NOERROR
;
1844 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
1846 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
1849 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
1851 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
1854 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
1855 unsigned long hostaddr
)
1857 struct in_addr
*addr
;
1859 assert(address
!= NULL
);
1861 CHECK_ADDRESS(address
, INET
);
1863 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1864 addr
->s_addr
= htonl(hostaddr
);
1866 return GSOCK_NOERROR
;
1869 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
1870 const char *protocol
)
1873 struct sockaddr_in
*addr
;
1875 assert(address
!= NULL
);
1876 CHECK_ADDRESS(address
, INET
);
1880 address
->m_error
= GSOCK_INVPORT
;
1881 return GSOCK_INVPORT
;
1884 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
1885 struct servent_data buffer
;
1889 struct servent serv
;
1890 se
= wxGetservbyname_r(port
, protocol
, &serv
,
1891 (void*)&buffer
, sizeof(buffer
));
1894 /* the cast to int suppresses compiler warnings about subscript having the
1896 if (isdigit((int)port
[0]))
1900 port_int
= atoi(port
);
1901 addr
= (struct sockaddr_in
*)address
->m_addr
;
1902 addr
->sin_port
= htons(port_int
);
1903 return GSOCK_NOERROR
;
1906 address
->m_error
= GSOCK_INVPORT
;
1907 return GSOCK_INVPORT
;
1910 addr
= (struct sockaddr_in
*)address
->m_addr
;
1911 addr
->sin_port
= se
->s_port
;
1913 return GSOCK_NOERROR
;
1916 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
1918 struct sockaddr_in
*addr
;
1920 assert(address
!= NULL
);
1921 CHECK_ADDRESS(address
, INET
);
1923 addr
= (struct sockaddr_in
*)address
->m_addr
;
1924 addr
->sin_port
= htons(port
);
1926 return GSOCK_NOERROR
;
1929 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
1933 struct sockaddr_in
*addr
;
1935 assert(address
!= NULL
);
1936 CHECK_ADDRESS(address
, INET
);
1938 addr
= (struct sockaddr_in
*)address
->m_addr
;
1939 addr_buf
= (char *)&(addr
->sin_addr
);
1941 struct hostent temphost
;
1942 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1943 struct hostent_data buffer
;
1948 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
1949 (void*)&buffer
, sizeof(buffer
), &err
);
1952 address
->m_error
= GSOCK_NOHOST
;
1953 return GSOCK_NOHOST
;
1956 strncpy(hostname
, he
->h_name
, sbuf
);
1958 return GSOCK_NOERROR
;
1961 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
1963 struct sockaddr_in
*addr
;
1965 assert(address
!= NULL
);
1966 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1968 addr
= (struct sockaddr_in
*)address
->m_addr
;
1970 return ntohl(addr
->sin_addr
.s_addr
);
1973 unsigned short GAddress_INET_GetPort(GAddress
*address
)
1975 struct sockaddr_in
*addr
;
1977 assert(address
!= NULL
);
1978 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1980 addr
= (struct sockaddr_in
*)address
->m_addr
;
1981 return ntohs(addr
->sin_port
);
1986 * -------------------------------------------------------------------------
1987 * Internet IPv6 address family
1988 * -------------------------------------------------------------------------
1991 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
1993 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
1994 address
->m_len
= sizeof(struct sockaddr_in6
);
1995 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1996 if (address
->m_addr
== NULL
)
1998 address
->m_error
= GSOCK_MEMERR
;
1999 return GSOCK_MEMERR
;
2001 memset(address
->m_addr
,0,address
->m_len
);
2003 address
->m_family
= GSOCK_INET6
;
2004 address
->m_realfamily
= AF_INET6
;
2005 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
2006 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
2008 return GSOCK_NOERROR
;
2011 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
2013 assert(address
!= NULL
);
2014 CHECK_ADDRESS(address
, INET6
);
2017 memset( & hints
, 0, sizeof( hints
) );
2018 hints
.ai_family
= AF_INET6
;
2019 addrinfo
* info
= 0;
2020 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
2022 address
->m_error
= GSOCK_NOHOST
;
2023 return GSOCK_NOHOST
;
2026 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
2027 freeaddrinfo( info
);
2028 return GSOCK_NOERROR
;
2031 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
2033 assert(address
!= NULL
);
2035 CHECK_ADDRESS(address
, INET6
);
2037 struct in6_addr addr
;
2038 memset( & addr
, 0, sizeof( addr
) );
2039 return GAddress_INET6_SetHostAddress(address
, addr
);
2041 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
2042 struct in6_addr hostaddr
)
2044 assert(address
!= NULL
);
2046 CHECK_ADDRESS(address
, INET6
);
2048 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
2050 return GSOCK_NOERROR
;
2053 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
2054 const char *protocol
)
2057 struct sockaddr_in6
*addr
;
2059 assert(address
!= NULL
);
2060 CHECK_ADDRESS(address
, INET6
);
2064 address
->m_error
= GSOCK_INVPORT
;
2065 return GSOCK_INVPORT
;
2068 se
= getservbyname(port
, protocol
);
2071 if (isdigit(port
[0]))
2075 port_int
= atoi(port
);
2076 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2077 addr
->sin6_port
= htons((u_short
) port_int
);
2078 return GSOCK_NOERROR
;
2081 address
->m_error
= GSOCK_INVPORT
;
2082 return GSOCK_INVPORT
;
2085 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2086 addr
->sin6_port
= se
->s_port
;
2088 return GSOCK_NOERROR
;
2091 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
2093 struct sockaddr_in6
*addr
;
2095 assert(address
!= NULL
);
2096 CHECK_ADDRESS(address
, INET6
);
2098 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2099 addr
->sin6_port
= htons(port
);
2101 return GSOCK_NOERROR
;
2104 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2108 struct sockaddr_in6
*addr
;
2110 assert(address
!= NULL
);
2111 CHECK_ADDRESS(address
, INET6
);
2113 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2114 addr_buf
= (char *)&(addr
->sin6_addr
);
2116 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
2119 address
->m_error
= GSOCK_NOHOST
;
2120 return GSOCK_NOHOST
;
2123 strncpy(hostname
, he
->h_name
, sbuf
);
2125 return GSOCK_NOERROR
;
2128 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
2130 assert(address
!= NULL
);
2131 assert(hostaddr
!= NULL
);
2132 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
2133 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
2134 return GSOCK_NOERROR
;
2137 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2139 assert(address
!= NULL
);
2140 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2142 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2145 #endif // wxUSE_IPV6
2148 * -------------------------------------------------------------------------
2149 * Unix address family
2150 * -------------------------------------------------------------------------
2153 #ifndef __VISAGECPP__
2154 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2156 address
->m_len
= sizeof(struct sockaddr_un
);
2157 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2158 if (address
->m_addr
== NULL
)
2160 address
->m_error
= GSOCK_MEMERR
;
2161 return GSOCK_MEMERR
;
2164 address
->m_family
= GSOCK_UNIX
;
2165 address
->m_realfamily
= PF_UNIX
;
2166 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2167 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2169 return GSOCK_NOERROR
;
2172 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2174 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2176 struct sockaddr_un
*addr
;
2178 assert(address
!= NULL
);
2180 CHECK_ADDRESS(address
, UNIX
);
2182 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2183 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2184 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2186 return GSOCK_NOERROR
;
2189 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2191 struct sockaddr_un
*addr
;
2193 assert(address
!= NULL
);
2194 CHECK_ADDRESS(address
, UNIX
);
2196 addr
= (struct sockaddr_un
*)address
->m_addr
;
2198 strncpy(path
, addr
->sun_path
, sbuf
);
2200 return GSOCK_NOERROR
;
2202 #endif /* !defined(__VISAGECPP__) */
2203 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */