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; 
 181   assert(gs_gui_functions
); 
 182   /* Per-socket GUI-specific initialization */ 
 183   m_ok 
= gs_gui_functions
->Init_Socket(this); 
 186 void GSocket::Close() 
 188     gs_gui_functions
->Disable_Events(this); 
 190     m_fd 
= INVALID_SOCKET
; 
 197   /* Per-socket GUI-specific cleanup */ 
 198   gs_gui_functions
->Destroy_Socket(this); 
 200   /* Check that the socket is really shutdowned */ 
 201   if (m_fd 
!= INVALID_SOCKET
) 
 204   /* Destroy private addresses */ 
 206     GAddress_destroy(m_local
); 
 209     GAddress_destroy(m_peer
); 
 213  *  Disallow further read/write operations on this socket, close 
 214  *  the fd and disable all callbacks. 
 216 void GSocket::Shutdown() 
 222   /* If socket has been created, shutdown it */ 
 223   if (m_fd 
!= INVALID_SOCKET
) 
 229   /* Disable GUI callbacks */ 
 230   for (evt 
= 0; evt 
< GSOCK_MAX_EVENT
; evt
++) 
 231     m_cbacks
[evt
] = NULL
; 
 233   m_detected 
= GSOCK_LOST_FLAG
; 
 236 /* Address handling */ 
 242  *  Set or get the local or peer address for this socket. The 'set' 
 243  *  functions return GSOCK_NOERROR on success, an error code otherwise. 
 244  *  The 'get' functions return a pointer to a GAddress object on success, 
 245  *  or NULL otherwise, in which case they set the error code of the 
 246  *  corresponding GSocket. 
 249  *    GSOCK_INVSOCK - the socket is not valid. 
 250  *    GSOCK_INVADDR - the address is not valid. 
 252 GSocketError 
GSocket::SetLocal(GAddress 
*address
) 
 256   /* the socket must be initialized, or it must be a server */ 
 257   if (m_fd 
!= INVALID_SOCKET 
&& !m_server
) 
 259     m_error 
= GSOCK_INVSOCK
; 
 260     return GSOCK_INVSOCK
; 
 264   if (address 
== NULL 
|| address
->m_family 
== GSOCK_NOFAMILY
) 
 266     m_error 
= GSOCK_INVADDR
; 
 267     return GSOCK_INVADDR
; 
 271     GAddress_destroy(m_local
); 
 273   m_local 
= GAddress_copy(address
); 
 275   return GSOCK_NOERROR
; 
 278 GSocketError 
GSocket::SetPeer(GAddress 
*address
) 
 283   if (address 
== NULL 
|| address
->m_family 
== GSOCK_NOFAMILY
) 
 285     m_error 
= GSOCK_INVADDR
; 
 286     return GSOCK_INVADDR
; 
 290     GAddress_destroy(m_peer
); 
 292   m_peer 
= GAddress_copy(address
); 
 294   return GSOCK_NOERROR
; 
 297 GAddress 
*GSocket::GetLocal() 
 300   struct sockaddr addr
; 
 301   WX_SOCKLEN_T size 
= sizeof(addr
); 
 306   /* try to get it from the m_local var first */ 
 308     return GAddress_copy(m_local
); 
 310   /* else, if the socket is initialized, try getsockname */ 
 311   if (m_fd 
== INVALID_SOCKET
) 
 313     m_error 
= GSOCK_INVSOCK
; 
 317   if (getsockname(m_fd
, &addr
, &size
) == SOCKET_ERROR
) 
 319     m_error 
= GSOCK_IOERR
; 
 323   /* got a valid address from getsockname, create a GAddress object */ 
 324   if ((address 
= GAddress_new()) == NULL
) 
 326      m_error 
= GSOCK_MEMERR
; 
 330   if ((err 
= _GAddress_translate_from(address
, &addr
, size
)) != GSOCK_NOERROR
) 
 332      GAddress_destroy(address
); 
 340 GAddress 
*GSocket::GetPeer() 
 344   /* try to get it from the m_peer var */ 
 346     return GAddress_copy(m_peer
); 
 351 /* Server specific parts */ 
 353 /* GSocket_SetServer: 
 354  *  Sets up this socket as a server. The local address must have been 
 355  *  set with GSocket_SetLocal() before GSocket_SetServer() is called. 
 356  *  Returns GSOCK_NOERROR on success, one of the following otherwise: 
 359  *    GSOCK_INVSOCK - the socket is in use. 
 360  *    GSOCK_INVADDR - the local address has not been set. 
 361  *    GSOCK_IOERR   - low-level error. 
 363 GSocketError 
GSocket::SetServer() 
 369   /* must not be in use */ 
 370   if (m_fd 
!= INVALID_SOCKET
) 
 372     m_error 
= GSOCK_INVSOCK
; 
 373     return GSOCK_INVSOCK
; 
 376   /* the local addr must have been set */ 
 379     m_error 
= GSOCK_INVADDR
; 
 380     return GSOCK_INVADDR
; 
 383   /* Initialize all fields */ 
 387   /* Create the socket */ 
 388   m_fd 
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0); 
 390   if (m_fd 
== INVALID_SOCKET
) 
 392     m_error 
= GSOCK_IOERR
; 
 396   ioctlsocket(m_fd
, FIONBIO
, (u_long FAR 
*) &arg
); 
 397   gs_gui_functions
->Enable_Events(this); 
 399   /* allow a socket to re-bind if the socket is in the TIME_WAIT 
 400      state after being previously closed. 
 403     setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(u_long
)); 
 406   /* Bind to the local address, 
 407    * retrieve the actual address bound, 
 408    * and listen up to 5 connections. 
 410   if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) || 
 413                    (WX_SOCKLEN_T 
*)&m_local
->m_len
) != 0) || 
 414       (listen(m_fd
, 5) != 0)) 
 417     m_error 
= GSOCK_IOERR
; 
 421   return GSOCK_NOERROR
; 
 424 /* GSocket_WaitConnection: 
 425  *  Waits for an incoming client connection. Returns a pointer to 
 426  *  a GSocket object, or NULL if there was an error, in which case 
 427  *  the last error field will be updated for the calling GSocket. 
 429  *  Error codes (set in the calling GSocket) 
 430  *    GSOCK_INVSOCK    - the socket is not valid or not a server. 
 431  *    GSOCK_TIMEDOUT   - timeout, no incoming connections. 
 432  *    GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking. 
 433  *    GSOCK_MEMERR     - couldn't allocate memory. 
 434  *    GSOCK_IOERR      - low-level error. 
 436 GSocket 
*GSocket::WaitConnection() 
 439   struct sockaddr from
; 
 440   WX_SOCKLEN_T fromlen 
= sizeof(from
); 
 446   /* Reenable CONNECTION events */ 
 447   m_detected 
&= ~GSOCK_CONNECTION_FLAG
; 
 449   /* If the socket has already been created, we exit immediately */ 
 450   if (m_fd 
== INVALID_SOCKET 
|| !m_server
) 
 452     m_error 
= GSOCK_INVSOCK
; 
 456   /* Create a GSocket object for the new connection */ 
 457   connection 
= GSocket_new(); 
 461     m_error 
= GSOCK_MEMERR
; 
 465   /* Wait for a connection (with timeout) */ 
 466   if (Input_Timeout() == GSOCK_TIMEDOUT
) 
 469     /* m_error set by _GSocket_Input_Timeout */ 
 473   connection
->m_fd 
= accept(m_fd
, &from
, &fromlen
); 
 475   if (connection
->m_fd 
== INVALID_SOCKET
) 
 477     if (WSAGetLastError() == WSAEWOULDBLOCK
) 
 478       m_error 
= GSOCK_WOULDBLOCK
; 
 480       m_error 
= GSOCK_IOERR
; 
 486   /* Initialize all fields */ 
 487   connection
->m_server   
= false; 
 488   connection
->m_stream   
= true; 
 490   /* Setup the peer address field */ 
 491   connection
->m_peer 
= GAddress_new(); 
 492   if (!connection
->m_peer
) 
 495     m_error 
= GSOCK_MEMERR
; 
 498   err 
= _GAddress_translate_from(connection
->m_peer
, &from
, fromlen
); 
 499   if (err 
!= GSOCK_NOERROR
) 
 501     GAddress_destroy(connection
->m_peer
); 
 507   ioctlsocket(connection
->m_fd
, FIONBIO
, (u_long FAR 
*) &arg
); 
 508   gs_gui_functions
->Enable_Events(connection
); 
 513 /* GSocket_SetReusable: 
 514 *  Simply sets the m_resuable flag on the socket. GSocket_SetServer will 
 515 *  make the appropriate setsockopt() call. 
 516 *  Implemented as a GSocket function because clients (ie, wxSocketServer) 
 517 *  don't have access to the GSocket struct information. 
 518 *  Returns true if the flag was set correctly, false if an error occurred 
 519 *  (ie, if the parameter was NULL) 
 521 bool GSocket::SetReusable() 
 523     /* socket must not be null, and must not be in use/already bound */ 
 524     if (this && m_fd 
== INVALID_SOCKET
) { 
 531 /* Client specific parts */ 
 534  *  For stream (connection oriented) sockets, GSocket_Connect() tries 
 535  *  to establish a client connection to a server using the peer address 
 536  *  as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the 
 537  *  connection has been successfully established, or one of the error 
 538  *  codes listed below. Note that for nonblocking sockets, a return 
 539  *  value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection 
 540  *  request can be completed later; you should use GSocket_Select() 
 541  *  to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the 
 542  *  corresponding asynchronous events. 
 544  *  For datagram (non connection oriented) sockets, GSocket_Connect() 
 545  *  just sets the peer address established with GSocket_SetPeer() as 
 546  *  default destination. 
 549  *    GSOCK_INVSOCK    - the socket is in use or not valid. 
 550  *    GSOCK_INVADDR    - the peer address has not been established. 
 551  *    GSOCK_TIMEDOUT   - timeout, the connection failed. 
 552  *    GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only) 
 553  *    GSOCK_MEMERR     - couldn't allocate memory. 
 554  *    GSOCK_IOERR      - low-level error. 
 556 GSocketError 
GSocket::Connect(GSocketStream stream
) 
 563   /* Enable CONNECTION events (needed for nonblocking connections) */ 
 564   m_detected 
&= ~GSOCK_CONNECTION_FLAG
; 
 566   if (m_fd 
!= INVALID_SOCKET
) 
 568     m_error 
= GSOCK_INVSOCK
; 
 569     return GSOCK_INVSOCK
; 
 574     m_error 
= GSOCK_INVADDR
; 
 575     return GSOCK_INVADDR
; 
 578   /* Streamed or dgram socket? */ 
 579   m_stream   
= (stream 
== GSOCK_STREAMED
); 
 581   m_establishing 
= false; 
 583   /* Create the socket */ 
 584   m_fd 
= socket(m_peer
->m_realfamily
, 
 585                      m_stream
? SOCK_STREAM 
: SOCK_DGRAM
, 0); 
 587   if (m_fd 
== INVALID_SOCKET
) 
 589     m_error 
= GSOCK_IOERR
; 
 593   ioctlsocket(m_fd
, FIONBIO
, (u_long FAR 
*) &arg
); 
 594   gs_gui_functions
->Enable_Events(this); 
 596   // If the reuse flag is set, use the applicable socket reuse flag 
 599      setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&arg
, sizeof(u_long
)); 
 602   // If a local address has been set, then we need to bind to it before calling connect 
 603   if (m_local 
&& m_local
->m_addr
) 
 605     bind(m_fd
, m_local
->m_addr
, m_local
->m_len
); 
 608   /* Connect it to the peer address, with a timeout (see below) */ 
 609   ret 
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
); 
 611   if (ret 
== SOCKET_ERROR
) 
 613     err 
= WSAGetLastError(); 
 615     /* If connect failed with EWOULDBLOCK and the GSocket object 
 616      * is in blocking mode, we select() for the specified timeout 
 617      * checking for writability to see if the connection request 
 620     if ((err 
== WSAEWOULDBLOCK
) && (!m_non_blocking
)) 
 622       err 
= Connect_Timeout(); 
 624       if (err 
!= GSOCK_NOERROR
) 
 627         /* m_error is set in _GSocket_Connect_Timeout */ 
 630       return (GSocketError
) err
; 
 633     /* If connect failed with EWOULDBLOCK and the GSocket object 
 634      * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK 
 635      * (and return GSOCK_WOULDBLOCK) but we don't close the socket; 
 636      * this way if the connection completes, a GSOCK_CONNECTION 
 637      * event will be generated, if enabled. 
 639     if ((err 
== WSAEWOULDBLOCK
) && (m_non_blocking
)) 
 641       m_establishing 
= true; 
 642       m_error 
= GSOCK_WOULDBLOCK
; 
 643       return GSOCK_WOULDBLOCK
; 
 646     /* If connect failed with an error other than EWOULDBLOCK, 
 647      * then the call to GSocket_Connect() has failed. 
 650     m_error 
= GSOCK_IOERR
; 
 654   return GSOCK_NOERROR
; 
 657 /* Datagram sockets */ 
 659 /* GSocket_SetNonOriented: 
 660  *  Sets up this socket as a non-connection oriented (datagram) socket. 
 661  *  Before using this function, the local address must have been set 
 662  *  with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR 
 663  *  on success, or one of the following otherwise. 
 666  *    GSOCK_INVSOCK - the socket is in use. 
 667  *    GSOCK_INVADDR - the local address has not been set. 
 668  *    GSOCK_IOERR   - low-level error. 
 670 GSocketError 
GSocket::SetNonOriented() 
 676   if (m_fd 
!= INVALID_SOCKET
) 
 678     m_error 
= GSOCK_INVSOCK
; 
 679     return GSOCK_INVSOCK
; 
 684     m_error 
= GSOCK_INVADDR
; 
 685     return GSOCK_INVADDR
; 
 688   /* Initialize all fields */ 
 692   /* Create the socket */ 
 693   m_fd 
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0); 
 695   if (m_fd 
== INVALID_SOCKET
) 
 697     m_error 
= GSOCK_IOERR
; 
 701   ioctlsocket(m_fd
, FIONBIO
, (u_long FAR 
*) &arg
); 
 702   gs_gui_functions
->Enable_Events(this); 
 704   /* Bind to the local address, 
 705    * and retrieve the actual address bound. 
 707   if ((bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0) || 
 710                    (WX_SOCKLEN_T 
*)&m_local
->m_len
) != 0)) 
 713     m_error 
= GSOCK_IOERR
; 
 717   return GSOCK_NOERROR
; 
 722 /* Like recv(), send(), ... */ 
 723 int GSocket::Read(char *buffer
, int size
) 
 729   /* Reenable INPUT events */ 
 730   m_detected 
&= ~GSOCK_INPUT_FLAG
; 
 732   if (m_fd 
== INVALID_SOCKET 
|| m_server
) 
 734     m_error 
= GSOCK_INVSOCK
; 
 738   /* If the socket is blocking, wait for data (with a timeout) */ 
 739   if (Input_Timeout() == GSOCK_TIMEDOUT
) 
 741     m_error 
= GSOCK_TIMEDOUT
; 
 747     ret 
= Recv_Stream(buffer
, size
); 
 749     ret 
= Recv_Dgram(buffer
, size
); 
 751   if (ret 
== SOCKET_ERROR
) 
 753     if (WSAGetLastError() != WSAEWOULDBLOCK
) 
 754       m_error 
= GSOCK_IOERR
; 
 756       m_error 
= GSOCK_WOULDBLOCK
; 
 763 int GSocket::Write(const char *buffer
, int size
) 
 769   if (m_fd 
== INVALID_SOCKET 
|| m_server
) 
 771     m_error 
= GSOCK_INVSOCK
; 
 775   /* If the socket is blocking, wait for writability (with a timeout) */ 
 776   if (Output_Timeout() == GSOCK_TIMEDOUT
) 
 781     ret 
= Send_Stream(buffer
, size
); 
 783     ret 
= Send_Dgram(buffer
, size
); 
 785   if (ret 
== SOCKET_ERROR
) 
 787     if (WSAGetLastError() != WSAEWOULDBLOCK
) 
 788       m_error 
= GSOCK_IOERR
; 
 790       m_error 
= GSOCK_WOULDBLOCK
; 
 792     /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect 
 793      * does). Once the first OUTPUT event is received, users can assume 
 794      * that the socket is writable until a read operation fails. Only then 
 795      * will further OUTPUT events be posted. 
 797     m_detected 
&= ~GSOCK_OUTPUT_FLAG
; 
 805  *  Polls the socket to determine its status. This function will 
 806  *  check for the events specified in the 'flags' parameter, and 
 807  *  it will return a mask indicating which operations can be 
 808  *  performed. This function won't block, regardless of the 
 809  *  mode (blocking | nonblocking) of the socket. 
 811 GSocketEventFlags 
GSocket::Select(GSocketEventFlags flags
) 
 813   if (!gs_gui_functions
->CanUseEventLoop()) 
 815     GSocketEventFlags result 
= 0; 
 825     FD_SET(m_fd
, &readfds
); 
 826     if (flags 
& GSOCK_OUTPUT_FLAG 
|| flags 
& GSOCK_CONNECTION_FLAG
) 
 827       FD_SET(m_fd
, &writefds
); 
 828     FD_SET(m_fd
, &exceptfds
); 
 830     /* Check 'sticky' CONNECTION flag first */ 
 831     result 
|= (GSOCK_CONNECTION_FLAG 
& m_detected
); 
 833     /* If we have already detected a LOST event, then don't try 
 834      * to do any further processing. 
 836     if ((m_detected 
& GSOCK_LOST_FLAG
) != 0) 
 838       m_establishing 
= false; 
 840       return (GSOCK_LOST_FLAG 
& flags
); 
 844     if (select(m_fd 
+ 1, &readfds
, &writefds
, &exceptfds
, 
 847       /* What to do here? */ 
 848       return (result 
& flags
); 
 851     /* Check for exceptions and errors */ 
 852     if (FD_ISSET(m_fd
, &exceptfds
)) 
 854       m_establishing 
= false; 
 855       m_detected 
= GSOCK_LOST_FLAG
; 
 857       /* LOST event: Abort any further processing */ 
 858       return (GSOCK_LOST_FLAG 
& flags
); 
 861     /* Check for readability */ 
 862     if (FD_ISSET(m_fd
, &readfds
)) 
 864       result 
|= GSOCK_INPUT_FLAG
; 
 866       if (m_server 
&& m_stream
) 
 868         /* This is a TCP server socket that detected a connection.  
 869            While the INPUT_FLAG is also set, it doesn't matter on  
 870            this kind of  sockets, as we can only Accept() from them. */ 
 871         result 
|= GSOCK_CONNECTION_FLAG
; 
 872         m_detected 
|= GSOCK_CONNECTION_FLAG
; 
 876     /* Check for writability */ 
 877     if (FD_ISSET(m_fd
, &writefds
)) 
 879       if (m_establishing 
&& !m_server
) 
 882         WX_SOCKLEN_T len 
= sizeof(error
); 
 884         m_establishing 
= false; 
 886         getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
); 
 890           m_detected 
= GSOCK_LOST_FLAG
; 
 892           /* LOST event: Abort any further processing */ 
 893           return (GSOCK_LOST_FLAG 
& flags
); 
 897           result 
|= GSOCK_CONNECTION_FLAG
; 
 898           m_detected 
|= GSOCK_CONNECTION_FLAG
; 
 903         result 
|= GSOCK_OUTPUT_FLAG
; 
 907     return (result 
& flags
); 
 912     return flags 
& m_detected
; 
 918 /* GSocket_SetNonBlocking: 
 919  *  Sets the socket to non-blocking mode. All IO calls will return 
 922 void GSocket::SetNonBlocking(bool non_block
) 
 926   m_non_blocking 
= non_block
; 
 929 /* GSocket_SetTimeout: 
 930  *  Sets the timeout for blocking calls. Time is expressed in 
 933 void GSocket::SetTimeout(unsigned long millis
) 
 937   m_timeout
.tv_sec  
= (millis 
/ 1000); 
 938   m_timeout
.tv_usec 
= (millis 
% 1000) * 1000; 
 942  *  Returns the last error occurred for this socket. Note that successful 
 943  *  operations do not clear this back to GSOCK_NOERROR, so use it only 
 946 GSocketError WXDLLIMPEXP_NET 
GSocket::GetError() 
 956  *   There is data to be read in the input buffer. If, after a read 
 957  *   operation, there is still data available, the callback function will 
 960  *   The socket is available for writing. That is, the next write call 
 961  *   won't block. This event is generated only once, when the connection is 
 962  *   first established, and then only if a call failed with GSOCK_WOULDBLOCK, 
 963  *   when the output buffer empties again. This means that the app should 
 964  *   assume that it can write since the first OUTPUT event, and no more 
 965  *   OUTPUT events will be generated unless an error occurs. 
 967  *   Connection successfully established, for client sockets, or incoming 
 968  *   client connection, for server sockets. Wait for this event (also watch 
 969  *   out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call. 
 971  *   The connection is lost (or a connection request failed); this could 
 972  *   be due to a failure, or due to the peer closing it gracefully. 
 975 /* GSocket_SetCallback: 
 976  *  Enables the callbacks specified by 'flags'. Note that 'flags' 
 977  *  may be a combination of flags OR'ed toghether, so the same 
 978  *  callback function can be made to accept different events. 
 979  *  The callback function must have the following prototype: 
 981  *  void function(GSocket *socket, GSocketEvent event, char *cdata) 
 983 void GSocket::SetCallback(GSocketEventFlags flags
, 
 984                          GSocketCallback callback
, char *cdata
) 
 990   for (count 
= 0; count 
< GSOCK_MAX_EVENT
; count
++) 
 992     if ((flags 
& (1 << count
)) != 0) 
 994       m_cbacks
[count
] = callback
; 
 995       m_data
[count
] = cdata
; 
1000 /* GSocket_UnsetCallback: 
1001  *  Disables all callbacks specified by 'flags', which may be a 
1002  *  combination of flags OR'ed toghether. 
1004 void GSocket::UnsetCallback(GSocketEventFlags flags
) 
1010   for (count 
= 0; count 
< GSOCK_MAX_EVENT
; count
++) 
1012     if ((flags 
& (1 << count
)) != 0) 
1014       m_cbacks
[count
] = NULL
; 
1015       m_data
[count
] = NULL
; 
1020 GSocketError 
GSocket::GetSockOpt(int level
, int optname
, 
1021                                 void *optval
, int *optlen
) 
1023     if (getsockopt(m_fd
, level
, optname
, (char*)optval
, optlen
) == 0) 
1025         return GSOCK_NOERROR
; 
1027     return GSOCK_OPTERR
; 
1030 GSocketError 
GSocket::SetSockOpt(int level
, int optname
, 
1031                                 const void *optval
, int optlen
) 
1033     if (setsockopt(m_fd
, level
, optname
, (char*)optval
, optlen
) == 0) 
1035         return GSOCK_NOERROR
; 
1037     return GSOCK_OPTERR
; 
1040 /* Internals (IO) */ 
1042 /* _GSocket_Input_Timeout: 
1043  *  For blocking sockets, wait until data is available or 
1044  *  until timeout ellapses. 
1046 GSocketError 
GSocket::Input_Timeout() 
1050   if (!m_non_blocking
) 
1053     FD_SET(m_fd
, &readfds
); 
1054     if (select(0, &readfds
, NULL
, NULL
, &m_timeout
) == 0) 
1056       m_error 
= GSOCK_TIMEDOUT
; 
1057       return GSOCK_TIMEDOUT
; 
1060   return GSOCK_NOERROR
; 
1063 /* _GSocket_Output_Timeout: 
1064  *  For blocking sockets, wait until data can be sent without 
1065  *  blocking or until timeout ellapses. 
1067 GSocketError 
GSocket::Output_Timeout() 
1071   if (!m_non_blocking
) 
1074     FD_SET(m_fd
, &writefds
); 
1075     if (select(0, NULL
, &writefds
, NULL
, &m_timeout
) == 0) 
1077       m_error 
= GSOCK_TIMEDOUT
; 
1078       return GSOCK_TIMEDOUT
; 
1081   return GSOCK_NOERROR
; 
1084 /* _GSocket_Connect_Timeout: 
1085  *  For blocking sockets, wait until the connection is 
1086  *  established or fails, or until timeout ellapses. 
1088 GSocketError 
GSocket::Connect_Timeout() 
1094   FD_ZERO(&exceptfds
); 
1095   FD_SET(m_fd
, &writefds
); 
1096   FD_SET(m_fd
, &exceptfds
); 
1097   if (select(0, NULL
, &writefds
, &exceptfds
, &m_timeout
) == 0) 
1099     m_error 
= GSOCK_TIMEDOUT
; 
1100     return GSOCK_TIMEDOUT
; 
1102   if (!FD_ISSET(m_fd
, &writefds
)) 
1104     m_error 
= GSOCK_IOERR
; 
1108   return GSOCK_NOERROR
; 
1111 int GSocket::Recv_Stream(char *buffer
, int size
) 
1113   return recv(m_fd
, buffer
, size
, 0); 
1116 int GSocket::Recv_Dgram(char *buffer
, int size
) 
1118   struct sockaddr from
; 
1119   WX_SOCKLEN_T fromlen 
= sizeof(from
); 
1123   ret 
= recvfrom(m_fd
, buffer
, size
, 0, &from
, &fromlen
); 
1125   if (ret 
== SOCKET_ERROR
) 
1126     return SOCKET_ERROR
; 
1128   /* Translate a system address into a GSocket address */ 
1131     m_peer 
= GAddress_new(); 
1134       m_error 
= GSOCK_MEMERR
; 
1138   err 
= _GAddress_translate_from(m_peer
, &from
, fromlen
); 
1139   if (err 
!= GSOCK_NOERROR
) 
1141     GAddress_destroy(m_peer
); 
1150 int GSocket::Send_Stream(const char *buffer
, int size
) 
1152   return send(m_fd
, buffer
, size
, 0); 
1155 int GSocket::Send_Dgram(const char *buffer
, int size
) 
1157   struct sockaddr 
*addr
; 
1163     m_error 
= GSOCK_INVADDR
; 
1167   err 
= _GAddress_translate_to(m_peer
, &addr
, &len
); 
1168   if (err 
!= GSOCK_NOERROR
) 
1174   ret 
= sendto(m_fd
, buffer
, size
, 0, addr
, len
); 
1176   /* Frees memory allocated by _GAddress_translate_to */ 
1182 /* Compatibility functions for GSocket */ 
1183 GSocket 
*GSocket_new(void) 
1185     GSocket 
*newsocket 
= new GSocket(); 
1186     if(newsocket
->IsOk()) 
1194  * ------------------------------------------------------------------------- 
1196  * ------------------------------------------------------------------------- 
1199 /* CHECK_ADDRESS verifies that the current address family is either 
1200  * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it 
1201  * initalizes it to be a GSOCK_*family*. In other cases, it returns 
1202  * an appropiate error code. 
1204  * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error. 
1206 #define CHECK_ADDRESS(address, family)                              \ 
1208   if (address->m_family == GSOCK_NOFAMILY)                          \ 
1209     if (_GAddress_Init_##family(address) != GSOCK_NOERROR)          \ 
1210       return address->m_error;                                      \ 
1211   if (address->m_family != GSOCK_##family)                          \ 
1213     address->m_error = GSOCK_INVADDR;                               \ 
1214     return GSOCK_INVADDR;                                           \ 
1218 #define CHECK_ADDRESS_RETVAL(address, family, retval)               \ 
1220   if (address->m_family == GSOCK_NOFAMILY)                          \ 
1221     if (_GAddress_Init_##family(address) != GSOCK_NOERROR)          \ 
1223   if (address->m_family != GSOCK_##family)                          \ 
1225     address->m_error = GSOCK_INVADDR;                               \ 
1231 GAddress 
*GAddress_new(void) 
1235   if ((address 
= (GAddress 
*) malloc(sizeof(GAddress
))) == NULL
) 
1238   address
->m_family 
= GSOCK_NOFAMILY
; 
1239   address
->m_addr   
= NULL
; 
1245 GAddress 
*GAddress_copy(GAddress 
*address
) 
1249   assert(address 
!= NULL
); 
1251   if ((addr2 
= (GAddress 
*) malloc(sizeof(GAddress
))) == NULL
) 
1254   memcpy(addr2
, address
, sizeof(GAddress
)); 
1256   if (address
->m_addr
) 
1258     addr2
->m_addr 
= (struct sockaddr 
*) malloc(addr2
->m_len
); 
1259     if (addr2
->m_addr 
== NULL
) 
1264     memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
); 
1270 void GAddress_destroy(GAddress 
*address
) 
1272   assert(address 
!= NULL
); 
1274   if (address
->m_addr
) 
1275     free(address
->m_addr
); 
1280 void GAddress_SetFamily(GAddress 
*address
, GAddressType type
) 
1282   assert(address 
!= NULL
); 
1284   address
->m_family 
= type
; 
1287 GAddressType 
GAddress_GetFamily(GAddress 
*address
) 
1289   assert(address 
!= NULL
); 
1291   return address
->m_family
; 
1294 GSocketError 
_GAddress_translate_from(GAddress 
*address
, 
1295                                       struct sockaddr 
*addr
, int len
) 
1297   address
->m_realfamily 
= addr
->sa_family
; 
1298   switch (addr
->sa_family
) 
1301       address
->m_family 
= GSOCK_INET
; 
1304       address
->m_family 
= GSOCK_UNIX
; 
1308       address
->m_family 
= GSOCK_INET6
; 
1313       address
->m_error 
= GSOCK_INVOP
; 
1318   if (address
->m_addr
) 
1319     free(address
->m_addr
); 
1321   address
->m_len 
= len
; 
1322   address
->m_addr 
= (struct sockaddr 
*) malloc(len
); 
1324   if (address
->m_addr 
== NULL
) 
1326     address
->m_error 
= GSOCK_MEMERR
; 
1327     return GSOCK_MEMERR
; 
1329   memcpy(address
->m_addr
, addr
, len
); 
1331   return GSOCK_NOERROR
; 
1334 GSocketError 
_GAddress_translate_to(GAddress 
*address
, 
1335                                     struct sockaddr 
**addr
, int *len
) 
1337   if (!address
->m_addr
) 
1339     address
->m_error 
= GSOCK_INVADDR
; 
1340     return GSOCK_INVADDR
; 
1343   *len 
= address
->m_len
; 
1344   *addr 
= (struct sockaddr 
*) malloc(address
->m_len
); 
1347     address
->m_error 
= GSOCK_MEMERR
; 
1348     return GSOCK_MEMERR
; 
1351   memcpy(*addr
, address
->m_addr
, address
->m_len
); 
1352   return GSOCK_NOERROR
; 
1356  * ------------------------------------------------------------------------- 
1357  * Internet address family 
1358  * ------------------------------------------------------------------------- 
1361 GSocketError 
_GAddress_Init_INET(GAddress 
*address
) 
1363   address
->m_len  
= sizeof(struct sockaddr_in
); 
1364   address
->m_addr 
= (struct sockaddr 
*) malloc(address
->m_len
); 
1365   if (address
->m_addr 
== NULL
) 
1367     address
->m_error 
= GSOCK_MEMERR
; 
1368     return GSOCK_MEMERR
; 
1371   address
->m_family 
= GSOCK_INET
; 
1372   address
->m_realfamily 
= AF_INET
; 
1373   ((struct sockaddr_in 
*)address
->m_addr
)->sin_family 
= AF_INET
; 
1374   ((struct sockaddr_in 
*)address
->m_addr
)->sin_addr
.s_addr 
= INADDR_ANY
; 
1376   return GSOCK_NOERROR
; 
1379 GSocketError 
GAddress_INET_SetHostName(GAddress 
*address
, const char *hostname
) 
1382   struct in_addr 
*addr
; 
1384   assert(address 
!= NULL
); 
1386   CHECK_ADDRESS(address
, INET
); 
1388   addr 
= &(((struct sockaddr_in 
*)address
->m_addr
)->sin_addr
); 
1390   addr
->s_addr 
= inet_addr(hostname
); 
1392   /* If it is a numeric host name, convert it now */ 
1393   if (addr
->s_addr 
== INADDR_NONE
) 
1395     struct in_addr 
*array_addr
; 
1397     /* It is a real name, we solve it */ 
1398     if ((he 
= gethostbyname(hostname
)) == NULL
) 
1400       /* addr->s_addr = INADDR_NONE just done by inet_addr() above */ 
1401       address
->m_error 
= GSOCK_NOHOST
; 
1402       return GSOCK_NOHOST
; 
1404     array_addr 
= (struct in_addr 
*) *(he
->h_addr_list
); 
1405     addr
->s_addr 
= array_addr
[0].s_addr
; 
1407   return GSOCK_NOERROR
; 
1410 GSocketError 
GAddress_INET_SetAnyAddress(GAddress 
*address
) 
1412   return GAddress_INET_SetHostAddress(address
, INADDR_ANY
); 
1415 GSocketError 
GAddress_INET_SetHostAddress(GAddress 
*address
, 
1416                                           unsigned long hostaddr
) 
1418   struct in_addr 
*addr
; 
1420   assert(address 
!= NULL
); 
1422   CHECK_ADDRESS(address
, INET
); 
1424   addr 
= &(((struct sockaddr_in 
*)address
->m_addr
)->sin_addr
); 
1425   addr
->s_addr 
= htonl(hostaddr
); 
1427   return GSOCK_NOERROR
; 
1430 GSocketError 
GAddress_INET_SetPortName(GAddress 
*address
, const char *port
, 
1431                                        const char *protocol
) 
1434   struct sockaddr_in 
*addr
; 
1436   assert(address 
!= NULL
); 
1437   CHECK_ADDRESS(address
, INET
); 
1441     address
->m_error 
= GSOCK_INVPORT
; 
1442     return GSOCK_INVPORT
; 
1445   se 
= getservbyname(port
, protocol
); 
1448     if (isdigit(port
[0])) 
1452       port_int 
= atoi(port
); 
1453       addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1454       addr
->sin_port 
= htons((u_short
) port_int
); 
1455       return GSOCK_NOERROR
; 
1458     address
->m_error 
= GSOCK_INVPORT
; 
1459     return GSOCK_INVPORT
; 
1462   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1463   addr
->sin_port 
= se
->s_port
; 
1465   return GSOCK_NOERROR
; 
1468 GSocketError 
GAddress_INET_SetPort(GAddress 
*address
, unsigned short port
) 
1470   struct sockaddr_in 
*addr
; 
1472   assert(address 
!= NULL
); 
1473   CHECK_ADDRESS(address
, INET
); 
1475   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1476   addr
->sin_port 
= htons(port
); 
1478   return GSOCK_NOERROR
; 
1481 GSocketError 
GAddress_INET_GetHostName(GAddress 
*address
, char *hostname
, size_t sbuf
) 
1485   struct sockaddr_in 
*addr
; 
1487   assert(address 
!= NULL
); 
1488   CHECK_ADDRESS(address
, INET
); 
1490   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1491   addr_buf 
= (char *)&(addr
->sin_addr
); 
1493   he 
= gethostbyaddr(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
); 
1496     address
->m_error 
= GSOCK_NOHOST
; 
1497     return GSOCK_NOHOST
; 
1500   strncpy(hostname
, he
->h_name
, sbuf
); 
1502   return GSOCK_NOERROR
; 
1505 unsigned long GAddress_INET_GetHostAddress(GAddress 
*address
) 
1507   struct sockaddr_in 
*addr
; 
1509   assert(address 
!= NULL
); 
1510   CHECK_ADDRESS_RETVAL(address
, INET
, 0); 
1512   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1514   return ntohl(addr
->sin_addr
.s_addr
); 
1517 unsigned short GAddress_INET_GetPort(GAddress 
*address
) 
1519   struct sockaddr_in 
*addr
; 
1521   assert(address 
!= NULL
); 
1522   CHECK_ADDRESS_RETVAL(address
, INET
, 0); 
1524   addr 
= (struct sockaddr_in 
*)address
->m_addr
; 
1525   return ntohs(addr
->sin_port
); 
1529  * ------------------------------------------------------------------------- 
1530  * Unix address family 
1531  * ------------------------------------------------------------------------- 
1534 GSocketError 
_GAddress_Init_UNIX(GAddress 
*address
) 
1536   assert (address 
!= NULL
); 
1537   address
->m_error 
= GSOCK_INVADDR
; 
1538   return GSOCK_INVADDR
; 
1541 GSocketError 
GAddress_UNIX_SetPath(GAddress 
*address
, const char *WXUNUSED(path
)) 
1543   assert (address 
!= NULL
); 
1544   address
->m_error 
= GSOCK_INVADDR
; 
1545   return GSOCK_INVADDR
; 
1548 GSocketError 
GAddress_UNIX_GetPath(GAddress 
*address
, char *WXUNUSED(path
), size_t WXUNUSED(sbuf
)) 
1550   assert (address 
!= NULL
); 
1551   address
->m_error 
= GSOCK_INVADDR
; 
1552   return GSOCK_INVADDR
; 
1555 #else /* !wxUSE_SOCKETS */ 
1558  * Translation unit shouldn't be empty, so include this typedef to make the 
1559  * compiler (VC++ 6.0, for example) happy 
1561 typedef void (*wxDummy
)(); 
1563 #endif  /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */