1 /* ------------------------------------------------------------------------- 
   2  * Project: GSocket (Generic Socket) for WX 
   4  * Authors: Guilhem Lavaux, 
   5  *          Guillermo Rodriguez Garcia <guille@iies.es> (maintainer) 
   7  * Purpose: GSocket main mac file 
   9  * ------------------------------------------------------------------------- 
  13  * PLEASE don't put C++ comments here - this is a C source file. 
  16 #ifndef __GSOCKET_STANDALONE__ 
  18 #include "wx/platform.h" 
  21 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) 
  24   #include <CoreServices/CoreServices.h> 
  33   #include <MacHeaders.c> 
  34   #define OTUNIXERRORS 1 
  35   #include <OpenTransport.h> 
  36   #include <OpenTransportProviders.h> 
  37   #include <OpenTptInternet.h> 
  39 #if TARGET_CARBON && !defined(OTAssert) 
  40   #define OTAssert( str , cond ) /* does not exists in Carbon */ 
  54  * INADDR_BROADCAST is identical to INADDR_NONE which is not defined 
  55  * on all unices. INADDR_BROADCAST should be fine to indicate an error. 
  57 #ifndef INADDR_BROADCAST 
  58 #define INADDR_BROADCAST 0xFFFFFFFFUL 
  61 #define INADDR_NONE INADDR_BROADCAST 
  64 #define INADDR_ANY 0x0UL 
  66 #ifndef __GSOCKET_STANDALONE__ 
  68 #include "wx/mac/macnotfy.h" 
  69 #include "wx/mac/gsockmac.h" 
  70 #include "wx/gsocket.h" 
  77 #endif /* __GSOCKET_STANDALONE__ */ 
  83 extern pascal void OTDebugStr(const char* str
); 
  88 InetSvcRef gInetSvcRef 
= 0 ; 
  90 OTNotifyUPP gOTNotifierUPP 
= NULL 
; 
  92 OSStatus 
DoNegotiateIPReuseAddrOption(EndpointRef ep
, Boolean enableReuseIPMode
); 
  94 /* Input: ep - endpointref on which to negotiate the option 
  95                         enableReuseIPMode - desired option setting - true/false 
  96    Return: kOTNoError indicates that the option was successfully negotiated 
  97                         OSStatus is an error if < 0, otherwise, the status field is 
 100         IMPORTANT NOTE: The endpoint is assumed to be in synchronous more, otherwise 
 101                         this code will not function as desired 
 105 OSStatus 
DoNegotiateIPReuseAddrOption(EndpointRef ep
, Boolean enableReuseIPMode
) 
 108         UInt8           buf
[kOTFourByteOptionSize
];     // define buffer for fourByte Option size 
 109         TOption
*        opt
;                                            // option ptr to make items easier to access 
 114         if (!OTIsSynchronous(ep
)) 
 118         opt 
= (TOption
*)buf
;                                    // set option ptr to buffer 
 120         req
.opt
.len     
= sizeof(buf
); 
 121         req
.flags       
= T_NEGOTIATE
;                          // negotiate for option 
 124         ret
.opt
.maxlen 
= kOTFourByteOptionSize
; 
 126         opt
->level      
= INET_IP
;                                      // dealing with an IP Level function 
 128         opt
->name       
= kIP_REUSEADDR
; 
 130         opt
->name       
= IP_REUSEADDR
; 
 132         opt
->len        
= kOTFourByteOptionSize
; 
 134         *(UInt32
*)opt
->value 
= enableReuseIPMode
;               // set the desired option level, true or false 
 136         err 
= OTOptionManagement(ep
, &req
, &ret
); 
 138                 // if no error then return the option status value 
 139         if (err 
== kOTNoError
) 
 141                 if (opt
->status 
!= T_SUCCESS
) 
 151 pascal void OTInetEventHandler(void*s
, OTEventCode event
, OTResult
, void *cookie
) ; 
 152 pascal void OTInetEventHandler(void*s
, OTEventCode event
, OTResult result
, void *cookie
) 
 155         GSocket
* sock 
= (GSocket
*) s 
; 
 157         if ( event 
== kOTSyncIdleEvent 
) 
 165                 wxMacAddEvent( sock
->m_mac_events 
, _GSocket_Internal_Proc 
, event 
, s 
, wakeUp 
) ; 
 171 static void SetDefaultEndpointModes(EndpointRef ep 
, void *data 
) 
 172         // This routine sets the supplied endpoint into the default 
 173         // mode used in this application.  The specifics are: 
 174         // blocking, synchronous, and using synch idle events with 
 175         // the standard YieldingNotifier. 
 177         OSStatus junk 
= kOTNoError 
; 
 178         OTAssert ("SetDefaultEndpointModes:invalid ref", ep 
!= kOTInvalidEndpointRef 
) ; 
 179         junk 
= OTSetAsynchronous(ep
); 
 180         OTAssert("SetDefaultEndpointModes: Could not set asynchronous", junk 
== noErr
); 
 182         junk = OTSetBlocking(ep); 
 183         OTAssert("SetDefaultEndpointModes: Could not set blocking", junk == noErr); 
 184         junk = OTSetSynchronous(ep); 
 185         OTAssert("SetDefaultEndpointModes: Could not set synchronous", junk == noErr); 
 186         junk = OTSetBlocking(ep); 
 187         OTAssert("SetDefaultEndpointModes: Could not set blocking", junk == noErr); 
 189         junk 
= OTInstallNotifier(ep
, gOTNotifierUPP
, data
); 
 190         OTAssert("SetDefaultEndpointModes: Could not install notifier", junk 
== noErr
); 
 192         junk = OTUseSyncIdleEvents(ep, true); 
 193         OTAssert("SetDefaultEndpointModes: Could not use sync idle events", junk == noErr); 
 197 /* Global initialisers */ 
 199 void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable 
*table
) 
 201     // do nothing, wxMac doesn't have wxBase-GUI separation yet 
 209 int GSocket_Verify_Inited() ; 
 210 int GSocket_Verify_Inited() 
 214     // Marc Newsam: added the clientcontext variable 
 215     //              however, documentation is unclear how this works 
 216     OTClientContextPtr clientcontext
; 
 221     InitOpenTransportInContext(kInitOTForApplicationMask
, &clientcontext
); 
 223     gInetSvcRef 
= OTOpenInternetServicesInContext(kDefaultInternetServicesPath
, 
 224                                                 NULL
, &err
, clientcontext
); 
 229     InitOpenTransport() ; 
 231     gInetSvcRef 
= OTOpenInternetServices(kDefaultInternetServicesPath
, NULL
, &err
); 
 233     if ( gInetSvcRef 
== NULL 
||  err 
!= kOTNoError 
) 
 235         OTAssert("Could not open Inet Services", err 
== noErr
); 
 238     gOTNotifierUPP 
= NewOTNotifyUPP( OTInetEventHandler 
) ; 
 242 void GSocket_Cleanup() 
 244     if ( gOTInited 
!= 0 ) 
 246       if ( gInetSvcRef 
!= NULL 
) 
 247         OTCloseProvider( gInetSvcRef 
); 
 249       CloseOpenTransportInContext( NULL 
) ; 
 251       CloseOpenTransport() ; 
 253         if ( gOTNotifierUPP 
) 
 254             DisposeOTNotifyUPP( gOTNotifierUPP 
) ; 
 258 /* Constructors / Destructors for GSocket */ 
 260 GSocket 
*GSocket_new() 
 266  if ( GSocket_Verify_Inited() == FALSE 
) 
 269   socket 
= (GSocket 
*)malloc(sizeof(GSocket
)); 
 274   socket
->m_endpoint                  
= NULL 
; 
 275   for (i
=0;i
<GSOCK_MAX_EVENT
;i
++) 
 277     socket
->m_cbacks
[i
]         = NULL
; 
 279   socket
->m_detected            
= 0; 
 280   socket
->m_local               
= NULL
; 
 281   socket
->m_peer                
= NULL
; 
 282   socket
->m_error               
= GSOCK_NOERROR
; 
 283   socket
->m_server              
= FALSE
; 
 284   socket
->m_stream              
= TRUE
; 
 285   socket
->m_non_blocking        
= FALSE
; 
 286   socket
->m_timeout             
= 1*1000; 
 287                                 /* 10 sec * 1000 millisec */ 
 288   socket
->m_takesEvents                 
= TRUE 
; 
 289   socket
->m_mac_events                  
= wxMacGetNotifierTable() ; 
 293 void GSocket_destroy(GSocket 
*socket
) 
 295   assert(socket 
!= NULL
); 
 297   /* Check that the socket is really shutdowned */ 
 298   if (socket
->m_endpoint 
!= kOTInvalidEndpointRef
) 
 299     GSocket_Shutdown(socket
); 
 302   /* Destroy private addresses */ 
 304     GAddress_destroy(socket
->m_local
); 
 307     GAddress_destroy(socket
->m_peer
); 
 309   /* Destroy the socket itself */ 
 314  *  Disallow further read/write operations on this socket, close 
 315  *  the fd and disable all callbacks. 
 317 void GSocket_Shutdown(GSocket 
*socket
) 
 322   assert(socket 
!= NULL
); 
 324   /* If socket has been created, shutdown it */ 
 325   if (socket
->m_endpoint 
!= kOTInvalidEndpointRef 
) 
 327     err 
= OTSndOrderlyDisconnect( socket
->m_endpoint 
) ; 
 328         if ( err 
!= kOTNoError 
) 
 332     err 
= OTRcvOrderlyDisconnect( socket
->m_endpoint 
) ; 
 333         err 
= OTUnbind( socket
->m_endpoint 
) ; 
 334         err 
= OTCloseProvider( socket
->m_endpoint 
) ; 
 335         socket
->m_endpoint 
= kOTInvalidEndpointRef 
; 
 338   /* Disable GUI callbacks */ 
 339   for (evt 
= 0; evt 
< GSOCK_MAX_EVENT
; evt
++) 
 340     socket
->m_cbacks
[evt
] = NULL
; 
 342   socket
->m_detected 
= 0; 
 343   _GSocket_Disable_Events(socket
); 
 344   wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , socket 
) ; 
 348 /* Address handling */ 
 354  *  Set or get the local or peer address for this socket. The 'set' 
 355  *  functions return GSOCK_NOERROR on success, an error code otherwise. 
 356  *  The 'get' functions return a pointer to a GAddress object on success, 
 357  *  or NULL otherwise, in which case they set the error code of the 
 358  *  corresponding GSocket. 
 361  *    GSOCK_INVSOCK - the socket is not valid. 
 362  *    GSOCK_INVADDR - the address is not valid. 
 364 GSocketError 
GSocket_SetLocal(GSocket 
*socket
, GAddress 
*address
) 
 366   assert(socket 
!= NULL
); 
 368   /* the socket must be initialized, or it must be a server */ 
 369   if ((socket
->m_endpoint 
!= kOTInvalidEndpointRef 
&& !socket
->m_server
)) 
 371     socket
->m_error 
= GSOCK_INVSOCK
; 
 372     return GSOCK_INVSOCK
; 
 376   if (address 
== NULL 
|| address
->m_family 
== GSOCK_NOFAMILY
) 
 378     socket
->m_error 
= GSOCK_INVADDR
; 
 379     return GSOCK_INVADDR
; 
 383     GAddress_destroy(socket
->m_local
); 
 385   socket
->m_local 
= GAddress_copy(address
); 
 387   return GSOCK_NOERROR
; 
 390 GSocketError 
GSocket_SetPeer(GSocket 
*socket
, GAddress 
*address
) 
 392   assert(socket 
!= NULL
); 
 395   if (address 
== NULL 
|| address
->m_family 
== GSOCK_NOFAMILY
) 
 397     socket
->m_error 
= GSOCK_INVADDR
; 
 398     return GSOCK_INVADDR
; 
 402     GAddress_destroy(socket
->m_peer
); 
 404   socket
->m_peer 
= GAddress_copy(address
); 
 406   return GSOCK_NOERROR
; 
 409 GAddress 
*GSocket_GetLocal(GSocket 
*socket
) 
 411   GAddress 
*address 
= NULL 
; 
 415   assert(socket 
!= NULL
); 
 417   /* try to get it from the m_local var first */ 
 419     return GAddress_copy(socket
->m_local
); 
 421   /* else, if the socket is initialized, try getsockname */ 
 422   if (socket
->m_endpoint 
== kOTInvalidEndpointRef
) 
 424     socket
->m_error 
= GSOCK_INVSOCK
; 
 429 /* we do not support multihoming with this code at the moment 
 430    OTGetProtAddress will have to be used then - but we don't have a handy  
 431    method to use right now 
 434     InetInterfaceInfo   info
; 
 435     OTInetGetInterfaceInfo(&info
, kDefaultInetInterface
); 
 436     loc
.fHost 
= info
.fAddress 
; 
 438         loc
.fAddressType 
= AF_INET 
; 
 441   /* got a valid address from getsockname, create a GAddress object */ 
 442   address 
= GAddress_new(); 
 445     socket
->m_error 
= GSOCK_MEMERR
; 
 449   err 
= _GAddress_translate_from(address
, &loc
); 
 450   if (err 
!= GSOCK_NOERROR
) 
 452     GAddress_destroy(address
); 
 453     socket
->m_error 
= err
; 
 460 GAddress 
*GSocket_GetPeer(GSocket 
*socket
) 
 462   assert(socket 
!= NULL
); 
 464   /* try to get it from the m_peer var */ 
 466     return GAddress_copy(socket
->m_peer
); 
 471 /* Server specific parts */ 
 473 /* GSocket_SetServer: 
 474  *  Sets up this socket as a server. The local address must have been 
 475  *  set with GSocket_SetLocal() before GSocket_SetServer() is called. 
 476  *  Returns GSOCK_NOERROR on success, one of the following otherwise: 
 479  *    GSOCK_INVSOCK - the socket is in use. 
 480  *    GSOCK_INVADDR - the local address has not been set. 
 481  *    GSOCK_IOERR   - low-level error.  
 483 GSocketError 
GSocket_SetServer(GSocket 
*sck
) 
 487   /* must not be in use */ 
 488   if (sck
->m_endpoint 
!= kOTInvalidEndpointRef 
) 
 490     sck
->m_error 
= GSOCK_INVSOCK
; 
 491     return GSOCK_INVSOCK
; 
 494   /* the local addr must have been set */ 
 497     sck
->m_error 
= GSOCK_INVADDR
; 
 498     return GSOCK_INVADDR
; 
 501   /* Initialize all fields */ 
 502   sck
->m_stream   
= TRUE
; 
 503   sck
->m_server   
= TRUE
; 
 504   sck
->m_oriented 
= TRUE
; 
 508   /* Create the socket */ 
 509   sck
->m_endpoint 
= socket(sck
->m_local
->m_realfamily
, SOCK_STREAM
, 0); 
 510   socket_set_ref( sck
->m_endpoint 
, (unsigned long) &gMacNetEvents 
,  (unsigned long) sck 
) ; 
 511   if (sck
->m_endpoint 
== kOTInvalidEndpointRef
) 
 513     sck
->m_error 
= GSOCK_IOERR
; 
 517   ioctl(sck
->m_endpoint
, FIONBIO
, &arg
); 
 518   _GSocket_Enable_Events(sck
); 
 520   /* Bind to the local address, 
 521    * retrieve the actual address bound, 
 522    * and listen up to 5 connections. 
 524   if ((bind(sck
->m_endpoint
, sck
->m_local
->m_addr
, sck
->m_local
->m_len
) != 0) || 
 525       (getsockname(sck
->m_endpoint
, 
 526                    sck
->m_local
->m_addr
, 
 527                    (SOCKLEN_T 
*) &sck
->m_local
->m_len
) != 0) || 
 528       (listen(sck
->m_endpoint
, 5) != 0)) 
 530     close(sck
->m_endpoint
); 
 531     sck
->m_endpoint 
= -1; 
 532     sck
->m_error 
= GSOCK_IOERR
; 
 536   return GSOCK_NOERROR
; 
 539 /* GSocket_WaitConnection: 
 540  *  Waits for an incoming client connection. Returns a pointer to 
 541  *  a GSocket object, or NULL if there was an error, in which case 
 542  *  the last error field will be updated for the calling GSocket. 
 544  *  Error codes (set in the calling GSocket) 
 545  *    GSOCK_INVSOCK    - the socket is not valid or not a server. 
 546  *    GSOCK_TIMEDOUT   - timeout, no incoming connections. 
 547  *    GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking. 
 548  *    GSOCK_MEMERR     - couldn't allocate memory. 
 549  *    GSOCK_IOERR      - low-level error.  
 551 GSocket 
*GSocket_WaitConnection(GSocket 
*socket
) 
 553   GSocket 
*connection 
= NULL 
; 
 555   assert(socket 
!= NULL
); 
 557   /* Reenable CONNECTION events */ 
 558   socket
->m_detected 
&= ~GSOCK_CONNECTION_FLAG
; 
 560   /* If the socket has already been created, we exit immediately */ 
 561   if (socket
->m_endpoint 
== kOTInvalidEndpointRef 
|| !socket
->m_server
) 
 563     socket
->m_error 
= GSOCK_INVSOCK
; 
 567   /* Create a GSocket object for the new connection */ 
 568   connection 
= GSocket_new(); 
 572     socket
->m_error 
= GSOCK_MEMERR
; 
 576   /* Wait for a connection (with timeout) */ 
 577   if (_GSocket_Input_Timeout(socket
) == GSOCK_TIMEDOUT
) 
 579     GSocket_destroy(connection
); 
 580     /* socket->m_error set by _GSocket_Input_Timeout */ 
 586   connection
->m_endpoint 
= accept(socket
->m_endpoint
, &from
, (SOCKLEN_T 
*) &fromlen
); 
 589   if (connection
->m_endpoint 
== kOTInvalidEndpointRef 
) 
 591     if (errno 
== EWOULDBLOCK
) 
 592       socket
->m_error 
= GSOCK_WOULDBLOCK
; 
 594       socket
->m_error 
= GSOCK_IOERR
; 
 596     GSocket_destroy(connection
); 
 600   /* Initialize all fields */ 
 601   connection
->m_server   
= FALSE
; 
 602   connection
->m_stream   
= TRUE
; 
 603   connection
->m_oriented 
= TRUE
; 
 605   /* Setup the peer address field */ 
 606   connection
->m_peer 
= GAddress_new(); 
 607   if (!connection
->m_peer
) 
 609     GSocket_destroy(connection
); 
 610     socket
->m_error 
= GSOCK_MEMERR
; 
 615   err 
= _GAddress_translate_from(connection
->m_peer
, &from
, fromlen
); 
 616   if (err 
!= GSOCK_NOERROR
) 
 618     GAddress_destroy(connection
->m_peer
); 
 619     GSocket_destroy(connection
); 
 620     socket
->m_error 
= err
; 
 624   ioctl(connection
->m_endpoint
, FIONBIO
, &arg
); 
 626   _GSocket_Enable_Events(connection
); 
 631 /* Datagram sockets */ 
 633 /* GSocket_SetNonOriented: 
 634  *  Sets up this socket as a non-connection oriented (datagram) socket. 
 635  *  Before using this function, the local address must have been set 
 636  *  with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR 
 637  *  on success, or one of the following otherwise. 
 640  *    GSOCK_INVSOCK - the socket is in use. 
 641  *    GSOCK_INVADDR - the local address has not been set. 
 642  *    GSOCK_IOERR   - low-level error. 
 644 GSocketError 
GSocket_SetNonOriented(GSocket 
*sck
) 
 648   if (sck
->m_endpoint 
!= kOTInvalidEndpointRef 
) 
 650     sck
->m_error 
= GSOCK_INVSOCK
; 
 651     return GSOCK_INVSOCK
; 
 656     sck
->m_error 
= GSOCK_INVADDR
; 
 657     return GSOCK_INVADDR
; 
 660   /* Initialize all fields */ 
 661   sck
->m_stream   
= FALSE
; 
 662   sck
->m_server   
= FALSE
; 
 663   sck
->m_oriented 
= FALSE
; 
 665   /* Create the socket */ 
 669   sck
->m_endpoint 
= socket(sck
->m_local
->m_realfamily
, SOCK_DGRAM
, 0); 
 670   socket_set_ref( sck
->m_endpoint 
, (unsigned long) &gMacNetEvents 
,  (unsigned long) sck 
) ; 
 672   if (sck
->m_endpoint 
== kOTInvalidEndpointRef 
) 
 674     sck
->m_error 
= GSOCK_IOERR
; 
 680   ioctl(sck
->m_endpoint
, FIONBIO
, &arg
); 
 682   _GSocket_Enable_Events(sck
); 
 684   /* Bind to the local address, 
 685    * and retrieve the actual address bound. 
 689   if ((bind(sck
->m_endpoint
, sck
->m_local
->m_addr
, sck
->m_local
->m_len
) != 0) || 
 690       (getsockname(sck
->m_endpoint
, 
 691                    sck
->m_local
->m_addr
, 
 692                    (SOCKLEN_T 
*) &sck
->m_local
->m_len
) != 0)) 
 694     close(sck
->m_endpoint
); 
 695     sck
->m_endpoint    
= -1; 
 696     sck
->m_error 
= GSOCK_IOERR
; 
 700   return GSOCK_NOERROR
; 
 703 /* Client specific parts */ 
 706  *  For stream (connection oriented) sockets, GSocket_Connect() tries 
 707  *  to establish a client connection to a server using the peer address 
 708  *  as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the 
 709  *  connection has been succesfully established, or one of the error 
 710  *  codes listed below. Note that for nonblocking sockets, a return 
 711  *  value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection 
 712  *  request can be completed later; you should use GSocket_Select() 
 713  *  to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the 
 714  *  corresponding asynchronous events. 
 716  *  For datagram (non connection oriented) sockets, GSocket_Connect() 
 717  *  just sets the peer address established with GSocket_SetPeer() as 
 718  *  default destination. 
 721  *    GSOCK_INVSOCK    - the socket is in use or not valid. 
 722  *    GSOCK_INVADDR    - the peer address has not been established. 
 723  *    GSOCK_TIMEDOUT   - timeout, the connection failed. 
 724  *    GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only) 
 725  *    GSOCK_MEMERR     - couldn't allocate memory. 
 726  *    GSOCK_IOERR      - low-level error.  
 728 GSocketError 
GSocket_Connect(GSocket 
*sck
, GSocketStream stream
) 
 732    OSStatus             err 
= kOTNoError
; 
 737   /* Enable CONNECTION events (needed for nonblocking connections) */ 
 738   sck
->m_detected 
&= ~GSOCK_CONNECTION_FLAG
; 
 740   if (sck
->m_endpoint 
!= kOTInvalidEndpointRef 
) 
 742     sck
->m_error 
= GSOCK_INVSOCK
; 
 743     return GSOCK_INVSOCK
; 
 748     sck
->m_error 
= GSOCK_INVADDR
; 
 749     return GSOCK_INVADDR
; 
 752   /* Streamed or dgram socket? */ 
 753   sck
->m_stream   
= (stream 
== GSOCK_STREAMED
); 
 754   sck
->m_oriented 
= TRUE
; 
 755   sck
->m_server   
= FALSE
; 
 757   /* Create the socket */ 
 760         OTOpenEndpointInContext( OTCreateConfiguration( kTCPName
) , 0 , &info 
, &err 
, NULL 
) ; 
 763         OTOpenEndpoint( OTCreateConfiguration( kTCPName
) , 0 , &info 
, &err 
) ; 
 765   if ( sck
->m_endpoint 
== kOTInvalidEndpointRef 
|| err 
!= kOTNoError 
) 
 767                 sck
->m_endpoint 
= kOTInvalidEndpointRef 
; 
 768         sck
->m_error 
= GSOCK_IOERR
; 
 771   err 
= OTBind( sck
->m_endpoint 
, nil 
, nil 
) ; 
 772   if ( err 
!= kOTNoError 
) 
 776   SetDefaultEndpointModes( sck
->m_endpoint 
, sck 
) ; 
 779   ioctl(sck
->m_endpoint
, FIONBIO
, &arg
); 
 781   _GSocket_Enable_Events(sck
); 
 783   _GAddress_translate_to( sck
->m_peer 
, &addr 
) ; 
 784   memset( &peer 
, 0 , sizeof( TCall 
) ) ; 
 785   peer
.addr
.len 
= sizeof( InetAddress 
) ; 
 786   peer
.addr
.buf 
= (unsigned char*) &addr 
; 
 787   err 
= OTConnect( sck
->m_endpoint 
, &peer 
, nil 
) ; 
 790     /* If connect failed with EINPROGRESS and the GSocket object 
 791      * is in blocking mode, we select() for the specified timeout 
 792      * checking for writability to see if the connection request 
 796     if ((err 
== kOTNoDataErr 
) && (!sck
->m_non_blocking
)) 
 798       if (_GSocket_Output_Timeout(sck
) == GSOCK_TIMEDOUT
) 
 800         OTSndOrderlyDisconnect( sck
->m_endpoint 
) ; 
 801         sck
->m_endpoint 
= kOTInvalidEndpointRef 
; 
 802         /* sck->m_error is set in _GSocket_Output_Timeout */ 
 803         return GSOCK_TIMEDOUT
; 
 809         SOCKLEN_T len = sizeof(error); 
 811         getsockopt(sck->m_endpoint, SOL_SOCKET, SO_ERROR, (void*) &error, &len); 
 815           return GSOCK_NOERROR
; 
 819     /* If connect failed with EINPROGRESS and the GSocket object 
 820      * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK 
 821      * (and return GSOCK_WOULDBLOCK) but we don't close the socket; 
 822      * this way if the connection completes, a GSOCK_CONNECTION 
 823      * event will be generated, if enabled. 
 825     if ((err 
== kOTNoDataErr
) && (sck
->m_non_blocking
)) 
 827       sck
->m_error 
= GSOCK_WOULDBLOCK
; 
 828       return GSOCK_WOULDBLOCK
; 
 831     /* If connect failed with an error other than EINPROGRESS, 
 832      * then the call to GSocket_Connect has failed. 
 834     OTSndOrderlyDisconnect( sck
->m_endpoint 
) ; 
 836     sck
->m_endpoint 
= kOTInvalidEndpointRef 
; 
 837     sck
->m_error 
= GSOCK_IOERR
; 
 840 //  OTInetEventHandler(sck, T_CONNECT , kOTNoError , NULL ) ; 
 841   return GSOCK_NOERROR
; 
 846 /* Like recv(), send(), ... */ 
 847 int GSocket_Read(GSocket 
*socket
, char *buffer
, int size
) 
 851   assert(socket 
!= NULL
); 
 853   /* Reenable INPUT events */ 
 854   socket
->m_detected 
&= ~GSOCK_INPUT_FLAG
; 
 856   if (socket
->m_endpoint 
== kOTInvalidEndpointRef 
|| socket
->m_server
) 
 858     socket
->m_error 
= GSOCK_INVSOCK
; 
 862   /* If the socket is blocking, wait for data (with a timeout) */ 
 863   if (_GSocket_Input_Timeout(socket
) == GSOCK_TIMEDOUT
) 
 867   if (socket
->m_stream
) 
 868     ret 
= _GSocket_Recv_Stream(socket
, buffer
, size
); 
 870     ret 
= _GSocket_Recv_Dgram(socket
, buffer
, size
); 
 874     if (errno 
== EWOULDBLOCK
) 
 875       socket
->m_error 
= GSOCK_WOULDBLOCK
; 
 877       socket
->m_error 
= GSOCK_IOERR
; 
 883 int GSocket_Write(GSocket 
*socket
, const char *buffer
, int size
) 
 887   assert(socket 
!= NULL
); 
 889   if (socket
->m_endpoint 
== kOTInvalidEndpointRef 
|| socket
->m_server
) 
 891     socket
->m_error 
= GSOCK_INVSOCK
; 
 895   /* If the socket is blocking, wait for writability (with a timeout) */ 
 896   if (_GSocket_Output_Timeout(socket
) == GSOCK_TIMEDOUT
) 
 900   if (socket
->m_stream
) 
 901     ret 
= _GSocket_Send_Stream(socket
, buffer
, size
); 
 903     ret 
= _GSocket_Send_Dgram(socket
, buffer
, size
); 
 907     if (errno 
== EWOULDBLOCK
) 
 908       socket
->m_error 
= GSOCK_WOULDBLOCK
; 
 910       socket
->m_error 
= GSOCK_IOERR
; 
 912     /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect 
 913      * in MSW). Once the first OUTPUT event is received, users can assume 
 914      * that the socket is writable until a read operation fails. Only then 
 915      * will further OUTPUT events be posted. 
 917     socket
->m_detected 
&= ~GSOCK_OUTPUT_FLAG
; 
 925  *  Polls the socket to determine its status. This function will 
 926  *  check for the events specified in the 'flags' parameter, and 
 927  *  it will return a mask indicating which operations can be 
 928  *  performed. This function won't block, regardless of the 
 929  *  mode (blocking | nonblocking) of the socket. 
 931 GSocketEventFlags 
GSocket_Select(GSocket 
*socket
, GSocketEventFlags flags
) 
 933   assert(socket 
!= NULL
); 
 934   wxMacProcessNotifierEvents() ; 
 936   state = OTGetEndpointState(socket->m_endpoint); 
 938   if ( ( flags & GSOCK_INPUT_FLAG ) && ! ( socket->m_detected & GSOCK_INPUT_FLAG ) ) 
 941         OTCountDataBytes( socket->m_endpoint , &sz ) ; 
 942         if ( state == T_INCON || sz > 0 ) 
 944         socket->m_detected |= GSOCK_INPUT_FLAG ; 
 945                 (socket->m_cbacks[GSOCK_INPUT])(socket, GSOCK_INPUT, socket->m_data[GSOCK_INPUT]); 
 948   if ( ( flags & GSOCK_INPUT_FLAG ) && ! ( socket->m_detected & GSOCK_OUTPUT_FLAG ) ) 
 950         if ( state == T_DATAXFER || state == T_INREL ) 
 952         socket->m_detected |=GSOCK_OUTPUT_FLAG ; 
 953                 (socket->m_cbacks[GSOCK_OUTPUT])(socket, GSOCK_OUTPUT, socket->m_data[GSOCK_OUTPUT]); 
 957   return ( flags 
& socket
->m_detected 
) ; 
 962 /* GSocket_SetNonBlocking: 
 963  *  Sets the socket to non-blocking mode. All IO calls will return 
 966 void GSocket_SetNonBlocking(GSocket 
*socket
, int non_block
) 
 968   assert(socket 
!= NULL
); 
 970   socket
->m_non_blocking 
= non_block
; 
 973 /* GSocket_SetTimeout: 
 974  *  Sets the timeout for blocking calls. Time is expressed in 
 977 void GSocket_SetTimeout(GSocket 
*socket
, unsigned long millisec
) 
 979   assert(socket 
!= NULL
); 
 981 //  this is usually set too high and we have not yet been able to detect a closed 
 982 //  stream, thus we leave the 10 sec timeout 
 983 //  socket->m_timeout = millisec; 
 987  *  Returns the last error occured for this socket. Note that successful 
 988  *  operations do not clear this back to GSOCK_NOERROR, so use it only 
 991 GSocketError 
GSocket_GetError(GSocket 
*socket
) 
 993   assert(socket 
!= NULL
); 
 995   return socket
->m_error
; 
1001  *   There is data to be read in the input buffer. If, after a read 
1002  *   operation, there is still data available, the callback function will 
1005  *   The socket is available for writing. That is, the next write call  
1006  *   won't block. This event is generated only once, when the connection is 
1007  *   first established, and then only if a call failed with GSOCK_WOULDBLOCK, 
1008  *   when the output buffer empties again. This means that the app should 
1009  *   assume that it can write since the first OUTPUT event, and no more 
1010  *   OUTPUT events will be generated unless an error occurs. 
1012  *   Connection succesfully established, for client sockets, or incoming 
1013  *   client connection, for server sockets. Wait for this event (also watch 
1014  *   out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call. 
1016  *   The connection is lost (or a connection request failed); this could 
1017  *   be due to a failure, or due to the peer closing it gracefully. 
1020 /* GSocket_SetCallback: 
1021  *  Enables the callbacks specified by 'flags'. Note that 'flags' 
1022  *  may be a combination of flags OR'ed toghether, so the same 
1023  *  callback function can be made to accept different events. 
1024  *  The callback function must have the following prototype: 
1026  *  void function(GSocket *socket, GSocketEvent event, char *cdata) 
1028 void GSocket_SetCallback(GSocket 
*socket
, GSocketEventFlags flags
, 
1029                          GSocketCallback callback
, char *cdata
) 
1033   assert(socket 
!= NULL
); 
1035   for (count 
= 0; count 
< GSOCK_MAX_EVENT
; count
++) 
1037     if ((flags 
& (1 << count
)) != 0) 
1039       socket
->m_cbacks
[count
] = callback
; 
1040       socket
->m_data
[count
] = cdata
; 
1045 /* GSocket_UnsetCallback: 
1046  *  Disables all callbacks specified by 'flags', which may be a 
1047  *  combination of flags OR'ed toghether. 
1049 void GSocket_UnsetCallback(GSocket 
*socket
, GSocketEventFlags flags
) 
1053   assert(socket 
!= NULL
); 
1055   for (count 
= 0; count 
< GSOCK_MAX_EVENT
; count
++) 
1057     if ((flags 
& (1 << count
)) != 0) 
1059       socket
->m_cbacks
[count
] = NULL
; 
1060       socket
->m_data
[count
] = NULL
; 
1066 #define CALL_CALLBACK(socket, event) {                                  \ 
1067   _GSocket_Disable(socket, event);                                      \ 
1068   if (socket->m_cbacks[event])                                          \ 
1069     socket->m_cbacks[event](socket, event, socket->m_data[event]);      \ 
1072 int _GSocket_Recv_Stream(GSocket 
*socket
, char *buffer
, int size
) 
1076         OTByteCount sz 
= 0 ; 
1078         OTCountDataBytes( socket
->m_endpoint 
, &sz 
) ; 
1079         if ( size 
> (int)sz 
) 
1081         res 
= OTRcv( socket
->m_endpoint 
, buffer 
, size 
, &flags 
) ; 
1087         // we simulate another read event if there are still bytes 
1088         if ( socket
->m_takesEvents 
) 
1090                 OTByteCount sz 
= 0 ; 
1091                 OTCountDataBytes( socket
->m_endpoint 
, &sz 
) ; 
1094                 socket
->m_detected 
|= GSOCK_INPUT_FLAG 
; 
1095                         (socket
->m_cbacks
[GSOCK_INPUT
])(socket
, GSOCK_INPUT
, socket
->m_data
[GSOCK_INPUT
]); 
1101 int _GSocket_Recv_Dgram(GSocket 
*socket
, char *buffer
, int size
) 
1106   struct sockaddr from
; 
1107   SOCKLEN_T fromlen 
= sizeof(from
); 
1110   fromlen 
= sizeof(from
); 
1112   ret 
= recvfrom(socket
->m_endpoint
, buffer
, size
, 0, &from
, (SOCKLEN_T 
*) &fromlen
); 
1117   /* Translate a system address into a GSocket address */ 
1118   if (!socket
->m_peer
) 
1120     socket
->m_peer 
= GAddress_new(); 
1121     if (!socket
->m_peer
) 
1123       socket
->m_error 
= GSOCK_MEMERR
; 
1127   err 
= _GAddress_translate_from(socket
->m_peer
, &from
, fromlen
); 
1128   if (err 
!= GSOCK_NOERROR
) 
1130     GAddress_destroy(socket
->m_peer
); 
1131     socket
->m_peer  
= NULL
; 
1132     socket
->m_error 
= err
; 
1139 int _GSocket_Send_Stream(GSocket 
*socket
, const char *buffer
, int size
) 
1144         res 
= OTSnd( socket
->m_endpoint 
, (void*) buffer 
, size 
, flags 
) ; 
1148 int _GSocket_Send_Dgram(GSocket 
*socket
, const char *buffer
, int size
) 
1153   struct sockaddr 
*addr
; 
1157   if (!socket
->m_peer
) 
1159     socket
->m_error 
= GSOCK_INVADDR
; 
1163   err 
= _GAddress_translate_to(socket
->m_peer
, &addr
, &len
); 
1164   if (err 
!= GSOCK_NOERROR
) 
1166     socket
->m_error 
= err
; 
1170   ret 
= sendto(socket
->m_endpoint
, buffer
, size
, 0, addr
, len
); 
1172   /* Frees memory allocated from _GAddress_translate_to */ 
1180  * ------------------------------------------------------------------------- 
1182  * ------------------------------------------------------------------------- 
1185 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY 
1186  * or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address 
1187  * to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR. 
1189 #define CHECK_ADDRESS(address, family, retval)                      \ 
1191   if (address->m_family == GSOCK_NOFAMILY)                          \ 
1192     if (_GAddress_Init_##family(address) != GSOCK_NOERROR)          \ 
1193       return address->m_error;                                      \ 
1194   if (address->m_family != GSOCK_##family)                          \ 
1196     address->m_error = GSOCK_INVADDR;                               \ 
1201 GAddress 
*GAddress_new() 
1205   if ((address 
= (GAddress 
*) malloc(sizeof(GAddress
))) == NULL
) 
1208   address
->m_family  
= GSOCK_NOFAMILY
; 
1209   address
->m_host 
= INADDR_NONE 
; 
1210   address
->m_port 
= 0 ; 
1215 GAddress 
*GAddress_copy(GAddress 
*address
) 
1219   assert(address 
!= NULL
); 
1221   if ((addr2 
= (GAddress 
*) malloc(sizeof(GAddress
))) == NULL
) 
1224   memcpy(addr2
, address
, sizeof(GAddress
)); 
1228 void GAddress_destroy(GAddress 
*address
) 
1230   assert(address 
!= NULL
); 
1235 void GAddress_SetFamily(GAddress 
*address
, GAddressType type
) 
1237   assert(address 
!= NULL
); 
1239   address
->m_family 
= type
; 
1242 GAddressType 
GAddress_GetFamily(GAddress 
*address
) 
1244   assert(address 
!= NULL
); 
1246   return address
->m_family
; 
1249 GSocketError 
_GAddress_translate_from(GAddress 
*address
, 
1252   switch (addr
->fAddressType
) 
1255       address
->m_family 
= GSOCK_INET
; 
1259       address
->m_family 
= GSOCK_INET6
; 
1264       address
->m_error 
= GSOCK_INVOP
; 
1268   address
->m_host 
= addr
->fHost 
; 
1269   address
->m_port 
= addr
->fPort 
; 
1270   return GSOCK_NOERROR
; 
1273 GSocketError 
_GAddress_translate_to(GAddress 
*address
, 
1276  if ( GSocket_Verify_Inited() == FALSE 
) 
1277     return GSOCK_IOERR 
; 
1278   memset(addr
, 0 , sizeof(struct InetAddress
)); 
1279   OTInitInetAddress( addr 
, address
->m_port 
, address
->m_host 
) ; 
1280   return GSOCK_NOERROR
; 
1284  * ------------------------------------------------------------------------- 
1285  * Internet address family 
1286  * ------------------------------------------------------------------------- 
1289 GSocketError 
_GAddress_Init_INET(GAddress 
*address
) 
1291   address
->m_family 
= GSOCK_INET
; 
1292   address
->m_host 
= kOTAnyInetAddress 
; 
1294   return GSOCK_NOERROR
; 
1297 GSocketError 
GAddress_INET_SetHostName(GAddress 
*address
, const char *hostname
) 
1299   InetHostInfo hinfo 
; 
1302  if ( GSocket_Verify_Inited() == FALSE 
) 
1303     return GSOCK_IOERR 
; 
1305   assert(address 
!= NULL
); 
1307   CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
); 
1308   ret 
= OTInetStringToAddress( gInetSvcRef 
, (char*) hostname 
, &hinfo 
) ; 
1309   if ( ret 
!= kOTNoError 
) 
1311         address
->m_host 
= INADDR_NONE 
; 
1312     address
->m_error 
= GSOCK_NOHOST
; 
1313     return GSOCK_NOHOST
; 
1315   address
->m_host 
= hinfo
.addrs
[0] ; 
1316   return GSOCK_NOERROR
; 
1319 GSocketError 
GAddress_INET_SetAnyAddress(GAddress 
*address
) 
1321   return GAddress_INET_SetHostAddress(address
, INADDR_ANY
); 
1324 GSocketError 
GAddress_INET_SetHostAddress(GAddress 
*address
, 
1325                                           unsigned long hostaddr
) 
1327   assert(address 
!= NULL
); 
1329   CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
); 
1331   address
->m_host 
= hostaddr 
; 
1333   return GSOCK_NOERROR
; 
1336 struct service_entry 
 
1339         unsigned short port 
; 
1342 typedef struct service_entry service_entry 
; 
1344 service_entry gServices
[] = 
1346         { "http" , 80 , "tcp" }  
1349 GSocketError 
GAddress_INET_SetPortName(GAddress 
*address
, const char *port
, 
1350                                        const char *protocol
) 
1354   assert(address 
!= NULL
); 
1355   CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
); 
1359     address
->m_error 
= GSOCK_INVPORT
; 
1360     return GSOCK_INVPORT
; 
1362   for ( i 
= 0 ; i 
< sizeof( gServices
) / sizeof( service_entry 
) ; ++i 
) 
1364         if ( strcmp( port 
, gServices
[i
].name 
) == 0 ) 
1366                 if ( protocol 
== NULL 
|| strcmp( protocol 
, gServices
[i
].protocol 
) ) 
1368                         address
->m_port 
= gServices
[i
].port 
; 
1369                 return GSOCK_NOERROR
; 
1374   if (isdigit(port
[0])) 
1376      address
->m_port 
= atoi(port
); 
1377      return GSOCK_NOERROR
; 
1380   address
->m_error 
= GSOCK_INVPORT
; 
1381   return GSOCK_INVPORT
; 
1384 GSocketError 
GAddress_INET_SetPort(GAddress 
*address
, unsigned short port
) 
1386   assert(address 
!= NULL
); 
1387   CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
); 
1388   address
->m_port 
= port 
; 
1390   return GSOCK_NOERROR
; 
1393 GSocketError 
GAddress_INET_GetHostName(GAddress 
*address
, char *hostname
, size_t sbuf
) 
1395   InetDomainName name 
; 
1396  if ( GSocket_Verify_Inited() == FALSE 
) 
1397     return GSOCK_IOERR 
; 
1399   assert(address 
!= NULL
);  
1400   CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
); 
1402   OTInetAddressToName( gInetSvcRef 
, address
->m_host 
, name 
) ; 
1403   strncpy( hostname 
, name 
, sbuf 
) ; 
1404   return GSOCK_NOERROR
; 
1407 unsigned long GAddress_INET_GetHostAddress(GAddress 
*address
) 
1409   assert(address 
!= NULL
);  
1410   CHECK_ADDRESS(address
, INET
, 0);  
1412   return address
->m_host
; 
1415 unsigned short GAddress_INET_GetPort(GAddress 
*address
) 
1417   assert(address 
!= NULL
);  
1418   CHECK_ADDRESS(address
, INET
, 0);  
1420   return address
->m_port
; 
1423 void _GSocket_Enable_Events(GSocket 
*socket
) 
1425   if ( socket
->m_takesEvents 
) 
1430           socket
->m_takesEvents                 
= TRUE 
; 
1431           state 
= OTGetEndpointState(socket
->m_endpoint
); 
1434                 OTByteCount sz 
= 0 ; 
1435                 OTCountDataBytes( socket
->m_endpoint 
, &sz 
) ; 
1436                 if ( state 
== T_INCON 
|| sz 
> 0 ) 
1438                 socket
->m_detected 
|= GSOCK_INPUT_FLAG 
; 
1439                         (socket
->m_cbacks
[GSOCK_INPUT
])(socket
, GSOCK_INPUT
, socket
->m_data
[GSOCK_INPUT
]); 
1443                 if ( state 
== T_DATAXFER 
|| state 
== T_INREL 
) 
1445                 socket
->m_detected 
|=GSOCK_OUTPUT_FLAG 
; 
1446                         (socket
->m_cbacks
[GSOCK_OUTPUT
])(socket
, GSOCK_OUTPUT
, socket
->m_data
[GSOCK_OUTPUT
]); 
1452 void _GSocket_Disable_Events(GSocket 
*socket
) 
1454   socket
->m_takesEvents                 
= FALSE 
; 
1457 /* _GSocket_Input_Timeout: 
1458  *  For blocking sockets, wait until data is available or 
1459  *  until timeout ellapses. 
1461 GSocketError 
_GSocket_Input_Timeout(GSocket 
*socket
) 
1463   if ( !socket
->m_non_blocking 
) 
1465     UnsignedWide now 
, start 
; 
1466     short formerTakesEvents 
= socket
->m_takesEvents 
; 
1467     Microseconds(&start
); 
1469     socket
->m_takesEvents 
= FALSE 
; 
1471     while( (now
.hi 
* 4294967296.0 + now
.lo
) - (start
.hi 
* 4294967296.0 + start
.lo
) < socket
->m_timeout 
* 1000.0 ) 
1474                 OTByteCount sz 
= 0 ; 
1475                   state 
= OTGetEndpointState(socket
->m_endpoint
); 
1477                 OTCountDataBytes( socket
->m_endpoint 
, &sz 
) ; 
1478                 if ( state 
== T_INCON 
|| sz 
> 0 ) 
1480                 socket
->m_takesEvents 
= formerTakesEvents 
; 
1481                         return GSOCK_NOERROR
; 
1485     socket
->m_takesEvents 
= formerTakesEvents 
; 
1486     socket
->m_error 
= GSOCK_TIMEDOUT
; 
1487     return GSOCK_TIMEDOUT
; 
1489   return GSOCK_NOERROR
; 
1492 /* _GSocket_Output_Timeout: 
1493  *  For blocking sockets, wait until data can be sent without 
1494  *  blocking or until timeout ellapses. 
1496 GSocketError 
_GSocket_Output_Timeout(GSocket 
*socket
) 
1498   if ( !socket
->m_non_blocking 
) 
1500     UnsignedWide now 
, start 
; 
1501     short formerTakesEvents 
= socket
->m_takesEvents 
; 
1502     Microseconds(&start
); 
1504     socket
->m_takesEvents 
= FALSE 
; 
1506     while( (now
.hi 
* 4294967296.0 + now
.lo
) - (start
.hi 
* 4294967296.0 + start
.lo
) < socket
->m_timeout 
* 1000.0 ) 
1509                 state 
= OTGetEndpointState(socket
->m_endpoint
); 
1511                 if ( state 
== T_DATAXFER 
|| state 
== T_INREL 
) 
1513                 socket
->m_takesEvents 
= formerTakesEvents 
; 
1514                         return GSOCK_NOERROR
; 
1518     socket
->m_takesEvents 
= formerTakesEvents 
; 
1519     socket
->m_error 
= GSOCK_TIMEDOUT
; 
1520     return GSOCK_TIMEDOUT
; 
1522   return GSOCK_NOERROR
; 
1526  *   There is data to be read in the input buffer. If, after a read 
1527  *   operation, there is still data available, the callback function will 
1530  *   The socket is available for writing. That is, the next write call  
1531  *   won't block. This event is generated only once, when the connection is 
1532  *   first established, and then only if a call failed with GSOCK_WOULDBLOCK, 
1533  *   when the output buffer empties again. This means that the app should 
1534  *   assume that it can write since the first OUTPUT event, and no more 
1535  *   OUTPUT events will be generated unless an error occurs. 
1537  *   Connection succesfully established, for client sockets, or incoming 
1538  *   client connection, for server sockets. Wait for this event (also watch 
1539  *   out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call. 
1541  *   The connection is lost (or a connection request failed); this could 
1542  *   be due to a failure, or due to the peer closing it gracefully. 
1545 void _GSocket_Internal_Proc(unsigned long e 
, void* d 
) 
1548   GSocket 
* socket 
= (GSocket
*) d 
; 
1549   OTEventCode ev 
= (OTEventCode
) e 
; 
1551   GSocketEvent event2
; 
1552   GSocketCallback cback
; 
1554   GSocketCallback cback2
; 
1559     event 
= GSOCK_MAX_EVENT 
; 
1560     event2 
= GSOCK_MAX_EVENT 
; 
1566     /* Check that the socket still exists (it has not been 
1567      * destroyed) and for safety, check that the m_endpoint field 
1568      * is what we expect it to be. 
1570     if ((socket 
!= NULL
) && (socket
->m_takesEvents
)) 
1575                         event 
= GSOCK_CONNECTION 
; 
1578                         event 
= GSOCK_CONNECTION 
; 
1579                         event2 
= GSOCK_OUTPUT 
; 
1583                                         retCall
.addr
.buf        
= NULL
; 
1584                                         retCall
.addr
.maxlen     
= 0; 
1585                                         retCall
.opt
.buf         
= NULL
; 
1586                                         retCall
.opt
.maxlen      
= 0; 
1587                                         retCall
.udata
.buf       
= NULL
; 
1588                                         retCall
.udata
.maxlen
= 0; 
1589                                         OTRcvConnect( socket
->m_endpoint 
, &retCall 
) ; 
1593                         event 
= GSOCK_LOST 
; 
1597                         event 
= GSOCK_OUTPUT 
; 
1600                         event 
= GSOCK_INPUT 
; 
1603                         event 
= GSOCK_INPUT 
; 
1606       if (event 
!= GSOCK_MAX_EVENT
) 
1608         cback 
= socket
->m_cbacks
[event
]; 
1609         data 
= socket
->m_data
[event
]; 
1611         if (event 
== GSOCK_LOST
) 
1612           socket
->m_detected 
= GSOCK_LOST_FLAG
; 
1614           socket
->m_detected 
|= (1 << event
); 
1616       if (event2 
!= GSOCK_MAX_EVENT
) 
1618         cback2 
= socket
->m_cbacks
[event2
]; 
1619         data2 
= socket
->m_data
[event2
]; 
1621         if (event2 
== GSOCK_LOST
) 
1622           socket
->m_detected 
= GSOCK_LOST_FLAG
; 
1624           socket
->m_detected 
|= (1 << event2
); 
1628     /* OK, we can now leave the critical section because we have 
1629      * already obtained the callback address (we make no further 
1630      * accesses to socket->whatever). However, the app should 
1631      * be prepared to handle events from a socket that has just 
1636       (cback
)(socket
, event
, data
); 
1638       (cback2
)(socket
, event2
, data2
); 
1642 /* Hack added for Mac OS X */ 
1643 GSocketError 
GAddress_UNIX_GetPath(GAddress 
*addr
, char *path
, size_t buf
) 
1645     return GSOCK_INVADDR
; 
1648 GSocketError 
GAddress_UNIX_SetPath(GAddress 
*addr
, const char *path
) 
1650     return GSOCK_INVADDR
; 
1653 #endif  /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */