1 //////////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:    Socket handler classes 
   4 // Authors:    Guilhem Lavaux (completely rewritten from a basic API of Andrew 
   5 //             Davidson(1995) in wxWeb) 
   8 // Copyright:  (C) 1998, 1997, Guilhem Lavaux 
  10 // License:    see wxWindows license 
  11 //////////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "socket.h" 
  17 typedef int socklen_t 
; 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  29 ///////////////////////////////////////////////////////////////////////////// 
  31 ///////////////////////////////////////////////////////////////////////////// 
  33 #include <wx/object.h> 
  34 #include <wx/string.h> 
  38 // Not enough OS behaviour defined for wxStubs 
  45 ///////////////////////////////////////////////////////////////////////////// 
  46 // System specific headers 
  47 ///////////////////////////////////////////////////////////////////////////// 
  49 // in order to avoid problems with our c library and double definitions 
  50 #define close closesocket 
  51 #define ioctl ioctlsocket 
  53 #include <wx/mac/macsock.h> 
  54 extern GUSISpinFn GUSISpin
; 
  55 #define PROCESS_EVENTS() wxMacProcessEvents() 
  56 const short kwxMacNetEventsMax 
= 1000 ; 
  57 short wxMacNetEventsTop 
= 0 ; 
  58 short wxMacNetEventsBottom 
= 0 ; 
  59 short wxMacNetEventsEvents
[kwxMacNetEventsMax
] ; 
  60 void *wxMacNetEventsReferences
[kwxMacNetEventsMax
] ; 
  69 extern "C" void wxMacSocketHandlerProc( void *refcon 
, short event 
) ; // adds events 
  70 extern "C" void wxMacSocketOnRequestProc( void *refcon 
, short event 
) ; // consumes them 
  71 extern "C" void GUSISetReference( short sock 
, short eventmask 
, void * data 
) ; 
  72 void wxMacProcessEvents() ; 
  75 #if defined(__WINDOWS__) 
  84     #include <sys/socket.h> 
  87 #include <sys/ioctl.h> 
  93     #include <sys/filio.h> 
 105 #if defined(__WXMOTIF__) || defined(__WXXT__) 
 106     #include <X11/Intrinsic.h> 
 108     ///////////////////////////// 
 109     // Needs internal variables 
 110     ///////////////////////////// 
 112         #define Uses_XtIntrinsic 
 114 #endif // Motif or Xt 
 116 #if defined(__WXGTK__) 
 120 ///////////////////////////////////////////////////////////////////////////// 
 122 ///////////////////////////////////////////////////////////////////////////// 
 123 #include "wx/module.h" 
 125 #define WXSOCK_INTERNAL 
 127 #include "wx/sckaddr.h" 
 128 #include "wx/socket.h" 
 130 ///////////////////////////////////////////////////////////////////////////// 
 131 // Some patch ///// BEGIN 
 132 ///////////////////////////////////////////////////////////////////////////// 
 134 #define close closesocket 
 135 #define ioctl ioctlsocket 
 139 #define errno WSAGetLastError() 
 143 #define EWOULDBLOCK WSAEWOULDBLOCK 
 144 #define ETIMEDOUT WSAETIMEDOUT 
 146 #define EINTR WSAEINTR 
 150 #define INVALID_SOCKET -1 
 154 #define wxAPP_CONTEXT ((XtAppContext)wxTheApp->GetAppContext()) 
 158 // This is an MS TCP/IP routine and is not needed here. Some WinSock 
 159 // implementations (such as PC-NFS) will require you to include this 
 160 // or a similar routine (see appendix in WinSock doc or help file). 
 162 #if defined( NEED_WSAFDIsSet ) || defined( __VISUALC__ ) 
 163 int PASCAL FAR 
__WSAFDIsSet(SOCKET fd
, fd_set FAR 
*set
) 
 165   int i 
= set
->fd_count
; 
 169     if (set
->fd_array
[i
] == fd
) 
 178 #if defined(__WINDOWS__) 
 179     #define PROCESS_EVENTS() wxYield() 
 180 #elif defined(__WXXT__) || defined(__WXMOTIF__) 
 181     #define PROCESS_EVENTS() XtAppProcessEvent(wxAPP_CONTEXT, XtIMAll) 
 182 #elif defined(__WXGTK__) 
 183     #define PROCESS_EVENTS() gtk_main_iteration() 
 186 ///////////////////////////////////////////////////////////////////////////// 
 187 // Some patch ///// END 
 188 ///////////////////////////////////////////////////////////////////////////// 
 194 // -------------------------------------------------------------- 
 196 // -------------------------------------------------------------- 
 197 class wxSocketModule
: public wxModule 
 
 199   DECLARE_DYNAMIC_CLASS(wxSocketModule
) 
 206 // -------------------------------------------------------------- 
 208 // -------------------------------------------------------------- 
 209 #if !USE_SHARED_LIBRARY 
 210     IMPLEMENT_CLASS(wxSocketBase
, wxObject
) 
 211     IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
) 
 212     IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
) 
 213     IMPLEMENT_CLASS(wxSocketHandler
, wxObject
) 
 214     IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
) 
 215     IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
) 
 218 class wxSockWakeUp 
: public wxTimer 
 
 225   wxSockWakeUp(wxSocketBase 
*_sock
, int *id
, int new_val
)  
 227     my_id 
= id
; n_val 
= new_val
; 
 230   virtual void Notify()  
 233     if (sock
) sock
->Notify(FALSE
); 
 238 class SockRequest 
: public wxObject 
 
 245   wxSockWakeUp 
*auto_wakeup
; 
 246   wxSocketBase::wxRequestNotify type
; 
 250 ///////////////////////////////////////////////////////////////////////////// 
 251 // Some internal define 
 252 ///////////////////////////////////////////////////////////////////////////// 
 254 // -------------------------------------------------------------- 
 255 // --------- wxSocketBase CONSTRUCTOR --------------------------- 
 256 // -------------------------------------------------------------- 
 257 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags
, 
 258          wxSocketBase::wxSockType _type
) : 
 260   m_flags(_flags
), m_type(_type
), m_connected(FALSE
), m_connecting(FALSE
), 
 261   m_fd(INVALID_SOCKET
), m_waitflags(0), m_cbk(0), m_cdata(0), m_id(-1), 
 263   m_neededreq((wxRequestNotify
)(REQ_READ 
| REQ_LOST
)), 
 265   m_unread(NULL
), m_unrd_size(0), 
 267   m_timeout(3600), m_wantbuf(0) 
 269   m_internal 
= new wxSockInternal
; 
 270 #if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__) 
 271   m_internal
->sock_inputid 
= 0; 
 272   m_internal
->sock_outputid 
= 0; 
 273   m_internal
->sock_exceptid 
= 0; 
 276   m_internal
->my_msg 
= 0; 
 280 wxSocketBase::wxSocketBase() : 
 282   m_flags(WAITALL
), m_type(SOCK_UNINIT
), m_connected(FALSE
), 
 283   m_connecting(FALSE
), m_fd(INVALID_SOCKET
), m_waitflags(0), 
 284   m_cbk(0), m_cdata(0), 
 285   m_id(-1), m_handler(0), 
 286   m_neededreq((wxRequestNotify
)(REQ_READ 
| REQ_LOST
)), 
 288   m_unread(NULL
), m_unrd_size(0), 
 290   m_timeout(3600), m_wantbuf(0) 
 292   m_internal 
= new wxSockInternal
; 
 293 #if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__) 
 294   m_internal
->sock_inputid 
= 0; 
 295   m_internal
->sock_outputid 
= 0; 
 296   m_internal
->sock_exceptid 
= 0; 
 299   m_internal
->my_msg 
= 0; 
 303 // -------------------------------------------------------------- 
 305 // -------------------------------------------------------------- 
 307 wxSocketBase::~wxSocketBase() 
 317     if (m_internal
->my_msg
) 
 318       m_handler
->DestroyMessage(m_internal
->my_msg
); 
 320     m_handler
->UnRegister(this); 
 322   m_states
.DeleteContents(TRUE
); 
 327 bool wxSocketBase::Close() 
 329   if (m_fd 
!= INVALID_SOCKET
)  
 331     for (int i
=0;i
<3;i
++)  
 333       wxNode 
*n
, *node 
= req_list
[i
].First(); 
 337         SockRequest 
*req 
= (SockRequest 
*)node
->Data(); 
 349     m_fd 
= INVALID_SOCKET
; 
 356 // -------------------------------------------------------------- 
 357 // wxSocketBase base IO function 
 358 // -------------------------------------------------------------- 
 360 wxSocketBase
& wxSocketBase::Read(char* buffer
, size_t nbytes
) 
 364   count 
= GetPushback(buffer
, nbytes
, FALSE
); 
 368   // If we have got the whole needed buffer or if we don't want to 
 369   // wait then it returns immediately. 
 370   if (!nbytes 
|| (count 
&& !(m_flags 
& WAITALL
)) ) { 
 376   WantBuffer(buffer
, nbytes
, EVT_READ
); 
 382 wxSocketBase
& wxSocketBase::Peek(char* buffer
, size_t nbytes
) 
 386   count 
= GetPushback(buffer
, nbytes
, TRUE
); 
 387   if (nbytes
-count 
== 0)  
 396   WantBuffer(buffer
, nbytes
, EVT_PEEK
); 
 402 wxSocketBase
& wxSocketBase::Write(const char *buffer
, size_t nbytes
) 
 404   WantBuffer((char *)buffer
, nbytes
, EVT_WRITE
); 
 408 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, size_t nbytes
) 
 411   size_t len
, len2
, sig
; 
 413   Read((char *)&msg
, sizeof(msg
)); 
 414   if (m_lcount 
!= sizeof(msg
)) 
 417   sig 
= msg
.sig
[0] & 0xff; 
 418   sig 
|= (size_t)(msg
.sig
[1] & 0xff) << 8; 
 419   sig 
|= (size_t)(msg
.sig
[2] & 0xff) << 16; 
 420   sig 
|= (size_t)(msg
.sig
[3] & 0xff) << 24; 
 422   if (sig 
!= 0xfeeddead) 
 424   len 
= msg
.len
[0] & 0xff; 
 425   len 
|= (size_t)(msg
.len
[1] & 0xff) << 8; 
 426   len 
|= (size_t)(msg
.len
[2] & 0xff) << 16; 
 427   len 
|= (size_t)(msg
.len
[3] & 0xff) << 24; 
 434   if (Read(buffer
, len
).LastCount() != len
) 
 436   if (len2 
&& (Read(NULL
, len2
).LastCount() != len2
)) 
 438   if (Read((char *)&msg
, sizeof(msg
)).LastCount() != sizeof(msg
)) 
 441   sig 
= msg
.sig
[0] & 0xff; 
 442   sig 
|= (size_t)(msg
.sig
[1] & 0xff) << 8; 
 443   sig 
|= (size_t)(msg
.sig
[2] & 0xff) << 16; 
 444   sig 
|= (size_t)(msg
.sig
[3] & 0xff) << 24; 
 446   if (sig 
!= 0xdeadfeed) 
 452 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, size_t nbytes
) 
 456   // warning about 'cast truncates constant value' 
 458     #pragma warning(disable: 4310) 
 459 #endif // __VISUALC__ 
 461   msg
.sig
[0] = (char) 0xad; 
 462   msg
.sig
[1] = (char) 0xde; 
 463   msg
.sig
[2] = (char) 0xed; 
 464   msg
.sig
[3] = (char) 0xfe; 
 466   msg
.len
[0] = (char) nbytes 
& 0xff; 
 467   msg
.len
[1] = (char) (nbytes 
>> 8) & 0xff; 
 468   msg
.len
[2] = (char) (nbytes 
>> 16) & 0xff; 
 469   msg
.len
[3] = (char) (nbytes 
>> 24) & 0xff; 
 471   if (Write((char *)&msg
, sizeof(msg
)).LastCount() < sizeof(msg
)) 
 473   if (Write(buffer
, nbytes
).LastCount() < nbytes
) 
 476   msg
.sig
[0] = (char) 0xed; 
 477   msg
.sig
[1] = (char) 0xfe; 
 478   msg
.sig
[2] = (char) 0xad; 
 479   msg
.sig
[3] = (char) 0xde; 
 480   msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0; 
 481   Write((char *)&msg
, sizeof(msg
)); 
 486     #pragma warning(default: 4310) 
 487 #endif // __VISUALC__ 
 490 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, size_t nbytes
) 
 492   CreatePushbackAfter(buffer
, nbytes
); 
 496 bool wxSocketBase::IsData() const 
 509   FD_SET(m_fd
, &sock_set
); 
 510   select(FD_SETSIZE
, &sock_set
, NULL
, NULL
, &tv
); 
 511   return (FD_ISSET(m_fd
, &sock_set
) != 0); 
 514 // --------------------------------------------------------------------- 
 515 // --------- wxSocketBase Discard(): deletes all byte in the input queue 
 516 // --------------------------------------------------------------------- 
 517 void wxSocketBase::Discard() 
 519 #define MAX_BUFSIZE (10*1024) 
 520   char *my_data 
= new char[MAX_BUFSIZE
]; 
 521   size_t recv_size 
= MAX_BUFSIZE
; 
 524   SetFlags((wxSockFlags
)(NOWAIT 
| SPEED
)); 
 526   while (recv_size 
== MAX_BUFSIZE
)  
 528     recv_size 
= Read(my_data
, MAX_BUFSIZE
).LastCount(); 
 537 // this is normally defined by configure, but if it wasn't try to do it here 
 540         typedef socklen_t SOCKLEN_T
; 
 542         typedef int SOCKET_INT
; 
 546 // -------------------------------------------------------------- 
 547 // wxSocketBase socket info functions 
 548 // -------------------------------------------------------------- 
 550 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const 
 552   struct sockaddr my_addr
; 
 553   SOCKLEN_T len_addr 
= (SOCKLEN_T
)sizeof(my_addr
); 
 558   if (getpeername(m_fd
, (struct sockaddr 
*)&my_addr
, &len_addr
) < 0) 
 561   addr_man
.Disassemble(&my_addr
, len_addr
); 
 565 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const 
 567   struct sockaddr my_addr
; 
 568   SOCKLEN_T len_addr 
= (SOCKLEN_T
)sizeof(my_addr
); 
 573   if (getsockname(m_fd
, (struct sockaddr 
*)&my_addr
, &len_addr
) < 0) 
 576   addr_man
.Disassemble(&my_addr
, len_addr
); 
 580 // -------------------------------------------------------------- 
 581 // wxSocketBase wait functions 
 582 // -------------------------------------------------------------- 
 584 void wxSocketBase::SaveState() 
 586   wxSockState 
*state 
= new wxSockState
; 
 588   state
->cbk_on 
= m_cbkon
; 
 589   state
->cbk_set
= m_neededreq
; 
 591   state
->cdata  
= m_cdata
; 
 592   state
->flags  
= m_flags
; 
 593   state
->notif  
= m_notifyme
; 
 595   m_states
.Append(state
); 
 598 void wxSocketBase::RestoreState() 
 602   node 
= m_states
.Last(); 
 606   wxSockState 
*state 
= (wxSockState 
*)node
->Data(); 
 608   SetFlags(state
->flags
); 
 609   m_neededreq 
= state
->cbk_set
; 
 611   m_cdata     
= state
->cdata
; 
 612   m_notifyme  
= state
->notif
; 
 622 // -------------------------------------------------------------- 
 623 // --------- wxSocketBase wait functions ------------------------ 
 624 // -------------------------------------------------------------- 
 626 bool wxSocketBase::_Wait(long seconds
, long microseconds
, int type
) 
 628   if ((!m_connected 
&& !m_connecting
) || m_fd 
< 0) 
 631   wxSockWakeUp 
wakeup(this, &m_waitflags
, 0); 
 634   SetNotify((wxRequestNotify
)type
); 
 638     wakeup
.Start((int)(seconds
*1000 + (microseconds 
/ 1000)), TRUE
); 
 640   m_waitflags 
= 0x80 | type
; 
 641   while (m_waitflags 
& 0x80) 
 646   if (m_waitflags 
& 0x40)  
 656 bool wxSocketBase::Wait(long seconds
, long microseconds
) 
 658   return _Wait(seconds
, microseconds
, REQ_ACCEPT 
| REQ_CONNECT 
| 
 659                                       REQ_READ 
| REQ_WRITE 
| REQ_LOST
); 
 662 bool wxSocketBase::WaitForRead(long seconds
, long microseconds
) 
 664   return _Wait(seconds
, microseconds
, REQ_READ 
| REQ_LOST
); 
 667 bool wxSocketBase::WaitForWrite(long seconds
, long microseconds
) 
 669   return _Wait(seconds
, microseconds
, REQ_WRITE
); 
 672 bool wxSocketBase::WaitForLost(long seconds
, long microseconds
) 
 674   return _Wait(seconds
, microseconds
, REQ_LOST
); 
 677 // -------------------------------------------------------------- 
 678 // --------- wxSocketBase callback management ------------------- 
 679 // -------------------------------------------------------------- 
 682 void wxPrereadSocket(wxSocketBase 
*sock
) 
 688     got 
= recv(sock
->m_fd
, tmp_buf
, 1024, 0); 
 690       sock
->CreatePushbackAfter(tmp_buf
, got
); 
 695 #if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__) 
 696 #if defined(__WXMOTIF__) || defined(__WXXT__) 
 697 static void wx_socket_read(XtPointer client
, int *fid
, 
 698          XtInputId 
*WXUNUSED(id
)) 
 701 static void wx_socket_read(gpointer client
, gint fd
, 
 702                            GdkInputCondition 
WXUNUSED(cond
)) 
 706   wxSocketBase 
*sock 
= (wxSocketBase 
*)client
; 
 710   i 
= recv(fd
, &c
, 1, MSG_PEEK
); 
 712   if (i 
== -1 && (sock
->NeededReq() & wxSocketBase::REQ_ACCEPT
))  
 714     sock
->OnRequest(wxSocketBase::EVT_ACCEPT
); 
 720     if (!(sock
->NeededReq() & wxSocketBase::REQ_READ
)) 
 723       // We can't exit from the GDK main loop because it doesn't accept 
 724       // destroying input event while we are in a event dispatch. 
 725       // So we will preread socket and we put the data in the pushback. 
 726       wxPrereadSocket(sock
); 
 727       // Then we set the socket as BLOCKING 
 729       ioctl(fd
, FIONBIO
, &flag
); 
 734     sock
->OnRequest(wxSocketBase::EVT_READ
); 
 738     if (!(sock
->NeededReq() & wxSocketBase::REQ_LOST
))  
 744     sock
->OnRequest(wxSocketBase::EVT_LOST
); 
 749 #if defined(__WXMOTIF__) || defined(__WXXT__) 
 750 static void wx_socket_write(XtPointer client
, int *WXUNUSED(fid
), 
 751           XtInputId 
*WXUNUSED(id
)) 
 753 static void wx_socket_write(gpointer client
, gint 
WXUNUSED(fd
), 
 754           GdkInputCondition 
WXUNUSED(cond
)) 
 757   wxSocketBase 
*sock 
= (wxSocketBase 
*)client
; 
 759   if (!sock
->IsConnected()) 
 760     sock
->OnRequest(wxSocketBase::EVT_CONNECT
); 
 762     sock
->OnRequest(wxSocketBase::EVT_WRITE
); 
 767 Notify_value 
wx_sock_read_xview (Notify_client client
, int fd
) 
 769   wxSocketBase 
*sock 
= (wxSocketBase 
*)client
; 
 773   i 
= recv(fd
, &c
, 1, MSG_PEEK
); 
 775   if (i 
== -1 && (sock
->NeededReq() & wxSocketBase::REQ_ACCEPT
))  
 777     sock
->OnRequest(wxSocketBase::EVT_ACCEPT
); 
 784     if (!(sock
->NeededReq() & wxSocketBase::REQ_READ
)) 
 785       return (Notify_value
) FALSE
; 
 787     sock
->OnRequest(wxSocketBase::EVT_READ
); 
 791     if (!(sock
->NeededReq() & wxSocketBase::REQ_LOST
)) 
 794     sock
->OnRequest(wxSocketBase::EVT_LOST
); 
 797   return (Notify_value
) FALSE
; 
 800 Notify_value 
wx_sock_write_xview (Notify_client client
, int fd
) 
 802   wxSocketBase 
*sock 
= (wxSocketBase 
*)client
; 
 804   if (!sock
->IsConnected()) 
 805     sock
->OnRequest(wxSocketBase::EVT_CONNECT
); 
 807     sock
->OnRequest(wxSocketBase::EVT_WRITE
); 
 809   return (Notify_value
) TRUE
; 
 813 wxSocketBase::wxRequestNotify 
wxSocketBase::EventToNotify(wxRequestEvent evt
) 
 833 void wxSocketBase::SetFlags(wxSockFlags _flags
) 
 838     unsigned long flag 
= 0; 
 839     ioctl(m_fd
, FIONBIO
, &flag
); 
 841     // SPEED and WAITALL are antagonists. 
 842     m_flags 
= (wxSockFlags
)(m_flags 
& ~WAITALL
); 
 848     unsigned long flag 
= 1; 
 849     ioctl(m_fd
, FIONBIO
, &flag
); 
 853 void wxSocketBase::SetNotify(wxRequestNotify flags
) 
 855   wxRequestNotify old_needed_req 
= m_neededreq
; 
 856   if (flags 
& REQ_ACCEPT
)  
 858     /* Check if server */ 
 859     if (!(GetClassInfo()->IsKindOf(CLASSINFO(wxSocketServer
)))) 
 860       flags 
&= ~REQ_ACCEPT
; 
 865   if (m_cbkon && old_needed_req != flags)    seems to be wrong, Robert Roebling 
 869   if (old_needed_req 
!= flags
) 
 873 void wxSocketBase::SetupCallbacks() 
 875   if (m_fd 
== INVALID_SOCKET 
|| !m_handler 
|| (m_flags 
& SPEED
)) 
 878 #if defined(__WXMOTIF__) || defined(__WXXT__) 
 879   if (m_neededreq 
& (REQ_ACCEPT 
| REQ_READ 
| REQ_LOST
))  
 881     if (m_internal
->sock_inputid 
<= 0) 
 883       m_internal
->sock_inputid 
= XtAppAddInput (wxAPP_CONTEXT
, m_fd
, 
 884                                         (XtPointer 
*) XtInputReadMask
, 
 885                                         (XtInputCallbackProc
) wx_socket_read
, 
 891     if (m_internal
->sock_inputid 
> 0) 
 893       XtRemoveInput(m_internal
->sock_inputid
); 
 894       m_internal
->sock_inputid 
= 0; 
 898   if (m_neededreq 
& (REQ_CONNECT 
| REQ_WRITE
))  
 900     if (m_internal
->sock_outputid 
<= 0) 
 902       m_internal
->sock_outputid 
= XtAppAddInput (wxAPP_CONTEXT
, m_fd
, 
 903                                         (XtPointer 
*) XtInputWriteMask
, 
 904                                         (XtInputCallbackProc
) wx_socket_write
, 
 910     if (m_internal
->sock_outputid 
> 0) 
 912       XtRemoveInput(m_internal
->sock_outputid
); 
 913       m_internal
->sock_outputid 
= 0; 
 920   if (m_neededreq 
& (REQ_ACCEPT 
| REQ_READ 
| REQ_LOST
))  
 922     if (m_internal
->sock_inputid 
<= 0) 
 924        m_internal
->sock_inputid 
= gdk_input_add(m_fd
, GDK_INPUT_READ
, 
 925                                            wx_socket_read
, (gpointer
)this); 
 930     if (m_internal
->sock_inputid 
> 0) 
 933       gdk_input_remove(m_internal->sock_inputid); 
 934       m_internal->sock_inputid = 0; 
 939   if (m_neededreq 
& (REQ_CONNECT 
| REQ_WRITE
))  
 941     if (m_internal
->sock_outputid 
<= 0) 
 943       m_internal
->sock_outputid 
= gdk_input_add(m_fd
, GDK_INPUT_WRITE
, 
 944                                              wx_socket_write
, (gpointer
)this); 
 949     if (m_internal
->sock_outputid 
> 0) 
 952       gdk_input_remove(m_internal->sock_outputid); 
 953       m_internal->sock_outputid = 0; 
 963   if (m_neededreq 
& REQ_READ
) 
 965   if (m_neededreq 
& REQ_WRITE
) 
 967   if (m_neededreq 
& REQ_LOST
) 
 969   if (m_neededreq 
& REQ_ACCEPT
) 
 971   if (m_neededreq 
& REQ_CONNECT
) 
 974   if (!m_internal
->my_msg
) 
 975     m_internal
->my_msg 
= m_handler
->NewMessage(this); 
 976   WSAAsyncSelect(m_fd
, m_handler
->GetHWND(), m_internal
->my_msg
, mask
); 
 981   if (m_neededreq 
& REQ_READ
) 
 983   if (m_neededreq 
& REQ_WRITE
) 
 985   if (m_neededreq 
& REQ_LOST
) 
 987   if (m_neededreq 
& REQ_ACCEPT
) 
 989   if (m_neededreq 
& REQ_CONNECT
) 
 992   GUSISetReference( m_fd 
,mask
, this ) ; 
 993   unsigned long flag 
= 1; 
 994   ioctl(m_fd
, FIONBIO
, &flag
); 
 997   m_processing 
= FALSE
; 
1000 void wxSocketBase::DestroyCallbacks() 
1002   if (!m_cbkon 
|| !m_handler
) 
1006   m_processing 
= FALSE
; 
1007 #if defined(__WXMOTIF__) || defined(__WXXT__) 
1008   if (m_internal
->sock_inputid 
> 0) 
1009     XtRemoveInput(m_internal
->sock_inputid
); 
1010   m_internal
->sock_inputid 
= 0; 
1011   if (m_internal
->sock_outputid 
> 0) 
1012     XtRemoveInput(m_internal
->sock_outputid
); 
1013   m_internal
->sock_outputid 
= 0; 
1016   if (m_internal
->sock_inputid 
> 0) 
1017     gdk_input_remove(m_internal
->sock_inputid
); 
1018   m_internal
->sock_inputid 
= 0; 
1019   if (m_internal
->sock_outputid 
> 0) 
1020     gdk_input_remove(m_internal
->sock_outputid
); 
1021   m_internal
->sock_outputid 
= 0; 
1024   WSAAsyncSelect(m_fd
, m_handler
->GetHWND(), 0, 0); 
1027   GUSISetReference( m_fd 
, 0 , 0 ) ; 
1028   int bottom 
= wxMacNetEventsBottom 
; 
1029   while ( wxMacNetEventsTop 
!= bottom 
) 
1031     // set all events that reference this socket to nil 
1032     if ( wxMacNetEventsReferences
[bottom
] == (void*) this ) 
1033       wxMacNetEventsReferences
[bottom
] = NULL 
; 
1035     if ( bottom 
== kwxMacNetEventsMax 
) 
1038   SetFlags( m_flags 
) ; 
1042 void wxSocketBase::Notify(bool notify
) 
1044   if (m_notifyme 
== notify
) 
1050   m_notifyme 
= notify
; 
1053 void wxSocketBase::OnRequest(wxRequestEvent req_evt
) 
1055   wxRequestNotify req_notif 
= EventToNotify(req_evt
); 
1057   // Mask the current event 
1058   SetNotify(m_neededreq 
& ~req_notif
);   
1060   if (req_evt 
<= EVT_WRITE 
&& DoRequests(req_evt
)) 
1063   if (m_waitflags 
& 0xF0)  
1066     if ((m_waitflags 
& 0x0F) == req_evt
)  
1076   if (req_evt 
== EVT_LOST
)  
1078     m_connected 
= FALSE
; 
1082     OldOnNotify(req_evt
); 
1085   SetNotify(m_neededreq 
| req_notif
); 
1088 wxSocketEvent::wxSocketEvent(int id
) 
1091   wxEventType type 
= (wxEventType
)wxEVT_SOCKET
; 
1096 void wxSocketBase::OldOnNotify(wxRequestEvent evt
) 
1098   wxSocketEvent 
event(m_id
); 
1100   event
.SetEventObject(this); 
1101   event
.m_skevt 
= evt
; 
1102   ProcessEvent(event
); 
1105     m_cbk(*this, evt
, m_cdata
); 
1108 // -------------------------------------------------------------- 
1109 // --------- wxSocketBase functions [Callback, CallbackData] ---- 
1110 // -------------------------------------------------------------- 
1112 wxSocketBase::wxSockCbk 
wxSocketBase::Callback(wxSocketBase::wxSockCbk _cbk
) 
1114   wxSockCbk old_cbk 
= m_cbk
; 
1120 char *wxSocketBase::CallbackData(char *cdata_
) 
1122   char *old_cdata 
= m_cdata
; 
1128 void wxSocketBase::SetEventHandler(wxEvtHandler
& h_evt
, int id
) 
1130   SetNextHandler(&h_evt
); 
1134 // -------------------------------------------------------------- 
1135 // --------- wxSocketBase pushback library ---------------------- 
1136 // -------------------------------------------------------------- 
1138 void wxSocketBase::CreatePushbackAfter(const char *buffer
, size_t size
) 
1142   if (m_unread 
!= NULL
) 
1143     m_unread 
= (char *) realloc(m_unread
, m_unrd_size
+size
); 
1145     m_unread 
= (char *) malloc(size
); 
1146   curr_pos 
= m_unread 
+ m_unrd_size
; 
1148   memcpy(curr_pos
, buffer
, size
); 
1149   m_unrd_size 
+= size
; 
1152 void wxSocketBase::CreatePushbackBefore(const char *buffer
, size_t size
) 
1154   char *curr_pos
, *new_buf
; 
1156   new_buf 
= (char *) malloc(m_unrd_size
+size
); 
1157   curr_pos 
= new_buf 
+ size
; 
1159   memcpy(new_buf
, buffer
, size
); 
1160   if (m_unrd_size 
!= 0) { 
1161     memcpy(curr_pos
, m_unread
, m_unrd_size
); 
1165   m_unrd_size 
+= size
; 
1168 size_t wxSocketBase::GetPushback(char *buffer
, size_t size
, bool peek
) 
1173   if (size 
> m_unrd_size
) 
1175   memcpy(buffer
, m_unread
, size
); 
1178     m_unrd_size 
-= size
; 
1179     if (m_unrd_size 
== 0) { 
1188 // -------------------------------------------------------------- 
1189 // --------- wxSocketBase "multi-thread" core ------------------- 
1190 // -------------------------------------------------------------- 
1192 bool wxSocketBase::DoRequests(wxRequestEvent req_flag
) 
1194   wxNode 
*node 
= req_list
[req_flag
].First(); 
1201   SockRequest 
*req 
= (SockRequest 
*)node
->Data(); 
1209     ret 
= recv(m_fd
, req
->buffer
, req
->size
, 
1210                (req
->type 
== EVT_PEEK
) ? MSG_PEEK 
: 0); 
1218     if ((len 
< req
->size
) && (m_flags 
& WAITALL
))  
1223       req
->auto_wakeup
->Start(m_timeout
*1000, TRUE
); 
1224       req_list
[req_flag
].Insert(req
); 
1234     ret 
= send(m_fd
, req
->buffer
, req
->size
, 0); 
1242     if ((len 
< req
->size
) && (m_flags 
& WAITALL
))  
1247       req
->auto_wakeup
->Start(m_timeout
*1000, TRUE
); 
1248       req_list
[req_flag
].Insert(req
); 
1263 void wxSocketBase::WantSpeedBuffer(char *buffer
, size_t nbytes
, 
1272     ret 
= recv(m_fd
, buffer
, nbytes
, 
1273                (evt 
== EVT_PEEK
) ? MSG_PEEK 
: 0); 
1276     ret 
= send(m_fd
, buffer
, nbytes
, 0); 
1291 void wxSocketBase::WantBuffer(char *buffer
, size_t nbytes
, 
1296   if (m_fd 
== INVALID_SOCKET 
|| !m_handler 
|| !m_connected
) 
1299   if (m_flags 
& SPEED
)  
1301     WantSpeedBuffer(buffer
, nbytes
, evt
); 
1305   SockRequest 
*buf 
= new SockRequest
; 
1306   wxSockWakeUp 
s_wake(NULL
, (int *)&buf_timed_out
, (int)TRUE
); 
1309   req_list
[evt
].Append(buf
); 
1312   SetNotify(REQ_LOST 
| EventToNotify(evt
)); 
1314   buf
->buffer 
= buffer
; 
1319   buf
->auto_wakeup 
= &s_wake
; 
1321   buf_timed_out 
= FALSE
; 
1323   s_wake
.Start(m_timeout
*1000, TRUE
); 
1324   if (m_flags 
& NOWAIT
)  
1330     while (!buf
->done 
&& !buf_timed_out
) 
1334   m_lcount 
= buf
->nbytes
; 
1336     m_error 
= ETIMEDOUT
; 
1338     m_error 
= buf
->error
; 
1344 // -------------------------------------------------------------- 
1346 // -------------------------------------------------------------- 
1348 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
, 
1349              wxSockFlags flags
) : 
1350   wxSocketBase(flags
, SOCK_SERVER
) 
1352   m_fd 
= socket(addr_man
.GetFamily(), SOCK_STREAM
, 0); 
1354   if (m_fd 
== INVALID_SOCKET
) 
1358   setsockopt(m_fd
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&flag
, sizeof(int)); 
1360   struct sockaddr 
*myaddr
; 
1363   addr_man
.Build(myaddr
, len
); 
1364   if (bind(m_fd
, myaddr
, addr_man
.SockAddrLen()) < 0) 
1367   if (listen(m_fd
, 5) < 0) { 
1368     m_fd 
= INVALID_SOCKET
; 
1373 // -------------------------------------------------------------- 
1374 // wxSocketServer Accept 
1375 // -------------------------------------------------------------- 
1377 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
) 
1381   if ((fd2 
= accept(m_fd
, 0, 0)) < 0) 
1384   struct linger linger
; 
1386   linger
.l_linger 
= 1; 
1388   setsockopt(fd2
, SOL_SOCKET
, SO_LINGER
, (char*)&linger
, sizeof(linger
)); 
1391   setsockopt(fd2
, SOL_SOCKET
, SO_KEEPALIVE
, (char*)&flag
, sizeof(int)); 
1393   if (!(sock
.m_flags 
& SPEED
))  
1395     unsigned long flag2 
= 1; 
1396     ioctl(fd2
, FIONBIO
, &flag2
); 
1399   sock
.m_type 
= SOCK_INTERNAL
; 
1401   sock
.m_connected 
= TRUE
; 
1406 wxSocketBase 
*wxSocketServer::Accept() 
1408   wxSocketBase
* sock 
= new wxSocketBase(); 
1410   sock
->SetFlags((wxSockFlags
)m_flags
); 
1412   if (!AcceptWith(*sock
)) 
1416     m_handler
->Register(sock
); 
1421 // -------------------------------------------------------------- 
1422 // wxSocketServer callbacks 
1423 // -------------------------------------------------------------- 
1425 void wxSocketServer::OnRequest(wxRequestEvent evt
) 
1427   if (evt 
== EVT_ACCEPT
)  
1429     OldOnNotify(EVT_ACCEPT
); 
1433 // -------------------------------------------------------------- 
1435 // -------------------------------------------------------------- 
1437 // --------- wxSocketClient CONSTRUCTOR ------------------------- 
1438 // -------------------------------------------------------------- 
1439 wxSocketClient::wxSocketClient(wxSockFlags _flags
) : 
1440   wxSocketBase(_flags
, SOCK_CLIENT
) 
1444 // -------------------------------------------------------------- 
1445 // --------- wxSocketClient DESTRUCTOR -------------------------- 
1446 // -------------------------------------------------------------- 
1447 wxSocketClient::~wxSocketClient() 
1451 // -------------------------------------------------------------- 
1452 // --------- wxSocketClient Connect functions ------------------- 
1453 // -------------------------------------------------------------- 
1454 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool WXUNUSED(wait
) ) 
1456   struct linger linger
; 
1461   m_fd 
= socket(addr_man
.GetFamily(), SOCK_STREAM
, 0); 
1466   m_connected 
= FALSE
; 
1469   linger
.l_linger 
= 5; 
1470   setsockopt(m_fd
, SOL_SOCKET
, SO_LINGER
, (char*)&linger
, sizeof(linger
)); 
1472   // Stay in touch with the state of things... 
1474   unsigned long flag 
= 1; 
1475   setsockopt(m_fd
, SOL_SOCKET
, SO_KEEPALIVE
, (char*)&flag
, sizeof(int)); 
1477   // Disable the nagle algorithm, which delays sends till the 
1478   // buffer is full (or a certain time period has passed?)... 
1480 #if defined(__WINDOWS__) || (defined(IPPROTO_TCP) && defined(TCP_NODELAY)) 
1482   setsockopt(m_fd
, IPPROTO_TCP
, TCP_NODELAY
, (char*)&flag
, sizeof(int)); 
1485   struct sockaddr 
*remote
; 
1488   addr_man
.Build(remote
, len
); 
1490   if (connect(m_fd
, remote
, len
) != 0) 
1493   if (!(m_flags 
& SPEED
))  
1496     ioctl(m_fd
, FIONBIO
, &flag
); 
1505 bool wxSocketClient::WaitOnConnect(long seconds
, long microseconds
) 
1507   int ret 
= _Wait(seconds
, microseconds
, REQ_CONNECT 
| REQ_LOST
); 
1515 void wxSocketClient::OnRequest(wxRequestEvent evt
) 
1517   if (evt 
== EVT_CONNECT
)  
1522       SetNotify(m_neededreq 
& ~REQ_CONNECT
); 
1528     OldOnNotify(EVT_CONNECT
); 
1534   wxSocketBase::OnRequest(evt
); 
1537 ///////////////////////////////////////////////////////////////// 
1538 // wxSocketHandler /////////////////////////////////////////////// 
1539 ///////////////////////////////////////////////////////////////// 
1541 wxSocketHandler 
*wxSocketHandler::master 
= NULL
; 
1542 #if defined(__WINDOWS__) 
1543 static int win_initialized 
= 0; 
1546 // -------------------------------------------------------------- 
1547 // --------- wxSocketHandler CONSTRUCTOR ------------------------ 
1548 // -------------------------------------------------------------- 
1551 extern "C" int updatestatus(int s
) ; 
1553 void wxMacSocketOnRequestProc( void *refcon 
, short event 
) 
1557     wxSocketBase 
*sock 
= (wxSocketBase 
*) refcon 
;   
1559     wxSocketBase::wxRequestEvent sk_req
; 
1567       sk_req 
= wxSocketBase::EVT_READ
; 
1568      sock
->OnRequest(sk_req
); 
1571       sk_req 
= wxSocketBase::EVT_WRITE
; 
1572       sock
->OnRequest(sk_req
); 
1575       sk_req 
= wxSocketBase::EVT_LOST
; 
1576      sock
->OnRequest(sk_req
); 
1579       sk_req 
= wxSocketBase::EVT_ACCEPT
; 
1580       sock
->OnRequest(sk_req
); 
1583       sk_req 
= wxSocketBase::EVT_CONNECT
; 
1584       sock
->OnRequest(sk_req
); 
1589     updatestatus ( sock
->m_fd 
) ; 
1593 void wxMacSocketHandlerProc( void *refcon 
, short event 
) 
1595   wxMacNetEventsReferences
[wxMacNetEventsTop
] = refcon 
; 
1596   wxMacNetEventsEvents
[wxMacNetEventsTop
] = event 
; 
1598   // clumsy construct in order to never have a incorrect wxMacNetEventsTop (above limits) 
1600   if ( wxMacNetEventsTop 
+ 1 == kwxMacNetEventsMax 
) 
1601     wxMacNetEventsTop 
= 0 ; 
1603     wxMacNetEventsTop
++ ; 
1609 extern char wxPanelClassName
[]; 
1611 LRESULT APIENTRY _EXPORT 
wxSocketHandlerWndProc(HWND hWnd
, UINT message
, 
1612    WPARAM wParam
, LPARAM lParam
) 
1614   if(message
==WM_DESTROY
) 
1616     ::SetWindowLong(hWnd
, GWL_WNDPROC
, (LONG
) DefWindowProc
); 
1617     return DefWindowProc(hWnd
, message
, wParam
, lParam
); 
1619   wxSocketHandler 
*h_sock 
= (wxSocketHandler 
*)GetWindowLong(hWnd
, GWL_USERDATA
); 
1620   wxNode 
*node 
= h_sock
->smsg_list
->Find(message
); 
1622   wxSocketBase::wxRequestEvent sk_req
; 
1623   UINT event 
= WSAGETSELECTEVENT(lParam
); 
1626     return DefWindowProc(hWnd
, message
, wParam
, lParam
); 
1628   sock 
= (wxSocketBase 
*)node
->Data(); 
1632     sk_req 
= wxSocketBase::EVT_READ
; 
1635     sk_req 
= wxSocketBase::EVT_WRITE
; 
1638     sk_req 
= wxSocketBase::EVT_LOST
; 
1641     sk_req 
= wxSocketBase::EVT_ACCEPT
; 
1644     sk_req 
= wxSocketBase::EVT_CONNECT
; 
1648       wxFAIL_MSG("invalid socket event"); 
1652   sock
->OnRequest(sk_req
); 
1657 FARPROC wxSocketSubClassProc 
= NULL
; 
1661 wxSocketHandler::wxSocketHandler() 
1663 #if defined(__WINDOWS__) 
1664   if (!win_initialized
)  
1668     WSAStartup((1 << 8) | 1, &wsaData
); 
1669     win_initialized 
= 1; 
1671   internal 
= new wxSockHandlerInternal
; 
1672   internal
->sockWin 
= ::CreateWindow(wxPanelClassName
, NULL
, 0, 
1673     0, 0, 0, 0, NULL
, (HMENU
) NULL
, 
1676   // Subclass the window 
1677   if (!wxSocketSubClassProc
) 
1678     wxSocketSubClassProc 
= MakeProcInstance((FARPROC
) wxSocketHandlerWndProc
, wxhInstance
); 
1679   ::SetWindowLong(internal
->sockWin
, GWL_WNDPROC
, (LONG
) wxSocketSubClassProc
); 
1680   ::SetWindowLong(internal
->sockWin
, GWL_USERDATA
, (LONG
) this); 
1682   internal
->firstAvailableMsg 
= 5000; 
1683   smsg_list 
= new wxList(wxKEY_INTEGER
); 
1689   signal(SIGPIPE
, SIG_IGN
); 
1693 // -------------------------------------------------------------- 
1694 // --------- wxSocketHandler DESTRUCTOR ------------------------- 
1695 // -------------------------------------------------------------- 
1696 wxSocketHandler::~wxSocketHandler() 
1698   wxNode 
*next_node
, *node 
= socks
->First(); 
1702     wxSocketBase
* sock 
= (wxSocketBase
*)node
->Data(); 
1705     next_node 
= node
->Next(); 
1715   ::DestroyWindow(internal
->sockWin
); 
1717   win_initialized 
= 0; 
1723 // -------------------------------------------------------------- 
1724 // --------- wxSocketHandler registering functions -------------- 
1725 // -------------------------------------------------------------- 
1727 void wxSocketHandler::Register(wxSocketBase
* sock
) 
1731   for (node 
= socks
->First(); node 
!= NULL
; node 
= node
->Next())  
1733     wxSocketBase
* s 
= (wxSocketBase
*)node
->Data(); 
1741     socks
->Append(sock
); 
1742     sock
->SetHandler(this); 
1743     sock
->SetupCallbacks(); 
1747 void wxSocketHandler::UnRegister(wxSocketBase
* sock
) 
1751   for (node 
= socks
->First(); node
; node 
= node
->Next())  
1753     wxSocketBase
* s 
= (wxSocketBase
*)node
->Data(); 
1758       sock
->DestroyCallbacks(); 
1759       sock
->SetHandler(NULL
); 
1765 unsigned long wxSocketHandler::Count() const 
1767   return socks
->Number(); 
1770 // -------------------------------------------------------------- 
1771 // --------- wxSocketHandler "big" wait functions --------------- 
1772 // -------------------------------------------------------------- 
1773 void handler_cbk(wxSocketBase
& sock
, 
1774      wxSocketBase::wxRequestEvent 
WXUNUSED(flags
), 
1777   int *a_wait 
= (int *)cdata
; 
1783 int wxSocketHandler::Wait(long seconds
, long microseconds
) 
1787   wxSockWakeUp 
s_wake(NULL
, &on_wait
, -2); 
1790   for (node 
= socks
->First(), i
=0; node
; node 
= node
->Next(), i
++)  
1792     wxSocketBase 
*sock 
= (wxSocketBase 
*)node
->Data(); 
1796     sock
->SetupCallbacks(); 
1798     sock
->Callback(handler_cbk
); 
1799     sock
->CallbackData((char *)&on_wait
); 
1803     s_wake
.Start((seconds
*1000) + (microseconds
/1000), TRUE
); 
1808   for (node 
= socks
->First(), i
=0; node
; node 
= node
->Next(), i
++)  
1810     wxSocketBase 
*sock 
= (wxSocketBase 
*)node
->Data(); 
1812     sock
->RestoreState(); 
1821 void wxSocketHandler::YieldSock() 
1825   for (node 
= socks
->First(); node
; node 
= node
->Next() )  
1827     wxSocketBase 
*sock 
= (wxSocketBase 
*)node
->Data(); 
1831     sock
->SetFlags(wxSocketBase::SPEED
); 
1833       sock
->DoRequests(wxSocketBase::EVT_READ
); 
1834     sock
->DoRequests(wxSocketBase::EVT_WRITE
); 
1836     sock
->RestoreState(); 
1840 // -------------------------------------------------------------- 
1841 // --------- wxSocketHandler: create and register the socket ---- 
1842 // -------------------------------------------------------------- 
1843 wxSocketServer 
*wxSocketHandler::CreateServer(wxSockAddress
& addr
, 
1844                 wxSocketBase::wxSockFlags flags
) 
1846   wxSocketServer 
*serv 
= new wxSocketServer(addr
, flags
); 
1852 wxSocketClient 
*wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags
) 
1854   wxSocketClient 
*client 
= new wxSocketClient(flags
); 
1861 // -------------------------------------------------------------- 
1862 // --------- wxSocketHandler: Windows specific methods ---------- 
1863 // -------------------------------------------------------------- 
1865 UINT 
wxSocketHandler::NewMessage(wxSocketBase 
*sock
) 
1867   internal
->firstAvailableMsg
++; 
1868   smsg_list
->Append(internal
->firstAvailableMsg
, sock
); 
1869   return internal
->firstAvailableMsg
; 
1872 void wxSocketHandler::DestroyMessage(UINT msg
) 
1874   wxNode 
*node 
= smsg_list
->Find(msg
); 
1878 HWND 
wxSocketHandler::GetHWND() const 
1880   return internal
->sockWin
; 
1885 bool wxSocketModule::OnInit()  
1887   wxSocketHandler::master 
= new wxSocketHandler(); 
1891 void wxSocketModule::OnExit()  
1893   delete wxSocketHandler::master
; 
1894   wxSocketHandler::master 
= NULL
; 
1898 void wxMacProcessSocketEvents() ; 
1899 void wxMacProcessEvents() 
1901   wxMacProcessSocketEvents() ; 
1902    (*GUSISpin
)(SP_MISC
, 0) ; 
1905 void wxMacProcessSocketEvents() 
1907   while ( wxMacNetEventsTop 
!= wxMacNetEventsBottom 
) 
1909     // consume event at wxMacNetEventsBottom 
1910     wxMacSocketOnRequestProc(wxMacNetEventsReferences
[wxMacNetEventsBottom
] , wxMacNetEventsEvents
[wxMacNetEventsBottom
]  ) ; 
1911     wxMacNetEventsBottom
++ ; 
1912     if ( wxMacNetEventsBottom 
== kwxMacNetEventsMax 
) 
1913       wxMacNetEventsBottom 
= 0 ;