home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / common / sckipc.cpp < prev    next >
C/C++ Source or Header  |  2002-09-03  |  19KB  |  760 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        sckipc.cpp
  3. // Purpose:     Interprocess communication implementation (wxSocket version)
  4. // Author:      Julian Smart
  5. // Modified by: Guilhem Lavaux (big rewrite) May 1997, 1998
  6. //              Guillermo Rodriguez (updated for wxSocket v2) Jan 2000
  7. //                                  (callbacks deprecated)    Mar 2000
  8. //              Vadim Zeitlin (added support for Unix sockets) Apr 2002
  9. // Created:     1993
  10. // RCS-ID:      $Id: sckipc.cpp,v 1.33 2002/09/03 11:22:55 JS Exp $
  11. // Copyright:   (c) Julian Smart 1993
  12. //              (c) Guilhem Lavaux 1997, 1998
  13. //              (c) 2000 Guillermo Rodriguez <guille@iies.es>
  14. // Licence:     wxWindows license
  15. /////////////////////////////////////////////////////////////////////////////
  16.  
  17. // ==========================================================================
  18. // declarations
  19. // ==========================================================================
  20.  
  21. // --------------------------------------------------------------------------
  22. // headers
  23. // --------------------------------------------------------------------------
  24.  
  25. #ifdef __GNUG__
  26. #pragma implementation "sckipc.h"
  27. #endif
  28.  
  29. // For compilers that support precompilation, includes "wx.h".
  30. #include "wx/wxprec.h"
  31.  
  32. #ifdef __BORLANDC__
  33. #pragma hdrstop
  34. #endif
  35.  
  36. #ifndef WX_PRECOMP
  37. #include "wx/log.h"
  38. #endif
  39.  
  40. #if wxUSE_SOCKETS && wxUSE_IPC && wxUSE_STREAMS
  41.  
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include <errno.h>
  45.  
  46. #include "wx/socket.h"
  47. #include "wx/sckipc.h"
  48. #include "wx/module.h"
  49. #include "wx/event.h"
  50.  
  51. // --------------------------------------------------------------------------
  52. // macros and constants
  53. // --------------------------------------------------------------------------
  54.  
  55. // It seems to be already defined somewhere in the Xt includes.
  56. #ifndef __XT__
  57. // Message codes
  58. enum
  59. {
  60.   IPC_EXECUTE = 1,
  61.   IPC_REQUEST,
  62.   IPC_POKE,
  63.   IPC_ADVISE_START,
  64.   IPC_ADVISE_REQUEST,
  65.   IPC_ADVISE,
  66.   IPC_ADVISE_STOP,
  67.   IPC_REQUEST_REPLY,
  68.   IPC_FAIL,
  69.   IPC_CONNECT,
  70.   IPC_DISCONNECT
  71. };
  72. #endif
  73.  
  74. // All sockets will be created with the following flags
  75. #define SCKIPC_FLAGS (wxSOCKET_WAITALL)
  76.  
  77. // headers needed for umask()
  78. #ifdef __UNIX_LIKE__
  79.     #include <sys/types.h>
  80.     #include <sys/stat.h>
  81. #endif // __UNIX_LIKE__
  82.  
  83. // ----------------------------------------------------------------------------
  84. // private functions
  85. // ----------------------------------------------------------------------------
  86.  
  87. // get the address object for the given server name, the caller must delete it
  88. static wxSockAddress *
  89. GetAddressFromName(const wxString& serverName, const wxString& host = _T(""))
  90. {
  91.     // we always use INET sockets under non-Unix systems
  92. #if defined(__UNIX__) && !defined(__WXMAC__)
  93.     // under Unix, if the server name looks like a path, create a AF_UNIX
  94.     // socket instead of AF_INET one
  95.     if ( serverName.Find(_T('/')) != wxNOT_FOUND )
  96.     {
  97.         wxUNIXaddress *addr = new wxUNIXaddress;
  98.         addr->Filename(serverName);
  99.  
  100.         return addr;
  101.     }
  102. #endif // Unix/!Unix
  103.     {
  104.         wxIPV4address *addr = new wxIPV4address;
  105.         addr->Service(serverName);
  106.         if ( !host.empty() )
  107.         {
  108.             addr->Hostname(host);
  109.         }
  110.  
  111.         return addr;
  112.     }
  113. }
  114.  
  115. // --------------------------------------------------------------------------
  116. // wxTCPEventHandler stuff (private class)
  117. // --------------------------------------------------------------------------
  118.  
  119. class wxTCPEventHandler : public wxEvtHandler
  120. {
  121. public:
  122.   wxTCPEventHandler() : wxEvtHandler() {};
  123.  
  124.   void Client_OnRequest(wxSocketEvent& event);
  125.   void Server_OnRequest(wxSocketEvent& event);
  126.  
  127.   DECLARE_EVENT_TABLE()
  128. };
  129.  
  130. enum
  131. {
  132.   _CLIENT_ONREQUEST_ID = 1000,
  133.   _SERVER_ONREQUEST_ID
  134. };
  135.  
  136. static wxTCPEventHandler *gs_handler = NULL;
  137.  
  138. // ==========================================================================
  139. // implementation
  140. // ==========================================================================
  141.  
  142. IMPLEMENT_DYNAMIC_CLASS(wxTCPServer, wxServerBase)
  143. IMPLEMENT_DYNAMIC_CLASS(wxTCPClient, wxClientBase)
  144. IMPLEMENT_CLASS(wxTCPConnection, wxConnectionBase)
  145.  
  146. // --------------------------------------------------------------------------
  147. // wxTCPClient
  148. // --------------------------------------------------------------------------
  149.  
  150. wxTCPClient::wxTCPClient () : wxClientBase()
  151. {
  152. }
  153.  
  154. wxTCPClient::~wxTCPClient ()
  155. {
  156. }
  157.  
  158. bool wxTCPClient::ValidHost(const wxString& host)
  159. {
  160.   wxIPV4address addr;
  161.  
  162.   return addr.Hostname(host);
  163. }
  164.  
  165. wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host,
  166.                                                const wxString& serverName,
  167.                                                const wxString& topic)
  168. {
  169.   wxSocketClient *client = new wxSocketClient(SCKIPC_FLAGS);
  170.   wxSocketStream *stream = new wxSocketStream(*client);
  171.   wxDataInputStream *data_is = new wxDataInputStream(*stream);
  172.   wxDataOutputStream *data_os = new wxDataOutputStream(*stream);
  173.  
  174.   wxSockAddress *addr = GetAddressFromName(serverName, host);
  175.   if ( !addr )
  176.       return NULL;
  177.  
  178.   bool ok = client->Connect(*addr);
  179.   delete addr;
  180.  
  181.   if ( ok )
  182.   {
  183.     unsigned char msg;
  184.  
  185.     // Send topic name, and enquire whether this has succeeded
  186.     data_os->Write8(IPC_CONNECT);
  187.     data_os->WriteString(topic);
  188.  
  189.     msg = data_is->Read8();
  190.  
  191.     // OK! Confirmation.
  192.     if (msg == IPC_CONNECT)
  193.     {
  194.       wxTCPConnection *connection = (wxTCPConnection *)OnMakeConnection ();
  195.  
  196.       if (connection)
  197.       {
  198.         if (connection->IsKindOf(CLASSINFO(wxTCPConnection)))
  199.         {
  200.           connection->m_topic = topic;
  201.           connection->m_sock  = client;
  202.           connection->m_sockstrm = stream;
  203.           connection->m_codeci = data_is;
  204.           connection->m_codeco = data_os;
  205.           client->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID);
  206.           client->SetClientData(connection);
  207.           client->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
  208.           client->Notify(TRUE);
  209.           return connection;
  210.         }
  211.         else
  212.         {
  213.           delete connection;
  214.           // and fall through to delete everything else
  215.         }
  216.       }
  217.     }
  218.   }
  219.  
  220.   // Something went wrong, delete everything
  221.   delete data_is;
  222.   delete data_os;
  223.   delete stream;
  224.   client->Destroy();
  225.  
  226.   return NULL;
  227. }
  228.  
  229. wxConnectionBase *wxTCPClient::OnMakeConnection()
  230. {
  231.   return new wxTCPConnection();
  232. }
  233.  
  234. // --------------------------------------------------------------------------
  235. // wxTCPServer
  236. // --------------------------------------------------------------------------
  237.  
  238. wxTCPServer::wxTCPServer () : wxServerBase()
  239. {
  240.   m_server = NULL;
  241. }
  242.  
  243. bool wxTCPServer::Create(const wxString& serverName)
  244. {
  245.   // Destroy previous server, if any
  246.   if (m_server)
  247.   {
  248.     m_server->SetClientData(NULL);
  249.     m_server->Destroy();
  250.     m_server = NULL;
  251.   }
  252.  
  253.   wxSockAddress *addr = GetAddressFromName(serverName);
  254.   if ( !addr )
  255.       return FALSE;
  256.  
  257. #ifdef __UNIX_LIKE__
  258.   mode_t umaskOld;
  259.   if ( addr->Type() == wxSockAddress::UNIX )
  260.   {
  261.       // ensure that the file doesn't exist as otherwise calling socket() would
  262.       // fail
  263.       int rc = remove(serverName.fn_str());
  264.       if ( rc < 0 && errno != ENOENT )
  265.       {
  266.           delete addr;
  267.  
  268.           return FALSE;
  269.       }
  270.  
  271.       // also set the umask to prevent the others from reading our file
  272.       umaskOld = umask(077);
  273.   }
  274.   else
  275.   {
  276.       // unused anyhow but shut down the compiler warnings
  277.       umaskOld = 0;
  278.   }
  279. #endif // __UNIX_LIKE__
  280.  
  281.   // Create a socket listening on the specified port
  282.   m_server = new wxSocketServer(*addr, SCKIPC_FLAGS);
  283.  
  284. #ifdef __UNIX_LIKE__
  285.   if ( addr->Type() == wxSockAddress::UNIX )
  286.   {
  287.       // restore the umask
  288.       umask(umaskOld);
  289.  
  290.       // save the file name to remove it later
  291.       m_filename = serverName;
  292.   }
  293. #endif // __UNIX_LIKE__
  294.  
  295.   delete addr;
  296.  
  297.   if (!m_server->Ok())
  298.   {
  299.     m_server->Destroy();
  300.     m_server = NULL;
  301.  
  302.     return FALSE;
  303.   }
  304.  
  305.   m_server->SetEventHandler(*gs_handler, _SERVER_ONREQUEST_ID);
  306.   m_server->SetClientData(this);
  307.   m_server->SetNotify(wxSOCKET_CONNECTION_FLAG);
  308.   m_server->Notify(TRUE);
  309.  
  310.   return TRUE;
  311. }
  312.  
  313. wxTCPServer::~wxTCPServer()
  314. {
  315.     if (m_server)
  316.     {
  317.         m_server->SetClientData(NULL);
  318.         m_server->Destroy();
  319.     }
  320.  
  321. #ifdef __UNIX_LIKE__
  322.     if ( !m_filename.empty() )
  323.     {
  324.         if ( remove(m_filename.fn_str()) != 0 )
  325.         {
  326.             wxLogDebug(_T("Stale AF_UNIX file '%s' left."), m_filename.c_str());
  327.         }
  328.     }
  329. #endif // __UNIX_LIKE__
  330. }
  331.  
  332. wxConnectionBase *wxTCPServer::OnAcceptConnection( const wxString& WXUNUSED(topic) )
  333. {
  334.   return new wxTCPConnection();
  335. }
  336.  
  337. // --------------------------------------------------------------------------
  338. // wxTCPConnection
  339. // --------------------------------------------------------------------------
  340.  
  341. wxTCPConnection::wxTCPConnection () : wxConnectionBase()
  342. {
  343.   m_sock     = NULL;
  344.   m_sockstrm = NULL;
  345.   m_codeci   = NULL;
  346.   m_codeco   = NULL;
  347. }
  348.  
  349. wxTCPConnection::wxTCPConnection(wxChar *buffer, int size)
  350.        : wxConnectionBase(buffer, size)
  351. {
  352.   m_sock     = NULL;
  353.   m_sockstrm = NULL;
  354.   m_codeci   = NULL;
  355.   m_codeco   = NULL;
  356. }
  357.  
  358. wxTCPConnection::~wxTCPConnection ()
  359. {
  360.   Disconnect();
  361.   wxDELETE(m_codeci);
  362.   wxDELETE(m_codeco);
  363.   wxDELETE(m_sockstrm);
  364.  
  365.   if (m_sock)
  366.   {
  367.     m_sock->SetClientData(NULL);
  368.     m_sock->Destroy();
  369.   }
  370. }
  371.  
  372. void wxTCPConnection::Compress(bool WXUNUSED(on))
  373. {
  374.   // Use wxLZWStream
  375. }
  376.  
  377. // Calls that CLIENT can make.
  378. bool wxTCPConnection::Disconnect ()
  379. {
  380.   if ( !GetConnected() )
  381.       return TRUE;
  382.   // Send the the disconnect message to the peer.
  383.   m_codeco->Write8(IPC_DISCONNECT);
  384.   m_sock->Notify(FALSE);
  385.   m_sock->Close();
  386.   SetConnected(false);
  387.  
  388.   return TRUE;
  389. }
  390.  
  391. bool wxTCPConnection::Execute(const wxChar *data, int size, wxIPCFormat format)
  392. {
  393.   if (!m_sock->IsConnected())
  394.     return FALSE;
  395.  
  396.   // Prepare EXECUTE message
  397.   m_codeco->Write8(IPC_EXECUTE);
  398.   m_codeco->Write8(format);
  399.  
  400.   if (size < 0)
  401.     size = wxStrlen(data) + 1;    // includes final NUL
  402.  
  403.   m_codeco->Write32(size);
  404.   m_sockstrm->Write(data, size);
  405.  
  406.   return TRUE;
  407. }
  408.  
  409. wxChar *wxTCPConnection::Request (const wxString& item, int *size, wxIPCFormat format)
  410. {
  411.   if (!m_sock->IsConnected())
  412.     return NULL;
  413.  
  414.   m_codeco->Write8(IPC_REQUEST);
  415.   m_codeco->WriteString(item);
  416.   m_codeco->Write8(format);
  417.  
  418.   // If Unpack doesn't initialize it.
  419.   int ret;
  420.  
  421.   ret = m_codeci->Read8();
  422.   if (ret == IPC_FAIL)
  423.     return NULL;
  424.   else
  425.   {
  426.     size_t s;
  427.  
  428.     s = m_codeci->Read32();
  429.     wxChar *data = GetBufferAtLeast( s );
  430.     wxASSERT_MSG(data != NULL,
  431.                  _T("Buffer too small in wxTCPConnection::Request") );
  432.     m_sockstrm->Read(data, s);
  433.  
  434.     if (size)
  435.       *size = s;
  436.     return data;
  437.   }
  438. }
  439.  
  440. bool wxTCPConnection::Poke (const wxString& item, wxChar *data, int size, wxIPCFormat format)
  441. {
  442.   if (!m_sock->IsConnected())
  443.     return FALSE;
  444.  
  445.   m_codeco->Write8(IPC_POKE);
  446.   m_codeco->WriteString(item);
  447.   m_codeco->Write8(format);
  448.  
  449.   if (size < 0)
  450.     size = wxStrlen(data) + 1;    // includes final NUL
  451.  
  452.   m_codeco->Write32(size);
  453.   m_sockstrm->Write(data, size);
  454.  
  455.   return TRUE;
  456. }
  457.  
  458. bool wxTCPConnection::StartAdvise (const wxString& item)
  459. {
  460.   int ret;
  461.  
  462.   if (!m_sock->IsConnected())
  463.     return FALSE;
  464.  
  465.   m_codeco->Write8(IPC_ADVISE_START);
  466.   m_codeco->WriteString(item);
  467.  
  468.   ret = m_codeci->Read8();
  469.  
  470.   if (ret != IPC_FAIL)
  471.     return TRUE;
  472.   else
  473.     return FALSE;
  474. }
  475.  
  476. bool wxTCPConnection::StopAdvise (const wxString& item)
  477. {
  478.   int msg;
  479.  
  480.   if (!m_sock->IsConnected())
  481.     return FALSE;
  482.  
  483.   m_codeco->Write8(IPC_ADVISE_STOP);
  484.   m_codeco->WriteString(item);
  485.  
  486.   msg = m_codeci->Read8();
  487.  
  488.   if (msg != IPC_FAIL)
  489.     return TRUE;
  490.   else
  491.     return FALSE;
  492. }
  493.  
  494. // Calls that SERVER can make
  495. bool wxTCPConnection::Advise (const wxString& item,
  496.                               wxChar *data, int size, wxIPCFormat format)
  497. {
  498.   if (!m_sock->IsConnected())
  499.     return FALSE;
  500.  
  501.   m_codeco->Write8(IPC_ADVISE);
  502.   m_codeco->WriteString(item);
  503.   m_codeco->Write8(format);
  504.  
  505.   if (size < 0)
  506.     size = wxStrlen(data) + 1;    // includes final NUL
  507.  
  508.   m_codeco->Write32(size);
  509.   m_sockstrm->Write(data, size);
  510.  
  511.   return TRUE;
  512. }
  513.  
  514. // --------------------------------------------------------------------------
  515. // wxTCPEventHandler (private class)
  516. // --------------------------------------------------------------------------
  517.  
  518. BEGIN_EVENT_TABLE(wxTCPEventHandler, wxEvtHandler)
  519.   EVT_SOCKET(_CLIENT_ONREQUEST_ID, wxTCPEventHandler::Client_OnRequest)
  520.   EVT_SOCKET(_SERVER_ONREQUEST_ID, wxTCPEventHandler::Server_OnRequest)
  521. END_EVENT_TABLE()
  522.  
  523. void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event)
  524. {
  525.   wxSocketBase *sock = event.GetSocket();
  526.   wxSocketNotify evt = event.GetSocketEvent();
  527.   wxTCPConnection *connection = (wxTCPConnection *)(sock->GetClientData());
  528.  
  529.   // This socket is being deleted; skip this event
  530.   if (!connection)
  531.     return;
  532.  
  533.   int msg = 0;
  534.   wxDataInputStream *codeci;
  535.   wxDataOutputStream *codeco;
  536.   wxSocketStream *sockstrm;
  537.   wxString topic_name = connection->m_topic;
  538.   wxString item;
  539.  
  540.   // We lost the connection: destroy everything
  541.   if (evt == wxSOCKET_LOST)
  542.   {
  543.     sock->Notify(FALSE);
  544.     sock->Close();
  545.     connection->OnDisconnect();
  546.     return;
  547.   }
  548.  
  549.   // Receive message number.
  550.   codeci = connection->m_codeci;
  551.   codeco = connection->m_codeco;
  552.   sockstrm = connection->m_sockstrm;
  553.   msg = codeci->Read8();
  554.  
  555.   switch (msg)
  556.   {
  557.   case IPC_EXECUTE:
  558.   {
  559.     wxChar *data;
  560.     size_t size;
  561.     wxIPCFormat format;
  562.  
  563.     format = (wxIPCFormat)codeci->Read8();
  564.     size = codeci->Read32();
  565.     data = connection->GetBufferAtLeast( size );
  566.     wxASSERT_MSG(data != NULL,
  567.                  _T("Buffer too small in wxTCPEventHandler::Client_OnRequest") );
  568.     sockstrm->Read(data, size);
  569.  
  570.     connection->OnExecute (topic_name, data, size, format);
  571.  
  572.     break;
  573.   }
  574.   case IPC_ADVISE:
  575.   {
  576.     wxChar *data;
  577.     size_t size;
  578.     wxIPCFormat format;
  579.  
  580.     item = codeci->ReadString();
  581.     format = (wxIPCFormat)codeci->Read8();
  582.     size = codeci->Read32();
  583.     data = connection->GetBufferAtLeast( size );
  584.     wxASSERT_MSG(data != NULL,
  585.                  _T("Buffer too small in wxTCPEventHandler::Client_OnRequest") );
  586.     sockstrm->Read(data, size);
  587.  
  588.     connection->OnAdvise (topic_name, item, data, size, format);
  589.  
  590.     break;
  591.   }
  592.   case IPC_ADVISE_START:
  593.   {
  594.     item = codeci->ReadString();
  595.  
  596.     bool ok = connection->OnStartAdvise (topic_name, item);
  597.     if (ok)
  598.       codeco->Write8(IPC_ADVISE_START);
  599.     else
  600.       codeco->Write8(IPC_FAIL);
  601.  
  602.     break;
  603.   }
  604.   case IPC_ADVISE_STOP:
  605.   {
  606.     item = codeci->ReadString();
  607.  
  608.     bool ok = connection->OnStopAdvise (topic_name, item);
  609.     if (ok)
  610.       codeco->Write8(IPC_ADVISE_STOP);
  611.     else
  612.       codeco->Write8(IPC_FAIL);
  613.  
  614.     break;
  615.   }
  616.   case IPC_POKE:
  617.   {
  618.     wxIPCFormat format;
  619.     size_t size;
  620.     wxChar *data;
  621.  
  622.     item = codeci->ReadString();
  623.     format = (wxIPCFormat)codeci->Read8();
  624.     size = codeci->Read32();
  625.     data = connection->GetBufferAtLeast( size );
  626.     wxASSERT_MSG(data != NULL,
  627.                  _T("Buffer too small in wxTCPEventHandler::Client_OnRequest") );
  628.     sockstrm->Read(data, size);
  629.  
  630.     connection->OnPoke (topic_name, item, data, size, format);
  631.  
  632.     break;
  633.   }
  634.   case IPC_REQUEST:
  635.   {
  636.     wxIPCFormat format;
  637.  
  638.     item = codeci->ReadString();
  639.     format = (wxIPCFormat)codeci->Read8();
  640.  
  641.     int user_size = -1;
  642.     wxChar *user_data = connection->OnRequest (topic_name, item, &user_size, format);
  643.  
  644.     if (user_data)
  645.     {
  646.       codeco->Write8(IPC_REQUEST_REPLY);
  647.  
  648.       if (user_size == -1)
  649.         user_size = wxStrlen(user_data) + 1;      // includes final NUL
  650.  
  651.       codeco->Write32(user_size);
  652.       sockstrm->Write(user_data, user_size);
  653.     }
  654.     else
  655.       codeco->Write8(IPC_FAIL);
  656.  
  657.     break;
  658.   }
  659.   case IPC_DISCONNECT:
  660.   {
  661.     sock->Notify(FALSE);
  662.     sock->Close();
  663.     connection->SetConnected(false);
  664.     connection->OnDisconnect();
  665.     break;
  666.   }
  667.   default:
  668.     codeco->Write8(IPC_FAIL);
  669.     break;
  670.   }
  671. }
  672.  
  673. void wxTCPEventHandler::Server_OnRequest(wxSocketEvent &event)
  674. {
  675.   wxSocketServer *server = (wxSocketServer *) event.GetSocket();
  676.   wxTCPServer *ipcserv = (wxTCPServer *) server->GetClientData();
  677.  
  678.   // This socket is being deleted; skip this event
  679.   if (!ipcserv)
  680.     return;
  681.  
  682.   if (event.GetSocketEvent() != wxSOCKET_CONNECTION)
  683.     return;
  684.  
  685.   // Accept the connection, getting a new socket
  686.   wxSocketBase *sock = server->Accept();
  687.   if (!sock->Ok())
  688.   {
  689.     sock->Destroy();
  690.     return;
  691.   }
  692.  
  693.   wxSocketStream *stream     = new wxSocketStream(*sock);
  694.   wxDataInputStream *codeci  = new wxDataInputStream(*stream);
  695.   wxDataOutputStream *codeco = new wxDataOutputStream(*stream);
  696.  
  697.   int msg;
  698.   msg = codeci->Read8();
  699.  
  700.   if (msg == IPC_CONNECT)
  701.   {
  702.     wxString topic_name;
  703.     topic_name = codeci->ReadString();
  704.  
  705.     wxTCPConnection *new_connection =
  706.          (wxTCPConnection *)ipcserv->OnAcceptConnection (topic_name);
  707.  
  708.     if (new_connection)
  709.     {
  710.       if (new_connection->IsKindOf(CLASSINFO(wxTCPConnection)))
  711.       {
  712.         // Acknowledge success
  713.         codeco->Write8(IPC_CONNECT);
  714.         new_connection->m_topic = topic_name;
  715.         new_connection->m_sock = sock;
  716.         new_connection->m_sockstrm = stream;
  717.         new_connection->m_codeci = codeci;
  718.         new_connection->m_codeco = codeco;
  719.         sock->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID);
  720.         sock->SetClientData(new_connection);
  721.         sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
  722.         sock->Notify(TRUE);
  723.         return;
  724.       }
  725.       else
  726.       {
  727.         delete new_connection;
  728.         // and fall through to delete everything else
  729.       }
  730.     }
  731.   }
  732.  
  733.   // Something went wrong, send failure message and delete everything
  734.   codeco->Write8(IPC_FAIL);
  735.  
  736.   delete codeco;
  737.   delete codeci;
  738.   delete stream;
  739.   sock->Destroy();
  740. }
  741.  
  742. // --------------------------------------------------------------------------
  743. // wxTCPEventHandlerModule (private class)
  744. // --------------------------------------------------------------------------
  745.  
  746. class WXDLLEXPORT wxTCPEventHandlerModule: public wxModule
  747. {
  748.   DECLARE_DYNAMIC_CLASS(wxTCPEventHandlerModule)
  749.  
  750. public:
  751.   bool OnInit() { gs_handler = new wxTCPEventHandler(); return TRUE; }
  752.   void OnExit() { wxDELETE(gs_handler); }
  753. };
  754.  
  755. IMPLEMENT_DYNAMIC_CLASS(wxTCPEventHandlerModule, wxModule)
  756.  
  757.  
  758. #endif
  759.     // wxUSE_SOCKETS && wxUSE_IPC
  760.