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 */
474 m_gui_dependent
= NULL
;
475 m_use_events
= false;
478 void GSocket::Close()
483 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
484 will close the socket during Disable_Events. However, it will only do this
485 if it is being used. That is, it won't do it in a console program. To
486 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
487 if it has closed the socket which indicates to us (at runtime, instead of
488 at compile time as this had been before) that the socket has already
491 if(m_fd
!= INVALID_SOCKET
)
493 m_fd
= INVALID_SOCKET
;
502 * Disallow further read/write operations on this socket, close
503 * the fd and disable all callbacks.
505 void GSocket::Shutdown()
507 /* Don't allow events to fire after socket has been closed */
511 GSocketBase::Shutdown();
514 /* Address handling */
520 * Set or get the local or peer address for this socket. The 'set'
521 * functions return GSOCK_NOERROR on success, an error code otherwise.
522 * The 'get' functions return a pointer to a GAddress object on success,
523 * or NULL otherwise, in which case they set the error code of the
524 * corresponding GSocket.
527 * GSOCK_INVSOCK - the socket is not valid.
528 * GSOCK_INVADDR - the address is not valid.
530 GSocketError
GSocket::SetLocal(GAddress
*address
)
534 /* the socket must be initialized, or it must be a server */
535 if ((m_fd
!= INVALID_SOCKET
&& !m_server
))
537 m_error
= GSOCK_INVSOCK
;
538 return GSOCK_INVSOCK
;
542 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
544 m_error
= GSOCK_INVADDR
;
545 return GSOCK_INVADDR
;
549 GAddress_destroy(m_local
);
551 m_local
= GAddress_copy(address
);
553 return GSOCK_NOERROR
;
556 GSocketError
GSocket::SetPeer(GAddress
*address
)
561 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
563 m_error
= GSOCK_INVADDR
;
564 return GSOCK_INVADDR
;
568 GAddress_destroy(m_peer
);
570 m_peer
= GAddress_copy(address
);
572 return GSOCK_NOERROR
;
575 GAddress
*GSocket::GetLocal()
579 WX_SOCKLEN_T size
= sizeof(addr
);
584 /* try to get it from the m_local var first */
586 return GAddress_copy(m_local
);
588 /* else, if the socket is initialized, try getsockname */
589 if (m_fd
== INVALID_SOCKET
)
591 m_error
= GSOCK_INVSOCK
;
595 if (getsockname(m_fd
, (sockaddr
*)&addr
, (WX_SOCKLEN_T
*) &size
) < 0)
597 m_error
= GSOCK_IOERR
;
601 /* got a valid address from getsockname, create a GAddress object */
602 address
= GAddress_new();
605 m_error
= GSOCK_MEMERR
;
609 err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
);
610 if (err
!= GSOCK_NOERROR
)
612 GAddress_destroy(address
);
620 GAddress
*GSocket::GetPeer()
624 /* try to get it from the m_peer var */
626 return GAddress_copy(m_peer
);
631 /* Server specific parts */
633 /* GSocket_SetServer:
634 * Sets up this socket as a server. The local address must have been
635 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
636 * Returns GSOCK_NOERROR on success, one of the following otherwise:
639 * GSOCK_INVSOCK - the socket is in use.
640 * GSOCK_INVADDR - the local address has not been set.
641 * GSOCK_IOERR - low-level error.
643 GSocketError
GSocket::SetServer()
649 /* must not be in use */
650 if (m_fd
!= INVALID_SOCKET
)
652 m_error
= GSOCK_INVSOCK
;
653 return GSOCK_INVSOCK
;
656 /* the local addr must have been set */
659 m_error
= GSOCK_INVADDR
;
660 return GSOCK_INVADDR
;
663 /* Initialize all fields */
667 /* Create the socket */
668 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
670 if (m_fd
== INVALID_SOCKET
)
672 m_error
= GSOCK_IOERR
;
676 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
678 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
681 ioctl(m_fd
, FIONBIO
, &arg
);
685 /* allow a socket to re-bind if the socket is in the TIME_WAIT
686 state after being previously closed.
690 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
692 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
696 /* Bind to the local address,
697 * retrieve the actual address bound,
698 * and listen up to 5 connections.
700 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
703 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0) ||
704 (listen(m_fd
, 5) != 0))
707 m_error
= GSOCK_IOERR
;
711 return GSOCK_NOERROR
;
714 /* GSocket_WaitConnection:
715 * Waits for an incoming client connection. Returns a pointer to
716 * a GSocket object, or NULL if there was an error, in which case
717 * the last error field will be updated for the calling GSocket.
719 * Error codes (set in the calling GSocket)
720 * GSOCK_INVSOCK - the socket is not valid or not a server.
721 * GSOCK_TIMEDOUT - timeout, no incoming connections.
722 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
723 * GSOCK_MEMERR - couldn't allocate memory.
724 * GSOCK_IOERR - low-level error.
726 GSocket
*GSocket::WaitConnection()
729 WX_SOCKLEN_T fromlen
= sizeof(from
);
736 /* If the socket has already been created, we exit immediately */
737 if (m_fd
== INVALID_SOCKET
|| !m_server
)
739 m_error
= GSOCK_INVSOCK
;
743 /* Create a GSocket object for the new connection */
744 connection
= GSocket::Create();
748 m_error
= GSOCK_MEMERR
;
752 /* Wait for a connection (with timeout) */
753 if (Input_Timeout() == GSOCK_TIMEDOUT
)
756 /* m_error set by _GSocket_Input_Timeout */
760 connection
->m_fd
= accept(m_fd
, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
762 /* Reenable CONNECTION events */
763 Enable(GSOCK_CONNECTION
);
765 if (connection
->m_fd
== INVALID_SOCKET
)
767 if (errno
== EWOULDBLOCK
)
768 m_error
= GSOCK_WOULDBLOCK
;
770 m_error
= GSOCK_IOERR
;
776 /* Initialize all fields */
777 connection
->m_server
= false;
778 connection
->m_stream
= true;
780 /* Setup the peer address field */
781 connection
->m_peer
= GAddress_new();
782 if (!connection
->m_peer
)
785 m_error
= GSOCK_MEMERR
;
789 err
= _GAddress_translate_from(connection
->m_peer
, (sockaddr
*)&from
, fromlen
);
790 if (err
!= GSOCK_NOERROR
)
797 #if defined(__EMX__) || defined(__VISAGECPP__)
798 ioctl(connection
->m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
800 ioctl(connection
->m_fd
, FIONBIO
, &arg
);
803 connection
->Notify(true);
808 void GSocket::Notify(bool flag
)
810 if (flag
== m_use_events
)
816 void GSocket::EnableEvents(bool flag
)
819 GSocketManager::Get()->Enable_Events(this);
821 GSocketManager::Get()->Disable_Events(this);
824 bool GSocket::SetReusable()
826 /* socket must not be null, and must not be in use/already bound */
827 if (this && m_fd
== INVALID_SOCKET
)
837 bool GSocket::SetBroadcast()
839 /* socket must not be in use/already bound */
840 if (m_fd
== INVALID_SOCKET
) {
847 bool GSocket::DontDoBind()
849 /* socket must not be in use/already bound */
850 if (m_fd
== INVALID_SOCKET
) {
857 /* Client specific parts */
860 * For stream (connection oriented) sockets, GSocket_Connect() tries
861 * to establish a client connection to a server using the peer address
862 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
863 * connection has been successfully established, or one of the error
864 * codes listed below. Note that for nonblocking sockets, a return
865 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
866 * request can be completed later; you should use GSocket_Select()
867 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
868 * corresponding asynchronous events.
870 * For datagram (non connection oriented) sockets, GSocket_Connect()
871 * just sets the peer address established with GSocket_SetPeer() as
872 * default destination.
875 * GSOCK_INVSOCK - the socket is in use or not valid.
876 * GSOCK_INVADDR - the peer address has not been established.
877 * GSOCK_TIMEDOUT - timeout, the connection failed.
878 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
879 * GSOCK_MEMERR - couldn't allocate memory.
880 * GSOCK_IOERR - low-level error.
882 GSocketError
GSocket::Connect(GSocketStream stream
)
889 /* Enable CONNECTION events (needed for nonblocking connections) */
890 Enable(GSOCK_CONNECTION
);
892 if (m_fd
!= INVALID_SOCKET
)
894 m_error
= GSOCK_INVSOCK
;
895 return GSOCK_INVSOCK
;
900 m_error
= GSOCK_INVADDR
;
901 return GSOCK_INVADDR
;
904 /* Streamed or dgram socket? */
905 m_stream
= (stream
== GSOCK_STREAMED
);
907 m_establishing
= false;
909 /* Create the socket */
910 m_fd
= socket(m_peer
->m_realfamily
,
911 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
913 if (m_fd
== INVALID_SOCKET
)
915 m_error
= GSOCK_IOERR
;
919 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
921 setsockopt(m_fd
, SOL_SOCKET
, SO_NOSIGPIPE
, (const char*)&arg
, sizeof(arg
));
924 #if defined(__EMX__) || defined(__VISAGECPP__)
925 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
927 ioctl(m_fd
, FIONBIO
, &arg
);
930 // If the reuse flag is set, use the applicable socket reuse flags(s)
933 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
935 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
939 if (m_initialRecvBufferSize
>= 0)
940 setsockopt(m_fd
, SOL_SOCKET
, SO_RCVBUF
, (const char*)&m_initialRecvBufferSize
, sizeof(m_initialRecvBufferSize
));
941 if (m_initialSendBufferSize
>= 0)
942 setsockopt(m_fd
, SOL_SOCKET
, SO_SNDBUF
, (const char*)&m_initialSendBufferSize
, sizeof(m_initialSendBufferSize
));
944 // If a local address has been set, then we need to bind to it before calling connect
945 if (m_local
&& m_local
->m_addr
)
947 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
950 /* Connect it to the peer address, with a timeout (see below) */
951 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
953 /* We only call Enable_Events if we know we aren't shutting down the socket.
954 * NB: Enable_Events needs to be called whether the socket is blocking or
955 * non-blocking, it just shouldn't be called prior to knowing there is a
956 * connection _if_ blocking sockets are being used.
957 * If connect above returns 0, we are already connected and need to make the
958 * call to Enable_Events now.
961 if (m_use_events
&& (m_non_blocking
|| ret
== 0))
968 /* If connect failed with EINPROGRESS and the GSocket object
969 * is in blocking mode, we select() for the specified timeout
970 * checking for writability to see if the connection request
973 if ((err
== EINPROGRESS
) && (!m_non_blocking
))
975 if (Output_Timeout() == GSOCK_TIMEDOUT
)
978 /* m_error is set in _GSocket_Output_Timeout */
979 return GSOCK_TIMEDOUT
;
984 SOCKOPTLEN_T len
= sizeof(error
);
986 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*) &error
, &len
);
991 return GSOCK_NOERROR
;
995 /* If connect failed with EINPROGRESS and the GSocket object
996 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
997 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
998 * this way if the connection completes, a GSOCK_CONNECTION
999 * event will be generated, if enabled.
1001 if ((err
== EINPROGRESS
) && (m_non_blocking
))
1003 m_establishing
= true;
1004 m_error
= GSOCK_WOULDBLOCK
;
1005 return GSOCK_WOULDBLOCK
;
1008 /* If connect failed with an error other than EINPROGRESS,
1009 * then the call to GSocket_Connect has failed.
1012 m_error
= GSOCK_IOERR
;
1017 return GSOCK_NOERROR
;
1020 /* Datagram sockets */
1022 /* GSocket_SetNonOriented:
1023 * Sets up this socket as a non-connection oriented (datagram) socket.
1024 * Before using this function, the local address must have been set
1025 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
1026 * on success, or one of the following otherwise.
1029 * GSOCK_INVSOCK - the socket is in use.
1030 * GSOCK_INVADDR - the local address has not been set.
1031 * GSOCK_IOERR - low-level error.
1033 GSocketError
GSocket::SetNonOriented()
1039 if (m_fd
!= INVALID_SOCKET
)
1041 m_error
= GSOCK_INVSOCK
;
1042 return GSOCK_INVSOCK
;
1047 m_error
= GSOCK_INVADDR
;
1048 return GSOCK_INVADDR
;
1051 /* Initialize all fields */
1055 /* Create the socket */
1056 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
1058 if (m_fd
== INVALID_SOCKET
)
1060 m_error
= GSOCK_IOERR
;
1063 #if defined(__EMX__) || defined(__VISAGECPP__)
1064 ioctl(m_fd
, FIONBIO
, (char*)&arg
, sizeof(arg
));
1066 ioctl(m_fd
, FIONBIO
, &arg
);
1073 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
1075 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEPORT
, (const char*)&arg
, sizeof(arg
));
1081 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
1085 /* Bind to the local address,
1086 * and retrieve the actual address bound.
1088 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
1091 (WX_SOCKLEN_T
*) &m_local
->m_len
) != 0))
1094 m_error
= GSOCK_IOERR
;
1098 return GSOCK_NOERROR
;
1103 /* Like recv(), send(), ... */
1104 int GSocket::Read(char *buffer
, int size
)
1110 if (m_fd
== INVALID_SOCKET
|| m_server
)
1112 m_error
= GSOCK_INVSOCK
;
1116 /* Disable events during query of socket status */
1117 Disable(GSOCK_INPUT
);
1119 /* If the socket is blocking, wait for data (with a timeout) */
1120 if (Input_Timeout() == GSOCK_TIMEDOUT
) {
1121 m_error
= GSOCK_TIMEDOUT
;
1122 /* Don't return here immediately, otherwise socket events would not be
1130 ret
= Recv_Stream(buffer
, size
);
1132 ret
= Recv_Dgram(buffer
, size
);
1135 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1136 * socket and empty datagrams are possible), then the connection has been
1137 * gracefully closed.
1139 * Otherwise, recv has returned an error (-1), in which case we have lost
1140 * the socket only if errno does _not_ indicate that there may be more data
1143 if ((ret
== 0) && m_stream
)
1145 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1148 m_detected
= GSOCK_LOST_FLAG
;
1155 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1156 m_error
= GSOCK_WOULDBLOCK
;
1158 m_error
= GSOCK_IOERR
;
1162 /* Enable events again now that we are done processing */
1163 Enable(GSOCK_INPUT
);
1168 int GSocket::Write(const char *buffer
, int size
)
1174 GSocket_Debug(( "GSocket_Write #1, size %d\n", size
));
1176 if (m_fd
== INVALID_SOCKET
|| m_server
)
1178 m_error
= GSOCK_INVSOCK
;
1182 GSocket_Debug(( "GSocket_Write #2, size %d\n", size
));
1184 /* If the socket is blocking, wait for writability (with a timeout) */
1185 if (Output_Timeout() == GSOCK_TIMEDOUT
)
1188 GSocket_Debug(( "GSocket_Write #3, size %d\n", size
));
1190 /* Write the data */
1192 ret
= Send_Stream(buffer
, size
);
1194 ret
= Send_Dgram(buffer
, size
);
1196 GSocket_Debug(( "GSocket_Write #4, size %d\n", size
));
1200 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
))
1202 m_error
= GSOCK_WOULDBLOCK
;
1203 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1207 m_error
= GSOCK_IOERR
;
1208 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1211 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1212 * in MSW). Once the first OUTPUT event is received, users can assume
1213 * that the socket is writable until a read operation fails. Only then
1214 * will further OUTPUT events be posted.
1216 Enable(GSOCK_OUTPUT
);
1221 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size
, ret
));
1228 /* GSocket_SetNonBlocking:
1229 * Sets the socket to non-blocking mode. All IO calls will return
1232 void GSocket::SetNonBlocking(bool non_block
)
1236 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block
) );
1238 m_non_blocking
= non_block
;
1241 /* GSocket_SetTimeout:
1242 * Sets the timeout for blocking calls. Time is expressed in
1245 void GSocket::SetTimeout(unsigned long millisec
)
1249 m_timeout
= millisec
;
1252 /* GSocket_GetError:
1253 * Returns the last error occurred for this socket. Note that successful
1254 * operations do not clear this back to GSOCK_NOERROR, so use it only
1257 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
1267 * There is data to be read in the input buffer. If, after a read
1268 * operation, there is still data available, the callback function will
1271 * The socket is available for writing. That is, the next write call
1272 * won't block. This event is generated only once, when the connection is
1273 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1274 * when the output buffer empties again. This means that the app should
1275 * assume that it can write since the first OUTPUT event, and no more
1276 * OUTPUT events will be generated unless an error occurs.
1278 * Connection successfully established, for client sockets, or incoming
1279 * client connection, for server sockets. Wait for this event (also watch
1280 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1282 * The connection is lost (or a connection request failed); this could
1283 * be due to a failure, or due to the peer closing it gracefully.
1286 /* GSocket_SetCallback:
1287 * Enables the callbacks specified by 'flags'. Note that 'flags'
1288 * may be a combination of flags OR'ed toghether, so the same
1289 * callback function can be made to accept different events.
1290 * The callback function must have the following prototype:
1292 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1294 void GSocket::SetCallback(GSocketEventFlags flags
,
1295 GSocketCallback callback
, char *cdata
)
1301 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1303 if ((flags
& (1 << count
)) != 0)
1305 m_cbacks
[count
] = callback
;
1306 m_data
[count
] = cdata
;
1311 /* GSocket_UnsetCallback:
1312 * Disables all callbacks specified by 'flags', which may be a
1313 * combination of flags OR'ed toghether.
1315 void GSocket::UnsetCallback(GSocketEventFlags flags
)
1321 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1323 if ((flags
& (1 << count
)) != 0)
1325 m_cbacks
[count
] = NULL
;
1326 m_data
[count
] = NULL
;
1331 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1332 void *optval
, int *optlen
)
1334 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, (SOCKOPTLEN_T
*)optlen
) == 0)
1335 return GSOCK_NOERROR
;
1337 return GSOCK_OPTERR
;
1340 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1341 const void *optval
, int optlen
)
1343 if (setsockopt(m_fd
, level
, optname
, (const char*)optval
, optlen
) == 0)
1344 return GSOCK_NOERROR
;
1346 return GSOCK_OPTERR
;
1349 #define CALL_CALLBACK(socket, event) { \
1350 socket->Disable(event); \
1351 if (socket->m_cbacks[event]) \
1352 socket->m_cbacks[event](socket, event, socket->m_data[event]); \
1356 void GSocket::Enable(GSocketEvent event
)
1360 m_detected
&= ~(1 << event
);
1361 GSocketManager::Get()->Install_Callback(this, event
);
1365 void GSocket::Disable(GSocketEvent event
)
1369 m_detected
|= (1 << event
);
1370 GSocketManager::Get()->Uninstall_Callback(this, event
);
1374 /* _GSocket_Input_Timeout:
1375 * For blocking sockets, wait until data is available or
1376 * until timeout ellapses.
1378 GSocketError
GSocket::Input_Timeout()
1384 /* Linux select() will overwrite the struct on return */
1385 tv
.tv_sec
= (m_timeout
/ 1000);
1386 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1388 if (!m_non_blocking
)
1390 wxFD_ZERO(&readfds
);
1391 wxFD_SET(m_fd
, &readfds
);
1392 ret
= select(m_fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1395 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1396 m_error
= GSOCK_TIMEDOUT
;
1397 return GSOCK_TIMEDOUT
;
1402 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1403 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1404 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1405 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1406 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1407 m_error
= GSOCK_TIMEDOUT
;
1408 return GSOCK_TIMEDOUT
;
1412 return GSOCK_NOERROR
;
1415 /* _GSocket_Output_Timeout:
1416 * For blocking sockets, wait until data can be sent without
1417 * blocking or until timeout ellapses.
1419 GSocketError
GSocket::Output_Timeout()
1425 /* Linux select() will overwrite the struct on return */
1426 tv
.tv_sec
= (m_timeout
/ 1000);
1427 tv
.tv_usec
= (m_timeout
% 1000) * 1000;
1429 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking
) );
1431 if (!m_non_blocking
)
1433 wxFD_ZERO(&writefds
);
1434 wxFD_SET(m_fd
, &writefds
);
1435 ret
= select(m_fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
1438 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1439 m_error
= GSOCK_TIMEDOUT
;
1440 return GSOCK_TIMEDOUT
;
1445 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1446 if (errno
== EBADF
) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1447 if (errno
== EINTR
) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1448 if (errno
== EINVAL
) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1449 if (errno
== ENOMEM
) { GSocket_Debug(( "Not enough memory\n" )); }
1450 m_error
= GSOCK_TIMEDOUT
;
1451 return GSOCK_TIMEDOUT
;
1454 if ( ! wxFD_ISSET(m_fd
, &writefds
) )
1456 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1460 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1465 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1468 return GSOCK_NOERROR
;
1471 int GSocket::Recv_Stream(char *buffer
, int size
)
1476 ret
= recv(m_fd
, buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1478 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1483 int GSocket::Recv_Dgram(char *buffer
, int size
)
1486 WX_SOCKLEN_T fromlen
= sizeof(from
);
1490 fromlen
= sizeof(from
);
1494 ret
= recvfrom(m_fd
, buffer
, size
, 0, (sockaddr
*)&from
, (WX_SOCKLEN_T
*) &fromlen
);
1496 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1501 /* Translate a system address into a GSocket address */
1504 m_peer
= GAddress_new();
1507 m_error
= GSOCK_MEMERR
;
1512 err
= _GAddress_translate_from(m_peer
, (sockaddr
*)&from
, fromlen
);
1513 if (err
!= GSOCK_NOERROR
)
1515 GAddress_destroy(m_peer
);
1524 int GSocket::Send_Stream(const char *buffer
, int size
)
1532 ret
= send(m_fd
, (char *)buffer
, size
, GSOCKET_MSG_NOSIGNAL
);
1534 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1541 int GSocket::Send_Dgram(const char *buffer
, int size
)
1543 struct sockaddr
*addr
;
1549 m_error
= GSOCK_INVADDR
;
1553 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1554 if (err
!= GSOCK_NOERROR
)
1564 ret
= sendto(m_fd
, (char *)buffer
, size
, 0, addr
, len
);
1566 while (ret
== -1 && errno
== EINTR
); /* Loop until not interrupted */
1570 /* Frees memory allocated from _GAddress_translate_to */
1576 void GSocket::Detected_Read()
1580 /* Safeguard against straggling call to Detected_Read */
1581 if (m_fd
== INVALID_SOCKET
)
1586 /* If we have already detected a LOST event, then don't try
1587 * to do any further processing.
1589 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1591 m_establishing
= false;
1593 CALL_CALLBACK(this, GSOCK_LOST
);
1598 int num
= recv(m_fd
, &c
, 1, MSG_PEEK
| GSOCKET_MSG_NOSIGNAL
);
1602 CALL_CALLBACK(this, GSOCK_INPUT
);
1606 if (m_server
&& m_stream
)
1608 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1614 /* graceful shutdown */
1615 CALL_CALLBACK(this, GSOCK_LOST
);
1620 /* Empty datagram received */
1621 CALL_CALLBACK(this, GSOCK_INPUT
);
1626 /* Do not throw a lost event in cases where the socket isn't really lost */
1627 if ((errno
== EWOULDBLOCK
) || (errno
== EAGAIN
) || (errno
== EINTR
))
1629 CALL_CALLBACK(this, GSOCK_INPUT
);
1633 CALL_CALLBACK(this, GSOCK_LOST
);
1640 void GSocket::Detected_Write()
1642 /* If we have already detected a LOST event, then don't try
1643 * to do any further processing.
1645 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
1647 m_establishing
= false;
1649 CALL_CALLBACK(this, GSOCK_LOST
);
1654 if (m_establishing
&& !m_server
)
1657 SOCKOPTLEN_T len
= sizeof(error
);
1659 m_establishing
= false;
1661 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1665 CALL_CALLBACK(this, GSOCK_LOST
);
1670 CALL_CALLBACK(this, GSOCK_CONNECTION
);
1671 /* We have to fire this event by hand because CONNECTION (for clients)
1672 * and OUTPUT are internally the same and we just disabled CONNECTION
1673 * events with the above macro.
1675 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1680 CALL_CALLBACK(this, GSOCK_OUTPUT
);
1685 * -------------------------------------------------------------------------
1687 * -------------------------------------------------------------------------
1690 /* CHECK_ADDRESS verifies that the current address family is either
1691 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1692 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1693 * an appropiate error code.
1695 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1697 #define CHECK_ADDRESS(address, family) \
1699 if (address->m_family == GSOCK_NOFAMILY) \
1700 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1701 return address->m_error; \
1702 if (address->m_family != GSOCK_##family) \
1704 address->m_error = GSOCK_INVADDR; \
1705 return GSOCK_INVADDR; \
1709 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1711 if (address->m_family == GSOCK_NOFAMILY) \
1712 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1714 if (address->m_family != GSOCK_##family) \
1716 address->m_error = GSOCK_INVADDR; \
1722 GAddress
*GAddress_new(void)
1726 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1729 address
->m_family
= GSOCK_NOFAMILY
;
1730 address
->m_addr
= NULL
;
1736 GAddress
*GAddress_copy(GAddress
*address
)
1740 assert(address
!= NULL
);
1742 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1745 memcpy(addr2
, address
, sizeof(GAddress
));
1747 if (address
->m_addr
&& address
->m_len
> 0)
1749 addr2
->m_addr
= (struct sockaddr
*)malloc(addr2
->m_len
);
1750 if (addr2
->m_addr
== NULL
)
1755 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1761 void GAddress_destroy(GAddress
*address
)
1763 assert(address
!= NULL
);
1765 if (address
->m_addr
)
1766 free(address
->m_addr
);
1771 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1773 assert(address
!= NULL
);
1775 address
->m_family
= type
;
1778 GAddressType
GAddress_GetFamily(GAddress
*address
)
1780 assert(address
!= NULL
);
1782 return address
->m_family
;
1785 GSocketError
_GAddress_translate_from(GAddress
*address
,
1786 struct sockaddr
*addr
, int len
)
1788 address
->m_realfamily
= addr
->sa_family
;
1789 switch (addr
->sa_family
)
1792 address
->m_family
= GSOCK_INET
;
1795 address
->m_family
= GSOCK_UNIX
;
1799 address
->m_family
= GSOCK_INET6
;
1801 #endif // wxUSE_IPV6
1804 address
->m_error
= GSOCK_INVOP
;
1809 if (address
->m_addr
)
1810 free(address
->m_addr
);
1812 address
->m_len
= len
;
1813 address
->m_addr
= (struct sockaddr
*)malloc(len
);
1815 if (address
->m_addr
== NULL
)
1817 address
->m_error
= GSOCK_MEMERR
;
1818 return GSOCK_MEMERR
;
1821 memcpy(address
->m_addr
, addr
, len
);
1823 return GSOCK_NOERROR
;
1826 GSocketError
_GAddress_translate_to(GAddress
*address
,
1827 struct sockaddr
**addr
, int *len
)
1829 if (!address
->m_addr
)
1831 address
->m_error
= GSOCK_INVADDR
;
1832 return GSOCK_INVADDR
;
1835 *len
= address
->m_len
;
1836 *addr
= (struct sockaddr
*)malloc(address
->m_len
);
1839 address
->m_error
= GSOCK_MEMERR
;
1840 return GSOCK_MEMERR
;
1843 memcpy(*addr
, address
->m_addr
, address
->m_len
);
1844 return GSOCK_NOERROR
;
1848 * -------------------------------------------------------------------------
1849 * Internet address family
1850 * -------------------------------------------------------------------------
1853 GSocketError
_GAddress_Init_INET(GAddress
*address
)
1855 address
->m_len
= sizeof(struct sockaddr_in
);
1856 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1857 if (address
->m_addr
== NULL
)
1859 address
->m_error
= GSOCK_MEMERR
;
1860 return GSOCK_MEMERR
;
1863 address
->m_family
= GSOCK_INET
;
1864 address
->m_realfamily
= PF_INET
;
1865 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
1866 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
1868 return GSOCK_NOERROR
;
1871 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
1874 struct in_addr
*addr
;
1876 assert(address
!= NULL
);
1878 CHECK_ADDRESS(address
, INET
);
1880 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1882 /* If it is a numeric host name, convert it now */
1883 #if defined(HAVE_INET_ATON)
1884 if (inet_aton(hostname
, addr
) == 0)
1886 #elif defined(HAVE_INET_ADDR)
1887 if ( (addr
->s_addr
= inet_addr(hostname
)) == (unsigned)-1 )
1890 /* Use gethostbyname by default */
1892 int val
= 1; /* VA doesn't like constants in conditional expressions */
1897 struct in_addr
*array_addr
;
1899 /* It is a real name, we solve it */
1901 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1902 struct hostent_data buffer
;
1907 he
= wxGethostbyname_r(hostname
, &h
, (void*)&buffer
, sizeof(buffer
), &err
);
1910 /* Reset to invalid address */
1911 addr
->s_addr
= INADDR_NONE
;
1912 address
->m_error
= GSOCK_NOHOST
;
1913 return GSOCK_NOHOST
;
1916 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
1917 addr
->s_addr
= array_addr
[0].s_addr
;
1920 return GSOCK_NOERROR
;
1924 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
1926 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
1929 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
1931 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
1934 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
1935 unsigned long hostaddr
)
1937 struct in_addr
*addr
;
1939 assert(address
!= NULL
);
1941 CHECK_ADDRESS(address
, INET
);
1943 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1944 addr
->s_addr
= htonl(hostaddr
);
1946 return GSOCK_NOERROR
;
1949 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
1950 const char *protocol
)
1953 struct sockaddr_in
*addr
;
1955 assert(address
!= NULL
);
1956 CHECK_ADDRESS(address
, INET
);
1960 address
->m_error
= GSOCK_INVPORT
;
1961 return GSOCK_INVPORT
;
1964 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
1965 struct servent_data buffer
;
1969 struct servent serv
;
1970 se
= wxGetservbyname_r(port
, protocol
, &serv
,
1971 (void*)&buffer
, sizeof(buffer
));
1974 /* the cast to int suppresses compiler warnings about subscript having the
1976 if (isdigit((int)port
[0]))
1980 port_int
= atoi(port
);
1981 addr
= (struct sockaddr_in
*)address
->m_addr
;
1982 addr
->sin_port
= htons(port_int
);
1983 return GSOCK_NOERROR
;
1986 address
->m_error
= GSOCK_INVPORT
;
1987 return GSOCK_INVPORT
;
1990 addr
= (struct sockaddr_in
*)address
->m_addr
;
1991 addr
->sin_port
= se
->s_port
;
1993 return GSOCK_NOERROR
;
1996 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
1998 struct sockaddr_in
*addr
;
2000 assert(address
!= NULL
);
2001 CHECK_ADDRESS(address
, INET
);
2003 addr
= (struct sockaddr_in
*)address
->m_addr
;
2004 addr
->sin_port
= htons(port
);
2006 return GSOCK_NOERROR
;
2009 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2013 struct sockaddr_in
*addr
;
2015 assert(address
!= NULL
);
2016 CHECK_ADDRESS(address
, INET
);
2018 addr
= (struct sockaddr_in
*)address
->m_addr
;
2019 addr_buf
= (char *)&(addr
->sin_addr
);
2021 struct hostent temphost
;
2022 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
2023 struct hostent_data buffer
;
2028 he
= wxGethostbyaddr_r(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
, &temphost
,
2029 (void*)&buffer
, sizeof(buffer
), &err
);
2032 address
->m_error
= GSOCK_NOHOST
;
2033 return GSOCK_NOHOST
;
2036 strncpy(hostname
, he
->h_name
, sbuf
);
2038 return GSOCK_NOERROR
;
2041 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
2043 struct sockaddr_in
*addr
;
2045 assert(address
!= NULL
);
2046 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2048 addr
= (struct sockaddr_in
*)address
->m_addr
;
2050 return ntohl(addr
->sin_addr
.s_addr
);
2053 unsigned short GAddress_INET_GetPort(GAddress
*address
)
2055 struct sockaddr_in
*addr
;
2057 assert(address
!= NULL
);
2058 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
2060 addr
= (struct sockaddr_in
*)address
->m_addr
;
2061 return ntohs(addr
->sin_port
);
2066 * -------------------------------------------------------------------------
2067 * Internet IPv6 address family
2068 * -------------------------------------------------------------------------
2071 GSocketError
_GAddress_Init_INET6(GAddress
*address
)
2073 struct in6_addr any_address
= IN6ADDR_ANY_INIT
;
2074 address
->m_len
= sizeof(struct sockaddr_in6
);
2075 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
2076 if (address
->m_addr
== NULL
)
2078 address
->m_error
= GSOCK_MEMERR
;
2079 return GSOCK_MEMERR
;
2081 memset(address
->m_addr
,0,address
->m_len
);
2083 address
->m_family
= GSOCK_INET6
;
2084 address
->m_realfamily
= AF_INET6
;
2085 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_family
= AF_INET6
;
2086 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= any_address
;
2088 return GSOCK_NOERROR
;
2091 GSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
)
2093 assert(address
!= NULL
);
2094 CHECK_ADDRESS(address
, INET6
);
2097 memset( & hints
, 0, sizeof( hints
) );
2098 hints
.ai_family
= AF_INET6
;
2099 addrinfo
* info
= 0;
2100 if ( getaddrinfo( hostname
, "0", & hints
, & info
) || ! info
)
2102 address
->m_error
= GSOCK_NOHOST
;
2103 return GSOCK_NOHOST
;
2106 memcpy( address
->m_addr
, info
->ai_addr
, info
->ai_addrlen
);
2107 freeaddrinfo( info
);
2108 return GSOCK_NOERROR
;
2111 GSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
)
2113 assert(address
!= NULL
);
2115 CHECK_ADDRESS(address
, INET6
);
2117 struct in6_addr addr
;
2118 memset( & addr
, 0, sizeof( addr
) );
2119 return GAddress_INET6_SetHostAddress(address
, addr
);
2121 GSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
2122 struct in6_addr hostaddr
)
2124 assert(address
!= NULL
);
2126 CHECK_ADDRESS(address
, INET6
);
2128 ((struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
= hostaddr
;
2130 return GSOCK_NOERROR
;
2133 GSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
2134 const char *protocol
)
2137 struct sockaddr_in6
*addr
;
2139 assert(address
!= NULL
);
2140 CHECK_ADDRESS(address
, INET6
);
2144 address
->m_error
= GSOCK_INVPORT
;
2145 return GSOCK_INVPORT
;
2148 se
= getservbyname(port
, protocol
);
2151 if (isdigit(port
[0]))
2155 port_int
= atoi(port
);
2156 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2157 addr
->sin6_port
= htons((u_short
) port_int
);
2158 return GSOCK_NOERROR
;
2161 address
->m_error
= GSOCK_INVPORT
;
2162 return GSOCK_INVPORT
;
2165 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2166 addr
->sin6_port
= se
->s_port
;
2168 return GSOCK_NOERROR
;
2171 GSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
)
2173 struct sockaddr_in6
*addr
;
2175 assert(address
!= NULL
);
2176 CHECK_ADDRESS(address
, INET6
);
2178 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2179 addr
->sin6_port
= htons(port
);
2181 return GSOCK_NOERROR
;
2184 GSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
2188 struct sockaddr_in6
*addr
;
2190 assert(address
!= NULL
);
2191 CHECK_ADDRESS(address
, INET6
);
2193 addr
= (struct sockaddr_in6
*)address
->m_addr
;
2194 addr_buf
= (char *)&(addr
->sin6_addr
);
2196 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin6_addr
), AF_INET6
);
2199 address
->m_error
= GSOCK_NOHOST
;
2200 return GSOCK_NOHOST
;
2203 strncpy(hostname
, he
->h_name
, sbuf
);
2205 return GSOCK_NOERROR
;
2208 GSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
)
2210 assert(address
!= NULL
);
2211 assert(hostaddr
!= NULL
);
2212 CHECK_ADDRESS_RETVAL(address
, INET6
, GSOCK_INVADDR
);
2213 *hostaddr
= ( (struct sockaddr_in6
*)address
->m_addr
)->sin6_addr
;
2214 return GSOCK_NOERROR
;
2217 unsigned short GAddress_INET6_GetPort(GAddress
*address
)
2219 assert(address
!= NULL
);
2220 CHECK_ADDRESS_RETVAL(address
, INET6
, 0);
2222 return ntohs( ((struct sockaddr_in6
*)address
->m_addr
)->sin6_port
);
2225 #endif // wxUSE_IPV6
2228 * -------------------------------------------------------------------------
2229 * Unix address family
2230 * -------------------------------------------------------------------------
2233 #ifndef __VISAGECPP__
2234 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
2236 address
->m_len
= sizeof(struct sockaddr_un
);
2237 address
->m_addr
= (struct sockaddr
*)malloc(address
->m_len
);
2238 if (address
->m_addr
== NULL
)
2240 address
->m_error
= GSOCK_MEMERR
;
2241 return GSOCK_MEMERR
;
2244 address
->m_family
= GSOCK_UNIX
;
2245 address
->m_realfamily
= PF_UNIX
;
2246 ((struct sockaddr_un
*)address
->m_addr
)->sun_family
= AF_UNIX
;
2247 ((struct sockaddr_un
*)address
->m_addr
)->sun_path
[0] = 0;
2249 return GSOCK_NOERROR
;
2252 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2254 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
2256 struct sockaddr_un
*addr
;
2258 assert(address
!= NULL
);
2260 CHECK_ADDRESS(address
, UNIX
);
2262 addr
= ((struct sockaddr_un
*)address
->m_addr
);
2263 strncpy(addr
->sun_path
, path
, UNIX_SOCK_PATHLEN
);
2264 addr
->sun_path
[UNIX_SOCK_PATHLEN
- 1] = '\0';
2266 return GSOCK_NOERROR
;
2269 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
2271 struct sockaddr_un
*addr
;
2273 assert(address
!= NULL
);
2274 CHECK_ADDRESS(address
, UNIX
);
2276 addr
= (struct sockaddr_un
*)address
->m_addr
;
2278 strncpy(path
, addr
->sun_path
, sbuf
);
2280 return GSOCK_NOERROR
;
2282 #endif /* !defined(__VISAGECPP__) */
2283 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */