X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fcc6dddd1f1da49f94767ff148eaa3f1d3ca9367..d10e22fe8ad283f37b1809349028ffc282e393ce:/src/common/sckipc.cpp?ds=sidebyside diff --git a/src/common/sckipc.cpp b/src/common/sckipc.cpp index 4532de83a8..f2b33bb2e2 100644 --- a/src/common/sckipc.cpp +++ b/src/common/sckipc.cpp @@ -1,48 +1,59 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: sckipc.cpp +// Name: src/common/sckipc.cpp // Purpose: Interprocess communication implementation (wxSocket version) -// Author: Julian Smart, Guilhem Lavaux +// Author: Julian Smart // Modified by: Guilhem Lavaux (big rewrite) May 1997, 1998 +// Guillermo Rodriguez (updated for wxSocket v2) Jan 2000 +// (callbacks deprecated) Mar 2000 +// Vadim Zeitlin (added support for Unix sockets) Apr 2002 // Created: 1993 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart 1993, Guilhem Lavaux 1997, 1998 -// Licence: wxWindows license +// Copyright: (c) Julian Smart 1993 +// (c) Guilhem Lavaux 1997, 1998 +// (c) 2000 Guillermo Rodriguez +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "sckipc.h" -#endif +// ========================================================================== +// declarations +// ========================================================================== + +// -------------------------------------------------------------------------- +// headers +// -------------------------------------------------------------------------- // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif +#if wxUSE_SOCKETS && wxUSE_IPC && wxUSE_STREAMS + +#include "wx/sckipc.h" + #ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/event.h" + #include "wx/module.h" #endif #include #include +#include #include "wx/socket.h" -#include "wx/sckipc.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif -#if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxTCPServer, wxServerBase) -IMPLEMENT_DYNAMIC_CLASS(wxTCPClient, wxClientBase) -IMPLEMENT_DYNAMIC_CLASS(wxTCPConnection, wxConnectionBase) -#endif +// -------------------------------------------------------------------------- +// macros and constants +// -------------------------------------------------------------------------- // It seems to be already defined somewhere in the Xt includes. #ifndef __XT__ // Message codes -enum { +enum +{ IPC_EXECUTE = 1, IPC_REQUEST, IPC_POKE, @@ -57,23 +68,88 @@ enum { }; #endif -void Server_OnRequest(wxSocketServer& server, - wxSocketBase::wxRequestEvent evt, - char *cdata); -void Client_OnRequest(wxSocketBase& sock, - wxSocketBase::wxRequestEvent evt, - char *cdata); +// All sockets will be created with the following flags +#define SCKIPC_FLAGS (wxSOCKET_WAITALL) + +// headers needed for umask() +#ifdef __UNIX_LIKE__ + #include + #include +#endif // __UNIX_LIKE__ + +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +// get the address object for the given server name, the caller must delete it +static wxSockAddress * +GetAddressFromName(const wxString& serverName, const wxString& host = wxEmptyString) +{ + // we always use INET sockets under non-Unix systems +#if defined(__UNIX__) && !defined(__WINDOWS__) && !defined(__WINE__) && (!defined(__WXMAC__) || defined(__DARWIN__)) + // under Unix, if the server name looks like a path, create a AF_UNIX + // socket instead of AF_INET one + if ( serverName.Find(_T('/')) != wxNOT_FOUND ) + { + wxUNIXaddress *addr = new wxUNIXaddress; + addr->Filename(serverName); + + return addr; + } +#endif // Unix/!Unix + { + wxIPV4address *addr = new wxIPV4address; + addr->Service(serverName); + if ( !host.empty() ) + { + addr->Hostname(host); + } + + return addr; + } +} + +// -------------------------------------------------------------------------- +// wxTCPEventHandler stuff (private class) +// -------------------------------------------------------------------------- + +class wxTCPEventHandler : public wxEvtHandler +{ +public: + wxTCPEventHandler() : wxEvtHandler() {} + + void Client_OnRequest(wxSocketEvent& event); + void Server_OnRequest(wxSocketEvent& event); + + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxTCPEventHandler) +}; + +enum +{ + _CLIENT_ONREQUEST_ID = 1000, + _SERVER_ONREQUEST_ID +}; + +static wxTCPEventHandler *gs_handler = NULL; -// --------------------------------------------------------------------------- +// ========================================================================== +// implementation +// ========================================================================== + +IMPLEMENT_DYNAMIC_CLASS(wxTCPServer, wxServerBase) +IMPLEMENT_DYNAMIC_CLASS(wxTCPClient, wxClientBase) +IMPLEMENT_CLASS(wxTCPConnection, wxConnectionBase) + +// -------------------------------------------------------------------------- // wxTCPClient -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- -wxTCPClient::wxTCPClient (void) - : wxClientBase() +wxTCPClient::wxTCPClient () : wxClientBase() { } -wxTCPClient::~wxTCPClient (void) +wxTCPClient::~wxTCPClient () { } @@ -85,170 +161,273 @@ bool wxTCPClient::ValidHost(const wxString& host) } wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host, - const wxString& server_name, + const wxString& serverName, const wxString& topic) { - wxIPV4address addr; - wxSocketHandler *hsock = &wxSocketHandler::Master(); - wxSocketClient *client = hsock->CreateClient(); + wxSockAddress *addr = GetAddressFromName(serverName, host); + if ( !addr ) + return NULL; + + wxSocketClient *client = new wxSocketClient(SCKIPC_FLAGS); wxSocketStream *stream = new wxSocketStream(*client); - wxDataStream data_s(*stream); - - client->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST); - addr.Service(server_name); - addr.Hostname(host); - - if (!client->Connect(addr)) { - delete client; - return NULL; - } - client->Notify(FALSE); - - // Send topic name, and enquire whether this has succeeded - unsigned char msg; - - data_s.Write8(IPC_CONNECT); - data_s.WriteString(topic); - - msg = data_s.Read8(); - - // OK! Confirmation. - if (msg == IPC_CONNECT) { - wxTCPConnection *connection = (wxTCPConnection *)OnMakeConnection (); - if (connection) { - if (!connection->IsKindOf(CLASSINFO(wxTCPConnection))) { - delete connection; - return NULL; + wxDataInputStream *data_is = new wxDataInputStream(*stream); + wxDataOutputStream *data_os = new wxDataOutputStream(*stream); + + bool ok = client->Connect(*addr); + delete addr; + + if ( ok ) + { + unsigned char msg; + + // Send topic name, and enquire whether this has succeeded + data_os->Write8(IPC_CONNECT); + data_os->WriteString(topic); + + msg = data_is->Read8(); + + // OK! Confirmation. + if (msg == IPC_CONNECT) + { + wxTCPConnection *connection = (wxTCPConnection *)OnMakeConnection (); + + if (connection) + { + if (connection->IsKindOf(CLASSINFO(wxTCPConnection))) + { + connection->m_topic = topic; + connection->m_sock = client; + connection->m_sockstrm = stream; + connection->m_codeci = data_is; + connection->m_codeco = data_os; + client->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID); + client->SetClientData(connection); + client->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG); + client->Notify(true); + return connection; + } + else + { + delete connection; + // and fall through to delete everything else + } } - connection->m_topic = topic; - client->Callback(Client_OnRequest); - client->CallbackData((char *)connection); - client->Notify(TRUE); - return connection; - } else { - delete client; - return NULL; } - } else { - delete client; - return NULL; } + + // Something went wrong, delete everything + delete data_is; + delete data_os; + delete stream; + client->Destroy(); + return NULL; } wxConnectionBase *wxTCPClient::OnMakeConnection() { - return new wxTCPConnection; + return new wxTCPConnection(); } -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- // wxTCPServer -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- -wxTCPServer::wxTCPServer (void) - : wxServerBase() +wxTCPServer::wxTCPServer () : wxServerBase() { + m_server = NULL; } -bool wxTCPServer::Create(const wxString& server_name) +bool wxTCPServer::Create(const wxString& serverName) { - wxIPV4address addr; - wxSocketHandler *hsock = &wxSocketHandler::Master(); - wxSocketServer *server; + // Destroy previous server, if any + if (m_server) + { + m_server->SetClientData(NULL); + m_server->Destroy(); + m_server = NULL; + } + + wxSockAddress *addr = GetAddressFromName(serverName); + if ( !addr ) + return false; + +#ifdef __UNIX_LIKE__ + mode_t umaskOld; + if ( addr->Type() == wxSockAddress::UNIX ) + { + // ensure that the file doesn't exist as otherwise calling socket() would + // fail + int rc = remove(serverName.fn_str()); + if ( rc < 0 && errno != ENOENT ) + { + delete addr; + + return false; + } + + // also set the umask to prevent the others from reading our file + umaskOld = umask(077); + } + else + { + // unused anyhow but shut down the compiler warnings + umaskOld = 0; + } +#endif // __UNIX_LIKE__ + + // Create a socket listening on the specified port + m_server = new wxSocketServer(*addr, SCKIPC_FLAGS); + +#ifdef __UNIX_LIKE__ + if ( addr->Type() == wxSockAddress::UNIX ) + { + // restore the umask + umask(umaskOld); + + // save the file name to remove it later + m_filename = serverName; + } +#endif // __UNIX_LIKE__ - addr.Service(server_name); + delete addr; - // Create a socket listening on specified port - server = hsock->CreateServer(addr); - server->Callback((wxSocketBase::wxSockCbk)Server_OnRequest); - server->SetNotify(wxSocketBase::REQ_ACCEPT); + if (!m_server->Ok()) + { + m_server->Destroy(); + m_server = NULL; - server->CallbackData((char *)this); + return false; + } + + m_server->SetEventHandler(*gs_handler, _SERVER_ONREQUEST_ID); + m_server->SetClientData(this); + m_server->SetNotify(wxSOCKET_CONNECTION_FLAG); + m_server->Notify(true); - return TRUE; + return true; } -wxTCPServer::~wxTCPServer (void) +wxTCPServer::~wxTCPServer() { + if (m_server) + { + m_server->SetClientData(NULL); + m_server->Destroy(); + } + +#ifdef __UNIX_LIKE__ + if ( !m_filename.empty() ) + { + if ( remove(m_filename.fn_str()) != 0 ) + { + wxLogDebug(_T("Stale AF_UNIX file '%s' left."), m_filename.c_str()); + } + } +#endif // __UNIX_LIKE__ } -wxConnectionBase *wxTCPServer::OnAcceptConnection(const wxString& topic) +wxConnectionBase *wxTCPServer::OnAcceptConnection( const wxString& WXUNUSED(topic) ) { return new wxTCPConnection(); } -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- // wxTCPConnection -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- + +wxTCPConnection::wxTCPConnection () : wxConnectionBase() +{ + m_sock = NULL; + m_sockstrm = NULL; + m_codeci = NULL; + m_codeco = NULL; +} -wxTCPConnection::wxTCPConnection (void) - : wxConnectionBase(), - m_sock(NULL), m_sockstrm(NULL), m_codec(NULL) +wxTCPConnection::wxTCPConnection(wxChar *buffer, int size) + : wxConnectionBase(buffer, size) { + m_sock = NULL; + m_sockstrm = NULL; + m_codeci = NULL; + m_codeco = NULL; } -wxTCPConnection::~wxTCPConnection (void) +wxTCPConnection::~wxTCPConnection () { - wxDELETE(m_sock); - wxDELETE(m_codec); + Disconnect(); + wxDELETE(m_codeci); + wxDELETE(m_codeco); wxDELETE(m_sockstrm); + + if (m_sock) + { + m_sock->SetClientData(NULL); + m_sock->Destroy(); + } } -void wxTCPConnection::Compress(bool on) +void wxTCPConnection::Compress(bool WXUNUSED(on)) { // Use wxLZWStream } // Calls that CLIENT can make. -bool wxTCPConnection::Disconnect (void) +bool wxTCPConnection::Disconnect () { + if ( !GetConnected() ) + return true; // Send the the disconnect message to the peer. - m_codec->Write8(IPC_DISCONNECT); + m_codeco->Write8(IPC_DISCONNECT); + m_sock->Notify(false); m_sock->Close(); + SetConnected(false); - return TRUE; + return true; } -bool wxTCPConnection::Execute (char *data, int size, wxDataFormat format) +bool wxTCPConnection::Execute(const wxChar *data, int size, wxIPCFormat format) { if (!m_sock->IsConnected()) - return FALSE; + return false; // Prepare EXECUTE message - m_codec->Write8(IPC_EXECUTE); - m_codec->Write8(format); + m_codeco->Write8(IPC_EXECUTE); + m_codeco->Write8(format); + if (size < 0) - m_codec->WriteString(data); - else { - m_codec->Write32(size); - m_codec->Write(data, size); - } + size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL + + m_codeco->Write32(size); + m_sockstrm->Write(data, size); - return TRUE; + return true; } -char *wxTCPConnection::Request (const wxString& item, int *size, wxDataFormat format) +wxChar *wxTCPConnection::Request (const wxString& item, int *size, wxIPCFormat format) { if (!m_sock->IsConnected()) return NULL; - m_codec->Write8(IPC_REQUEST); - m_codec->WriteString(item); - m_codec->Write8(format); + m_codeco->Write8(IPC_REQUEST); + m_codeco->WriteString(item); + m_codeco->Write8(format); // If Unpack doesn't initialize it. int ret; - ret = m_codec->Read8(); + ret = m_codeci->Read8(); if (ret == IPC_FAIL) return NULL; - else { + else + { size_t s; - char *data = NULL; - s = m_codec->Read32(); - data = new char[s]; - m_codec->Read(data, s); + s = m_codeci->Read32(); + wxChar *data = GetBufferAtLeast( s ); + wxASSERT_MSG(data != NULL, + _T("Buffer too small in wxTCPConnection::Request") ); + m_sockstrm->Read(data, s); if (size) *size = s; @@ -256,22 +435,22 @@ char *wxTCPConnection::Request (const wxString& item, int *size, wxDataFormat fo } } -bool wxTCPConnection::Poke (const wxString& item, char *data, int size, wxDataFormat format) +bool wxTCPConnection::Poke (const wxString& item, wxChar *data, int size, wxIPCFormat format) { if (!m_sock->IsConnected()) - return FALSE; + return false; + + m_codeco->Write8(IPC_POKE); + m_codeco->WriteString(item); + m_codeco->Write8(format); - m_codec->Write8(IPC_POKE); - m_codec->WriteString(item); - m_codec->Write8(format); if (size < 0) - m_codec->WriteString(data); - else { - m_codec->Write32(size); - m_codec->Write(data, size); - } + size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL - return TRUE; + m_codeco->Write32(size); + m_sockstrm->Write(data, size); + + return true; } bool wxTCPConnection::StartAdvise (const wxString& item) @@ -279,17 +458,17 @@ bool wxTCPConnection::StartAdvise (const wxString& item) int ret; if (!m_sock->IsConnected()) - return FALSE; + return false; - m_codec->Write8(IPC_ADVISE_START); - m_codec->WriteString(item); + m_codeco->Write8(IPC_ADVISE_START); + m_codeco->WriteString(item); - ret = m_codec->Read8(); + ret = m_codeci->Read8(); if (ret != IPC_FAIL) - return TRUE; + return true; else - return FALSE; + return false; } bool wxTCPConnection::StopAdvise (const wxString& item) @@ -297,211 +476,281 @@ bool wxTCPConnection::StopAdvise (const wxString& item) int msg; if (!m_sock->IsConnected()) - return FALSE; + return false; - m_codec->Write8(IPC_ADVISE_STOP); - m_codec->WriteString(item); + m_codeco->Write8(IPC_ADVISE_STOP); + m_codeco->WriteString(item); - msg = m_codec->Read8(); + msg = m_codeci->Read8(); if (msg != IPC_FAIL) - return TRUE; + return true; else - return FALSE; + return false; } // Calls that SERVER can make bool wxTCPConnection::Advise (const wxString& item, - char *data, int size, wxDataFormat format) + wxChar *data, int size, wxIPCFormat format) { if (!m_sock->IsConnected()) - return FALSE; + return false; + + m_codeco->Write8(IPC_ADVISE); + m_codeco->WriteString(item); + m_codeco->Write8(format); - m_codec->Write8(IPC_ADVISE); - m_codec->WriteString(item); - m_codec->Write8(format); if (size < 0) - m_codec->WriteString(data); - else { - m_codec->Write32(size); - m_codec->Write(data, size); - } + size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL + + m_codeco->Write32(size); + m_sockstrm->Write(data, size); - return TRUE; + return true; } -void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt, - char *cdata) +// -------------------------------------------------------------------------- +// wxTCPEventHandler (private class) +// -------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(wxTCPEventHandler, wxEvtHandler) + EVT_SOCKET(_CLIENT_ONREQUEST_ID, wxTCPEventHandler::Client_OnRequest) + EVT_SOCKET(_SERVER_ONREQUEST_ID, wxTCPEventHandler::Server_OnRequest) +END_EVENT_TABLE() + +void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event) { - int msg = 0; - wxTCPConnection *connection = (wxTCPConnection *)cdata; - wxDataStream *codec; + wxSocketBase *sock = event.GetSocket(); + wxSocketNotify evt = event.GetSocketEvent(); + wxTCPConnection *connection = (wxTCPConnection *)(sock->GetClientData()); + + // This socket is being deleted; skip this event + if (!connection) + return; + + wxDataInputStream *codeci; + wxDataOutputStream *codeco; + wxSocketStream *sockstrm; wxString topic_name = connection->m_topic; wxString item; - // The socket handler signals us that we lost the connection: destroy all. - if (evt == wxSocketBase::EVT_LOST) { - sock.Close(); + // We lost the connection: destroy everything + if (evt == wxSOCKET_LOST) + { + sock->Notify(false); + sock->Close(); connection->OnDisconnect(); return; } // Receive message number. - codec = connection->m_codec; - msg = codec->Read8(); - - switch (msg) { - case IPC_EXECUTE: { - char *data; - size_t size; - wxDataFormat format; - - format = (wxDataFormat)codec->Read8(); - size = codec->Read32(); - data = new char[size]; - codec->Read(data, size); + codeci = connection->m_codeci; + codeco = connection->m_codeco; + sockstrm = connection->m_sockstrm; + int msg = codeci->Read8(); + + switch (msg) + { + case IPC_EXECUTE: + { + wxChar *data; + size_t size; + wxIPCFormat format; + + format = (wxIPCFormat)codeci->Read8(); + size = codeci->Read32(); + data = connection->GetBufferAtLeast( size ); + wxASSERT_MSG(data != NULL, + _T("Buffer too small in wxTCPEventHandler::Client_OnRequest") ); + sockstrm->Read(data, size); connection->OnExecute (topic_name, data, size, format); - delete [] data; break; } - case IPC_ADVISE: { - char *data; + case IPC_ADVISE: + { + wxChar *data; size_t size; - wxDataFormat format; - - item = codec->ReadString(); - format = (wxDataFormat)codec->Read8(); - size = codec->Read32(); - data = new char[size]; - codec->Read(data, size); - + wxIPCFormat format; + + item = codeci->ReadString(); + format = (wxIPCFormat)codeci->Read8(); + size = codeci->Read32(); + data = connection->GetBufferAtLeast( size ); + wxASSERT_MSG(data != NULL, + _T("Buffer too small in wxTCPEventHandler::Client_OnRequest") ); + sockstrm->Read(data, size); + connection->OnAdvise (topic_name, item, data, size, format); - delete [] data; break; } - case IPC_ADVISE_START: { - item = codec->ReadString(); + case IPC_ADVISE_START: + { + item = codeci->ReadString(); bool ok = connection->OnStartAdvise (topic_name, item); if (ok) - codec->Write8(IPC_ADVISE_START); + codeco->Write8(IPC_ADVISE_START); else - codec->Write8(IPC_FAIL); + codeco->Write8(IPC_FAIL); break; } - case IPC_ADVISE_STOP: { - item = codec->ReadString(); + case IPC_ADVISE_STOP: + { + item = codeci->ReadString(); bool ok = connection->OnStopAdvise (topic_name, item); if (ok) - codec->Write8(IPC_ADVISE_STOP); + codeco->Write8(IPC_ADVISE_STOP); else - codec->Write8(IPC_FAIL); + codeco->Write8(IPC_FAIL); break; } - case IPC_POKE: { - wxDataFormat format; + case IPC_POKE: + { + wxIPCFormat format; size_t size; - char *data; - - item = codec->ReadString(); - format = (wxDataFormat)codec->Read8(); - size = codec->Read32(); - data = new char[size]; - codec->Read(data, size); - - connection->OnPoke (topic_name, item, data, size, format); + wxChar *data; - delete [] data; + item = codeci->ReadString(); + format = (wxIPCFormat)codeci->Read8(); + size = codeci->Read32(); + data = connection->GetBufferAtLeast( size ); + wxASSERT_MSG(data != NULL, + _T("Buffer too small in wxTCPEventHandler::Client_OnRequest") ); + sockstrm->Read(data, size); + + connection->OnPoke (topic_name, item, data, size, format); break; } - case IPC_REQUEST: { - wxDataFormat format; + case IPC_REQUEST: + { + wxIPCFormat format; - item = codec->ReadString(); - format = (wxDataFormat)codec->Read8(); + item = codeci->ReadString(); + format = (wxIPCFormat)codeci->Read8(); int user_size = -1; - char *user_data = connection->OnRequest (topic_name, item, &user_size, format); - - if (user_data) { - codec->Write8(IPC_REQUEST_REPLY); - if (user_size != -1) { - codec->Write32(user_size); - codec->Write(user_data, user_size); - } else - codec->WriteString(user_data); - } else - codec->Write8(IPC_FAIL); + wxChar *user_data = connection->OnRequest (topic_name, item, &user_size, format); + + if (user_data) + { + codeco->Write8(IPC_REQUEST_REPLY); + + if (user_size == -1) + user_size = (wxStrlen(user_data) + 1) * sizeof(wxChar); // includes final NUL + + codeco->Write32(user_size); + sockstrm->Write(user_data, user_size); + } + else + codeco->Write8(IPC_FAIL); break; } - case IPC_DISCONNECT: { - sock.Close(); + case IPC_DISCONNECT: + { + sock->Notify(false); + sock->Close(); + connection->SetConnected(false); connection->OnDisconnect(); break; } default: - codec->Write8(IPC_FAIL); + codeco->Write8(IPC_FAIL); break; } } -void Server_OnRequest(wxSocketServer& server, - wxSocketBase::wxRequestEvent evt, char *cdata) +void wxTCPEventHandler::Server_OnRequest(wxSocketEvent &event) { - wxTCPServer *ipcserv = (wxTCPServer *)cdata; - wxSocketStream *stream; - wxDataStream *codec; + wxSocketServer *server = (wxSocketServer *) event.GetSocket(); + wxTCPServer *ipcserv = (wxTCPServer *) server->GetClientData(); - if (evt != wxSocketBase::EVT_ACCEPT) + // This socket is being deleted; skip this event + if (!ipcserv) return; - /* Accept the connection, getting a new socket */ - wxSocketBase *sock = server.Accept(); - sock->Notify(FALSE); - sock->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST); - - stream = new wxSocketStream(*sock); - codec = new wxDataStream(*stream); + if (event.GetSocketEvent() != wxSOCKET_CONNECTION) + return; + // Accept the connection, getting a new socket + wxSocketBase *sock = server->Accept(); if (!sock->Ok()) + { + sock->Destroy(); return; + } + + wxSocketStream *stream = new wxSocketStream(*sock); + wxDataInputStream *codeci = new wxDataInputStream(*stream); + wxDataOutputStream *codeco = new wxDataOutputStream(*stream); int msg; - msg = codec->Read8(); + msg = codeci->Read8(); - if (msg == IPC_CONNECT) { + if (msg == IPC_CONNECT) + { wxString topic_name; - topic_name = codec->ReadString(); + topic_name = codeci->ReadString(); - /* Register new socket with the notifier */ wxTCPConnection *new_connection = (wxTCPConnection *)ipcserv->OnAcceptConnection (topic_name); - if (new_connection) { - if (!new_connection->IsKindOf(CLASSINFO(wxTCPConnection))) { - delete new_connection; - codec->Write8(IPC_FAIL); + + if (new_connection) + { + if (new_connection->IsKindOf(CLASSINFO(wxTCPConnection))) + { + // Acknowledge success + codeco->Write8(IPC_CONNECT); + new_connection->m_topic = topic_name; + new_connection->m_sock = sock; + new_connection->m_sockstrm = stream; + new_connection->m_codeci = codeci; + new_connection->m_codeco = codeco; + sock->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID); + sock->SetClientData(new_connection); + sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG); + sock->Notify(true); return; } - // Acknowledge success - codec->Write8(IPC_CONNECT); - - new_connection->m_topic = topic_name; - new_connection->m_sockstrm = stream; - new_connection->m_codec = codec; - sock->Callback(Client_OnRequest); - sock->CallbackData((char *)new_connection); - sock->Notify(TRUE); - } else { - // Send failure message - codec->Write8(IPC_FAIL); + else + { + delete new_connection; + // and fall through to delete everything else + } } } + + // Something went wrong, send failure message and delete everything + codeco->Write8(IPC_FAIL); + + delete codeco; + delete codeci; + delete stream; + sock->Destroy(); } + +// -------------------------------------------------------------------------- +// wxTCPEventHandlerModule (private class) +// -------------------------------------------------------------------------- + +class wxTCPEventHandlerModule: public wxModule +{ + DECLARE_DYNAMIC_CLASS(wxTCPEventHandlerModule) + +public: + bool OnInit() { gs_handler = new wxTCPEventHandler(); return true; } + void OnExit() { wxDELETE(gs_handler); } +}; + +IMPLEMENT_DYNAMIC_CLASS(wxTCPEventHandlerModule, wxModule) + + +#endif + // wxUSE_SOCKETS && wxUSE_IPC && wxUSE_STREAMS