1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket)
3 * Name: src/msw/gsocket.cpp
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Author: Guillermo Rodriguez Garcia <guille@iies.es>
7 * Purpose: GSocket main MSW file
8 * Licence: The wxWindows licence
10 * -------------------------------------------------------------------------
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
21 /* RPCNOTIFICATION_ROUTINE in rasasync.h (included from winsock.h),
22 * warning: conditional expression is constant.
24 # pragma warning(disable:4115)
26 * warning: named type definition in parentheses.
28 # pragma warning(disable:4127)
29 /* GAddress_UNIX_GetPath,
30 * warning: unreferenced formal parameter.
32 # pragma warning(disable:4100)
35 /* windows.h results in tons of warnings at max warning level */
37 # pragma warning(push, 1)
42 # pragma warning(disable:4514)
48 #if defined(__CYGWIN__)
49 //CYGWIN gives annoying warning about runtime stuff if we don't do this
50 # define USE_SYS_TYPES_FD_SET
51 # include <sys/types.h>
56 #ifndef __GSOCKET_STANDALONE__
57 # include "wx/platform.h"
60 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
62 #ifndef __GSOCKET_STANDALONE__
63 # include "wx/msw/gsockmsw.h"
64 # include "wx/gsocket.h"
66 # include "gsockmsw.h"
68 #endif /* __GSOCKET_STANDALONE__ */
75 #define isdigit(x) (x > 47 && x < 58)
77 #include "wx/msw/wince/net.h"
86 /* if we use configure for MSW WX_SOCKLEN_T will be already defined */
88 # define WX_SOCKLEN_T int
91 /* Table of GUI-related functions. We must call them indirectly because
92 * of wxBase and GUI separation: */
94 static GSocketGUIFunctionsTable
*gs_gui_functions
;
96 class GSocketGUIFunctionsTableNull
: public GSocketGUIFunctionsTable
99 virtual bool OnInit();
100 virtual void OnExit();
101 virtual bool CanUseEventLoop();
102 virtual bool Init_Socket(GSocket
*socket
);
103 virtual void Destroy_Socket(GSocket
*socket
);
104 virtual void Enable_Events(GSocket
*socket
);
105 virtual void Disable_Events(GSocket
*socket
);
108 bool GSocketGUIFunctionsTableNull::OnInit()
110 void GSocketGUIFunctionsTableNull::OnExit()
112 bool GSocketGUIFunctionsTableNull::CanUseEventLoop()
114 bool GSocketGUIFunctionsTableNull::Init_Socket(GSocket
*WXUNUSED(socket
))
116 void GSocketGUIFunctionsTableNull::Destroy_Socket(GSocket
*WXUNUSED(socket
))
118 void GSocketGUIFunctionsTableNull::Enable_Events(GSocket
*WXUNUSED(socket
))
120 void GSocketGUIFunctionsTableNull::Disable_Events(GSocket
*WXUNUSED(socket
))
122 /* Global initialisers */
124 void GSocket_SetGUIFunctions(GSocketGUIFunctionsTable
*guifunc
)
126 gs_gui_functions
= guifunc
;
129 int GSocket_Init(void)
133 if (!gs_gui_functions
)
135 static GSocketGUIFunctionsTableNull table
;
136 gs_gui_functions
= &table
;
138 if ( !gs_gui_functions
->OnInit() )
143 /* Initialize WinSocket */
144 return (WSAStartup((1 << 8) | 1, &wsaData
) == 0);
147 void GSocket_Cleanup(void)
149 if (gs_gui_functions
)
151 gs_gui_functions
->OnExit();
154 /* Cleanup WinSocket */
158 /* Constructors / Destructors for GSocket */
164 m_fd
= INVALID_SOCKET
;
165 for (i
= 0; i
< GSOCK_MAX_EVENT
; i
++)
172 m_error
= GSOCK_NOERROR
;
175 m_non_blocking
= false;
176 m_timeout
.tv_sec
= 10 * 60; /* 10 minutes */
177 m_timeout
.tv_usec
= 0;
178 m_establishing
= false;
183 assert(gs_gui_functions
);
184 /* Per-socket GUI-specific initialization */
185 m_ok
= gs_gui_functions
->Init_Socket(this);
188 void GSocket::Close()
190 gs_gui_functions
->Disable_Events(this);
192 m_fd
= INVALID_SOCKET
;
199 /* Per-socket GUI-specific cleanup */
200 gs_gui_functions
->Destroy_Socket(this);
202 /* Check that the socket is really shutdowned */
203 if (m_fd
!= INVALID_SOCKET
)
206 /* Destroy private addresses */
208 GAddress_destroy(m_local
);
211 GAddress_destroy(m_peer
);
215 * Disallow further read/write operations on this socket, close
216 * the fd and disable all callbacks.
218 void GSocket::Shutdown()
224 /* If socket has been created, shutdown it */
225 if (m_fd
!= INVALID_SOCKET
)
227 shutdown(m_fd
, 1 /* SD_SEND */);
231 /* Disable GUI callbacks */
232 for (evt
= 0; evt
< GSOCK_MAX_EVENT
; evt
++)
233 m_cbacks
[evt
] = NULL
;
235 m_detected
= GSOCK_LOST_FLAG
;
238 /* Address handling */
244 * Set or get the local or peer address for this socket. The 'set'
245 * functions return GSOCK_NOERROR on success, an error code otherwise.
246 * The 'get' functions return a pointer to a GAddress object on success,
247 * or NULL otherwise, in which case they set the error code of the
248 * corresponding GSocket.
251 * GSOCK_INVSOCK - the socket is not valid.
252 * GSOCK_INVADDR - the address is not valid.
254 GSocketError
GSocket::SetLocal(GAddress
*address
)
258 /* the socket must be initialized, or it must be a server */
259 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
261 m_error
= GSOCK_INVSOCK
;
262 return GSOCK_INVSOCK
;
266 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
268 m_error
= GSOCK_INVADDR
;
269 return GSOCK_INVADDR
;
273 GAddress_destroy(m_local
);
275 m_local
= GAddress_copy(address
);
277 return GSOCK_NOERROR
;
280 GSocketError
GSocket::SetPeer(GAddress
*address
)
285 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
287 m_error
= GSOCK_INVADDR
;
288 return GSOCK_INVADDR
;
292 GAddress_destroy(m_peer
);
294 m_peer
= GAddress_copy(address
);
296 return GSOCK_NOERROR
;
299 GAddress
*GSocket::GetLocal()
302 struct sockaddr addr
;
303 WX_SOCKLEN_T size
= sizeof(addr
);
308 /* try to get it from the m_local var first */
310 return GAddress_copy(m_local
);
312 /* else, if the socket is initialized, try getsockname */
313 if (m_fd
== INVALID_SOCKET
)
315 m_error
= GSOCK_INVSOCK
;
319 if (getsockname(m_fd
, &addr
, &size
) == SOCKET_ERROR
)
321 m_error
= GSOCK_IOERR
;
325 /* got a valid address from getsockname, create a GAddress object */
326 if ((address
= GAddress_new()) == NULL
)
328 m_error
= GSOCK_MEMERR
;
332 if ((err
= _GAddress_translate_from(address
, &addr
, size
)) != GSOCK_NOERROR
)
334 GAddress_destroy(address
);
342 GAddress
*GSocket::GetPeer()
346 /* try to get it from the m_peer var */
348 return GAddress_copy(m_peer
);
353 /* Server specific parts */
355 /* GSocket_SetServer:
356 * Sets up this socket as a server. The local address must have been
357 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
358 * Returns GSOCK_NOERROR on success, one of the following otherwise:
361 * GSOCK_INVSOCK - the socket is in use.
362 * GSOCK_INVADDR - the local address has not been set.
363 * GSOCK_IOERR - low-level error.
365 GSocketError
GSocket::SetServer()
371 /* must not be in use */
372 if (m_fd
!= INVALID_SOCKET
)
374 m_error
= GSOCK_INVSOCK
;
375 return GSOCK_INVSOCK
;
378 /* the local addr must have been set */
381 m_error
= GSOCK_INVADDR
;
382 return GSOCK_INVADDR
;
385 /* Initialize all fields */
389 /* Create the socket */
390 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
392 if (m_fd
== INVALID_SOCKET
)
394 m_error
= GSOCK_IOERR
;
398 ioctlsocket(m_fd
, FIONBIO
, (u_long FAR
*) &arg
);
399 gs_gui_functions
->Enable_Events(this);
401 /* allow a socket to re-bind if the socket is in the TIME_WAIT
402 state after being previously closed.
406 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
409 /* Bind to the local address,
410 * retrieve the actual address bound,
411 * and listen up to 5 connections.
413 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
416 (WX_SOCKLEN_T
*)&m_local
->m_len
) != 0) ||
417 (listen(m_fd
, 5) != 0))
420 m_error
= GSOCK_IOERR
;
424 return GSOCK_NOERROR
;
427 /* GSocket_WaitConnection:
428 * Waits for an incoming client connection. Returns a pointer to
429 * a GSocket object, or NULL if there was an error, in which case
430 * the last error field will be updated for the calling GSocket.
432 * Error codes (set in the calling GSocket)
433 * GSOCK_INVSOCK - the socket is not valid or not a server.
434 * GSOCK_TIMEDOUT - timeout, no incoming connections.
435 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
436 * GSOCK_MEMERR - couldn't allocate memory.
437 * GSOCK_IOERR - low-level error.
439 GSocket
*GSocket::WaitConnection()
442 struct sockaddr from
;
443 WX_SOCKLEN_T fromlen
= sizeof(from
);
449 /* Reenable CONNECTION events */
450 m_detected
&= ~GSOCK_CONNECTION_FLAG
;
452 /* If the socket has already been created, we exit immediately */
453 if (m_fd
== INVALID_SOCKET
|| !m_server
)
455 m_error
= GSOCK_INVSOCK
;
459 /* Create a GSocket object for the new connection */
460 connection
= GSocket_new();
464 m_error
= GSOCK_MEMERR
;
468 /* Wait for a connection (with timeout) */
469 if (Input_Timeout() == GSOCK_TIMEDOUT
)
472 /* m_error set by _GSocket_Input_Timeout */
476 connection
->m_fd
= accept(m_fd
, &from
, &fromlen
);
478 if (connection
->m_fd
== INVALID_SOCKET
)
480 if (WSAGetLastError() == WSAEWOULDBLOCK
)
481 m_error
= GSOCK_WOULDBLOCK
;
483 m_error
= GSOCK_IOERR
;
489 /* Initialize all fields */
490 connection
->m_server
= false;
491 connection
->m_stream
= true;
493 /* Setup the peer address field */
494 connection
->m_peer
= GAddress_new();
495 if (!connection
->m_peer
)
498 m_error
= GSOCK_MEMERR
;
501 err
= _GAddress_translate_from(connection
->m_peer
, &from
, fromlen
);
502 if (err
!= GSOCK_NOERROR
)
504 GAddress_destroy(connection
->m_peer
);
510 ioctlsocket(connection
->m_fd
, FIONBIO
, (u_long FAR
*) &arg
);
511 gs_gui_functions
->Enable_Events(connection
);
516 /* GSocket_SetReusable:
517 * Simply sets the m_resuable flag on the socket. GSocket_SetServer will
518 * make the appropriate setsockopt() call.
519 * Implemented as a GSocket function because clients (ie, wxSocketServer)
520 * don't have access to the GSocket struct information.
521 * Returns true if the flag was set correctly, false if an error occurred
522 * (ie, if the parameter was NULL)
524 bool GSocket::SetReusable()
526 /* socket must not be null, and must not be in use/already bound */
527 if (this && m_fd
== INVALID_SOCKET
) {
534 /* GSocket_SetBroadcast:
535 * Simply sets the m_broadcast flag on the socket. GSocket_SetServer will
536 * make the appropriate setsockopt() call.
537 * Implemented as a GSocket function because clients (ie, wxSocketServer)
538 * don't have access to the GSocket struct information.
539 * Returns true if the flag was set correctly, false if an error occurred
540 * (ie, if the parameter was NULL)
542 bool GSocket::SetBroadcast()
544 /* socket must not be in use/already bound */
545 if (m_fd
== INVALID_SOCKET
) {
552 bool GSocket::DontDoBind()
554 /* socket must not be in use/already bound */
555 if (m_fd
== INVALID_SOCKET
) {
562 /* Client specific parts */
565 * For stream (connection oriented) sockets, GSocket_Connect() tries
566 * to establish a client connection to a server using the peer address
567 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
568 * connection has been successfully established, or one of the error
569 * codes listed below. Note that for nonblocking sockets, a return
570 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
571 * request can be completed later; you should use GSocket_Select()
572 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
573 * corresponding asynchronous events.
575 * For datagram (non connection oriented) sockets, GSocket_Connect()
576 * just sets the peer address established with GSocket_SetPeer() as
577 * default destination.
580 * GSOCK_INVSOCK - the socket is in use or not valid.
581 * GSOCK_INVADDR - the peer address has not been established.
582 * GSOCK_TIMEDOUT - timeout, the connection failed.
583 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
584 * GSOCK_MEMERR - couldn't allocate memory.
585 * GSOCK_IOERR - low-level error.
587 GSocketError
GSocket::Connect(GSocketStream stream
)
594 /* Enable CONNECTION events (needed for nonblocking connections) */
595 m_detected
&= ~GSOCK_CONNECTION_FLAG
;
597 if (m_fd
!= INVALID_SOCKET
)
599 m_error
= GSOCK_INVSOCK
;
600 return GSOCK_INVSOCK
;
605 m_error
= GSOCK_INVADDR
;
606 return GSOCK_INVADDR
;
609 /* Streamed or dgram socket? */
610 m_stream
= (stream
== GSOCK_STREAMED
);
612 m_establishing
= false;
614 /* Create the socket */
615 m_fd
= socket(m_peer
->m_realfamily
,
616 m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
618 if (m_fd
== INVALID_SOCKET
)
620 m_error
= GSOCK_IOERR
;
624 ioctlsocket(m_fd
, FIONBIO
, (u_long FAR
*) &arg
);
625 gs_gui_functions
->Enable_Events(this);
627 // If the reuse flag is set, use the applicable socket reuse flag
630 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
633 // If a local address has been set, then we need to bind to it before calling connect
634 if (m_local
&& m_local
->m_addr
)
636 bind(m_fd
, m_local
->m_addr
, m_local
->m_len
);
639 /* Connect it to the peer address, with a timeout (see below) */
640 ret
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
642 if (ret
== SOCKET_ERROR
)
644 err
= WSAGetLastError();
646 /* If connect failed with EWOULDBLOCK and the GSocket object
647 * is in blocking mode, we select() for the specified timeout
648 * checking for writability to see if the connection request
651 if ((err
== WSAEWOULDBLOCK
) && (!m_non_blocking
))
653 err
= Connect_Timeout();
655 if (err
!= GSOCK_NOERROR
)
658 /* m_error is set in _GSocket_Connect_Timeout */
661 return (GSocketError
) err
;
664 /* If connect failed with EWOULDBLOCK and the GSocket object
665 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
666 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
667 * this way if the connection completes, a GSOCK_CONNECTION
668 * event will be generated, if enabled.
670 if ((err
== WSAEWOULDBLOCK
) && (m_non_blocking
))
672 m_establishing
= true;
673 m_error
= GSOCK_WOULDBLOCK
;
674 return GSOCK_WOULDBLOCK
;
677 /* If connect failed with an error other than EWOULDBLOCK,
678 * then the call to GSocket_Connect() has failed.
681 m_error
= GSOCK_IOERR
;
685 return GSOCK_NOERROR
;
688 /* Datagram sockets */
690 /* GSocket_SetNonOriented:
691 * Sets up this socket as a non-connection oriented (datagram) socket.
692 * Before using this function, the local address must have been set
693 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
694 * on success, or one of the following otherwise.
697 * GSOCK_INVSOCK - the socket is in use.
698 * GSOCK_INVADDR - the local address has not been set.
699 * GSOCK_IOERR - low-level error.
701 GSocketError
GSocket::SetNonOriented()
707 if (m_fd
!= INVALID_SOCKET
)
709 m_error
= GSOCK_INVSOCK
;
710 return GSOCK_INVSOCK
;
715 m_error
= GSOCK_INVADDR
;
716 return GSOCK_INVADDR
;
719 /* Initialize all fields */
723 /* Create the socket */
724 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
726 if (m_fd
== INVALID_SOCKET
)
728 m_error
= GSOCK_IOERR
;
732 ioctlsocket(m_fd
, FIONBIO
, (u_long FAR
*) &arg
);
733 gs_gui_functions
->Enable_Events(this);
737 setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(arg
));
741 setsockopt(m_fd
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&arg
, sizeof(arg
));
745 /* Bind to the local address,
746 * and retrieve the actual address bound.
748 if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) ||
751 (WX_SOCKLEN_T
*)&m_local
->m_len
) != 0))
754 m_error
= GSOCK_IOERR
;
759 return GSOCK_NOERROR
;
764 /* Like recv(), send(), ... */
765 int GSocket::Read(char *buffer
, int size
)
771 /* Reenable INPUT events */
772 m_detected
&= ~GSOCK_INPUT_FLAG
;
774 if (m_fd
== INVALID_SOCKET
|| m_server
)
776 m_error
= GSOCK_INVSOCK
;
780 /* If the socket is blocking, wait for data (with a timeout) */
781 if (Input_Timeout() == GSOCK_TIMEDOUT
)
783 m_error
= GSOCK_TIMEDOUT
;
789 ret
= Recv_Stream(buffer
, size
);
791 ret
= Recv_Dgram(buffer
, size
);
793 if (ret
== SOCKET_ERROR
)
795 if (WSAGetLastError() != WSAEWOULDBLOCK
)
796 m_error
= GSOCK_IOERR
;
798 m_error
= GSOCK_WOULDBLOCK
;
805 int GSocket::Write(const char *buffer
, int size
)
811 if (m_fd
== INVALID_SOCKET
|| m_server
)
813 m_error
= GSOCK_INVSOCK
;
817 /* If the socket is blocking, wait for writability (with a timeout) */
818 if (Output_Timeout() == GSOCK_TIMEDOUT
)
823 ret
= Send_Stream(buffer
, size
);
825 ret
= Send_Dgram(buffer
, size
);
827 if (ret
== SOCKET_ERROR
)
829 if (WSAGetLastError() != WSAEWOULDBLOCK
)
830 m_error
= GSOCK_IOERR
;
832 m_error
= GSOCK_WOULDBLOCK
;
834 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
835 * does). Once the first OUTPUT event is received, users can assume
836 * that the socket is writable until a read operation fails. Only then
837 * will further OUTPUT events be posted.
839 m_detected
&= ~GSOCK_OUTPUT_FLAG
;
847 * Polls the socket to determine its status. This function will
848 * check for the events specified in the 'flags' parameter, and
849 * it will return a mask indicating which operations can be
850 * performed. This function won't block, regardless of the
851 * mode (blocking | nonblocking) of the socket.
853 GSocketEventFlags
GSocket::Select(GSocketEventFlags flags
)
855 if (!gs_gui_functions
->CanUseEventLoop())
857 GSocketEventFlags result
= 0;
867 FD_SET(m_fd
, &readfds
);
868 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
869 FD_SET(m_fd
, &writefds
);
870 FD_SET(m_fd
, &exceptfds
);
872 /* Check 'sticky' CONNECTION flag first */
873 result
|= (GSOCK_CONNECTION_FLAG
& m_detected
);
875 /* If we have already detected a LOST event, then don't try
876 * to do any further processing.
878 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
880 m_establishing
= false;
882 return (GSOCK_LOST_FLAG
& flags
);
886 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
,
889 /* What to do here? */
890 return (result
& flags
);
893 /* Check for exceptions and errors */
894 if (FD_ISSET(m_fd
, &exceptfds
))
896 m_establishing
= false;
897 m_detected
= GSOCK_LOST_FLAG
;
899 /* LOST event: Abort any further processing */
900 return (GSOCK_LOST_FLAG
& flags
);
903 /* Check for readability */
904 if (FD_ISSET(m_fd
, &readfds
))
906 result
|= GSOCK_INPUT_FLAG
;
908 if (m_server
&& m_stream
)
910 /* This is a TCP server socket that detected a connection.
911 While the INPUT_FLAG is also set, it doesn't matter on
912 this kind of sockets, as we can only Accept() from them. */
913 result
|= GSOCK_CONNECTION_FLAG
;
914 m_detected
|= GSOCK_CONNECTION_FLAG
;
918 /* Check for writability */
919 if (FD_ISSET(m_fd
, &writefds
))
921 if (m_establishing
&& !m_server
)
924 WX_SOCKLEN_T len
= sizeof(error
);
926 m_establishing
= false;
928 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
932 m_detected
= GSOCK_LOST_FLAG
;
934 /* LOST event: Abort any further processing */
935 return (GSOCK_LOST_FLAG
& flags
);
939 result
|= GSOCK_CONNECTION_FLAG
;
940 m_detected
|= GSOCK_CONNECTION_FLAG
;
945 result
|= GSOCK_OUTPUT_FLAG
;
949 return (result
& flags
);
954 return flags
& m_detected
;
960 /* GSocket_SetNonBlocking:
961 * Sets the socket to non-blocking mode. All IO calls will return
964 void GSocket::SetNonBlocking(bool non_block
)
968 m_non_blocking
= non_block
;
971 /* GSocket_SetTimeout:
972 * Sets the timeout for blocking calls. Time is expressed in
975 void GSocket::SetTimeout(unsigned long millis
)
979 m_timeout
.tv_sec
= (millis
/ 1000);
980 m_timeout
.tv_usec
= (millis
% 1000) * 1000;
984 * Returns the last error occurred for this socket. Note that successful
985 * operations do not clear this back to GSOCK_NOERROR, so use it only
988 GSocketError WXDLLIMPEXP_NET
GSocket::GetError()
998 * There is data to be read in the input buffer. If, after a read
999 * operation, there is still data available, the callback function will
1002 * The socket is available for writing. That is, the next write call
1003 * won't block. This event is generated only once, when the connection is
1004 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1005 * when the output buffer empties again. This means that the app should
1006 * assume that it can write since the first OUTPUT event, and no more
1007 * OUTPUT events will be generated unless an error occurs.
1009 * Connection successfully established, for client sockets, or incoming
1010 * client connection, for server sockets. Wait for this event (also watch
1011 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1013 * The connection is lost (or a connection request failed); this could
1014 * be due to a failure, or due to the peer closing it gracefully.
1017 /* GSocket_SetCallback:
1018 * Enables the callbacks specified by 'flags'. Note that 'flags'
1019 * may be a combination of flags OR'ed toghether, so the same
1020 * callback function can be made to accept different events.
1021 * The callback function must have the following prototype:
1023 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1025 void GSocket::SetCallback(GSocketEventFlags flags
,
1026 GSocketCallback callback
, char *cdata
)
1032 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1034 if ((flags
& (1 << count
)) != 0)
1036 m_cbacks
[count
] = callback
;
1037 m_data
[count
] = cdata
;
1042 /* GSocket_UnsetCallback:
1043 * Disables all callbacks specified by 'flags', which may be a
1044 * combination of flags OR'ed toghether.
1046 void GSocket::UnsetCallback(GSocketEventFlags flags
)
1052 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
1054 if ((flags
& (1 << count
)) != 0)
1056 m_cbacks
[count
] = NULL
;
1057 m_data
[count
] = NULL
;
1062 GSocketError
GSocket::GetSockOpt(int level
, int optname
,
1063 void *optval
, int *optlen
)
1065 if (getsockopt(m_fd
, level
, optname
, (char*)optval
, optlen
) == 0)
1067 return GSOCK_NOERROR
;
1069 return GSOCK_OPTERR
;
1072 GSocketError
GSocket::SetSockOpt(int level
, int optname
,
1073 const void *optval
, int optlen
)
1075 if (setsockopt(m_fd
, level
, optname
, (char*)optval
, optlen
) == 0)
1077 return GSOCK_NOERROR
;
1079 return GSOCK_OPTERR
;
1082 /* Internals (IO) */
1084 /* _GSocket_Input_Timeout:
1085 * For blocking sockets, wait until data is available or
1086 * until timeout ellapses.
1088 GSocketError
GSocket::Input_Timeout()
1092 if (!m_non_blocking
)
1095 FD_SET(m_fd
, &readfds
);
1096 if (select(0, &readfds
, NULL
, NULL
, &m_timeout
) == 0)
1098 m_error
= GSOCK_TIMEDOUT
;
1099 return GSOCK_TIMEDOUT
;
1102 return GSOCK_NOERROR
;
1105 /* _GSocket_Output_Timeout:
1106 * For blocking sockets, wait until data can be sent without
1107 * blocking or until timeout ellapses.
1109 GSocketError
GSocket::Output_Timeout()
1113 if (!m_non_blocking
)
1116 FD_SET(m_fd
, &writefds
);
1117 if (select(0, NULL
, &writefds
, NULL
, &m_timeout
) == 0)
1119 m_error
= GSOCK_TIMEDOUT
;
1120 return GSOCK_TIMEDOUT
;
1123 return GSOCK_NOERROR
;
1126 /* _GSocket_Connect_Timeout:
1127 * For blocking sockets, wait until the connection is
1128 * established or fails, or until timeout ellapses.
1130 GSocketError
GSocket::Connect_Timeout()
1136 FD_ZERO(&exceptfds
);
1137 FD_SET(m_fd
, &writefds
);
1138 FD_SET(m_fd
, &exceptfds
);
1139 if (select(0, NULL
, &writefds
, &exceptfds
, &m_timeout
) == 0)
1141 m_error
= GSOCK_TIMEDOUT
;
1142 return GSOCK_TIMEDOUT
;
1144 if (!FD_ISSET(m_fd
, &writefds
))
1146 m_error
= GSOCK_IOERR
;
1150 return GSOCK_NOERROR
;
1153 int GSocket::Recv_Stream(char *buffer
, int size
)
1155 return recv(m_fd
, buffer
, size
, 0);
1158 int GSocket::Recv_Dgram(char *buffer
, int size
)
1160 struct sockaddr from
;
1161 WX_SOCKLEN_T fromlen
= sizeof(from
);
1165 ret
= recvfrom(m_fd
, buffer
, size
, 0, &from
, &fromlen
);
1167 if (ret
== SOCKET_ERROR
)
1168 return SOCKET_ERROR
;
1170 /* Translate a system address into a GSocket address */
1173 m_peer
= GAddress_new();
1176 m_error
= GSOCK_MEMERR
;
1180 err
= _GAddress_translate_from(m_peer
, &from
, fromlen
);
1181 if (err
!= GSOCK_NOERROR
)
1183 GAddress_destroy(m_peer
);
1192 int GSocket::Send_Stream(const char *buffer
, int size
)
1194 return send(m_fd
, buffer
, size
, 0);
1197 int GSocket::Send_Dgram(const char *buffer
, int size
)
1199 struct sockaddr
*addr
;
1205 m_error
= GSOCK_INVADDR
;
1209 err
= _GAddress_translate_to(m_peer
, &addr
, &len
);
1210 if (err
!= GSOCK_NOERROR
)
1216 ret
= sendto(m_fd
, buffer
, size
, 0, addr
, len
);
1218 /* Frees memory allocated by _GAddress_translate_to */
1224 /* Compatibility functions for GSocket */
1225 GSocket
*GSocket_new(void)
1227 GSocket
*newsocket
= new GSocket();
1228 if(newsocket
->IsOk())
1236 * -------------------------------------------------------------------------
1238 * -------------------------------------------------------------------------
1241 /* CHECK_ADDRESS verifies that the current address family is either
1242 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1243 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1244 * an appropiate error code.
1246 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1248 #define CHECK_ADDRESS(address, family) \
1250 if (address->m_family == GSOCK_NOFAMILY) \
1251 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1252 return address->m_error; \
1253 if (address->m_family != GSOCK_##family) \
1255 address->m_error = GSOCK_INVADDR; \
1256 return GSOCK_INVADDR; \
1260 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1262 if (address->m_family == GSOCK_NOFAMILY) \
1263 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1265 if (address->m_family != GSOCK_##family) \
1267 address->m_error = GSOCK_INVADDR; \
1273 GAddress
*GAddress_new(void)
1277 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1280 address
->m_family
= GSOCK_NOFAMILY
;
1281 address
->m_addr
= NULL
;
1287 GAddress
*GAddress_copy(GAddress
*address
)
1291 assert(address
!= NULL
);
1293 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1296 memcpy(addr2
, address
, sizeof(GAddress
));
1298 if (address
->m_addr
)
1300 addr2
->m_addr
= (struct sockaddr
*) malloc(addr2
->m_len
);
1301 if (addr2
->m_addr
== NULL
)
1306 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1312 void GAddress_destroy(GAddress
*address
)
1314 assert(address
!= NULL
);
1316 if (address
->m_addr
)
1317 free(address
->m_addr
);
1322 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1324 assert(address
!= NULL
);
1326 address
->m_family
= type
;
1329 GAddressType
GAddress_GetFamily(GAddress
*address
)
1331 assert(address
!= NULL
);
1333 return address
->m_family
;
1336 GSocketError
_GAddress_translate_from(GAddress
*address
,
1337 struct sockaddr
*addr
, int len
)
1339 address
->m_realfamily
= addr
->sa_family
;
1340 switch (addr
->sa_family
)
1343 address
->m_family
= GSOCK_INET
;
1346 address
->m_family
= GSOCK_UNIX
;
1350 address
->m_family
= GSOCK_INET6
;
1355 address
->m_error
= GSOCK_INVOP
;
1360 if (address
->m_addr
)
1361 free(address
->m_addr
);
1363 address
->m_len
= len
;
1364 address
->m_addr
= (struct sockaddr
*) malloc(len
);
1366 if (address
->m_addr
== NULL
)
1368 address
->m_error
= GSOCK_MEMERR
;
1369 return GSOCK_MEMERR
;
1371 memcpy(address
->m_addr
, addr
, len
);
1373 return GSOCK_NOERROR
;
1376 GSocketError
_GAddress_translate_to(GAddress
*address
,
1377 struct sockaddr
**addr
, int *len
)
1379 if (!address
->m_addr
)
1381 address
->m_error
= GSOCK_INVADDR
;
1382 return GSOCK_INVADDR
;
1385 *len
= address
->m_len
;
1386 *addr
= (struct sockaddr
*) malloc(address
->m_len
);
1389 address
->m_error
= GSOCK_MEMERR
;
1390 return GSOCK_MEMERR
;
1393 memcpy(*addr
, address
->m_addr
, address
->m_len
);
1394 return GSOCK_NOERROR
;
1398 * -------------------------------------------------------------------------
1399 * Internet address family
1400 * -------------------------------------------------------------------------
1403 GSocketError
_GAddress_Init_INET(GAddress
*address
)
1405 address
->m_len
= sizeof(struct sockaddr_in
);
1406 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1407 if (address
->m_addr
== NULL
)
1409 address
->m_error
= GSOCK_MEMERR
;
1410 return GSOCK_MEMERR
;
1413 address
->m_family
= GSOCK_INET
;
1414 address
->m_realfamily
= AF_INET
;
1415 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
1416 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
1418 return GSOCK_NOERROR
;
1421 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
1424 struct in_addr
*addr
;
1426 assert(address
!= NULL
);
1428 CHECK_ADDRESS(address
, INET
);
1430 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1432 addr
->s_addr
= inet_addr(hostname
);
1434 /* If it is a numeric host name, convert it now */
1435 if (addr
->s_addr
== INADDR_NONE
)
1437 struct in_addr
*array_addr
;
1439 /* It is a real name, we solve it */
1440 if ((he
= gethostbyname(hostname
)) == NULL
)
1442 /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
1443 address
->m_error
= GSOCK_NOHOST
;
1444 return GSOCK_NOHOST
;
1446 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
1447 addr
->s_addr
= array_addr
[0].s_addr
;
1449 return GSOCK_NOERROR
;
1452 GSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
)
1454 return GAddress_INET_SetHostAddress(address
, INADDR_BROADCAST
);
1457 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
1459 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
1462 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
1463 unsigned long hostaddr
)
1465 struct in_addr
*addr
;
1467 assert(address
!= NULL
);
1469 CHECK_ADDRESS(address
, INET
);
1471 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1472 addr
->s_addr
= htonl(hostaddr
);
1474 return GSOCK_NOERROR
;
1477 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
1478 const char *protocol
)
1481 struct sockaddr_in
*addr
;
1483 assert(address
!= NULL
);
1484 CHECK_ADDRESS(address
, INET
);
1488 address
->m_error
= GSOCK_INVPORT
;
1489 return GSOCK_INVPORT
;
1492 se
= getservbyname(port
, protocol
);
1495 if (isdigit(port
[0]))
1499 port_int
= atoi(port
);
1500 addr
= (struct sockaddr_in
*)address
->m_addr
;
1501 addr
->sin_port
= htons((u_short
) port_int
);
1502 return GSOCK_NOERROR
;
1505 address
->m_error
= GSOCK_INVPORT
;
1506 return GSOCK_INVPORT
;
1509 addr
= (struct sockaddr_in
*)address
->m_addr
;
1510 addr
->sin_port
= se
->s_port
;
1512 return GSOCK_NOERROR
;
1515 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
1517 struct sockaddr_in
*addr
;
1519 assert(address
!= NULL
);
1520 CHECK_ADDRESS(address
, INET
);
1522 addr
= (struct sockaddr_in
*)address
->m_addr
;
1523 addr
->sin_port
= htons(port
);
1525 return GSOCK_NOERROR
;
1528 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
1532 struct sockaddr_in
*addr
;
1534 assert(address
!= NULL
);
1535 CHECK_ADDRESS(address
, INET
);
1537 addr
= (struct sockaddr_in
*)address
->m_addr
;
1538 addr_buf
= (char *)&(addr
->sin_addr
);
1540 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
);
1543 address
->m_error
= GSOCK_NOHOST
;
1544 return GSOCK_NOHOST
;
1547 strncpy(hostname
, he
->h_name
, sbuf
);
1549 return GSOCK_NOERROR
;
1552 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
1554 struct sockaddr_in
*addr
;
1556 assert(address
!= NULL
);
1557 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1559 addr
= (struct sockaddr_in
*)address
->m_addr
;
1561 return ntohl(addr
->sin_addr
.s_addr
);
1564 unsigned short GAddress_INET_GetPort(GAddress
*address
)
1566 struct sockaddr_in
*addr
;
1568 assert(address
!= NULL
);
1569 CHECK_ADDRESS_RETVAL(address
, INET
, 0);
1571 addr
= (struct sockaddr_in
*)address
->m_addr
;
1572 return ntohs(addr
->sin_port
);
1576 * -------------------------------------------------------------------------
1577 * Unix address family
1578 * -------------------------------------------------------------------------
1581 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
1583 assert (address
!= NULL
);
1584 address
->m_error
= GSOCK_INVADDR
;
1585 return GSOCK_INVADDR
;
1588 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *WXUNUSED(path
))
1590 assert (address
!= NULL
);
1591 address
->m_error
= GSOCK_INVADDR
;
1592 return GSOCK_INVADDR
;
1595 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *WXUNUSED(path
), size_t WXUNUSED(sbuf
))
1597 assert (address
!= NULL
);
1598 address
->m_error
= GSOCK_INVADDR
;
1599 return GSOCK_INVADDR
;
1602 #else /* !wxUSE_SOCKETS */
1605 * Translation unit shouldn't be empty, so include this typedef to make the
1606 * compiler (VC++ 6.0, for example) happy
1608 typedef void (*wxDummy
)();
1610 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */