+// --------------------------------------------------------------------------
+// macros and constants
+// --------------------------------------------------------------------------
+
+namespace
+{
+
+// Message codes (don't change them to avoid breaking the existing code using
+// wxIPC protocol!)
+enum IPCCode
+{
+ IPC_EXECUTE = 1,
+ IPC_REQUEST = 2,
+ IPC_POKE = 3,
+ IPC_ADVISE_START = 4,
+ IPC_ADVISE_REQUEST = 5,
+ IPC_ADVISE = 6,
+ IPC_ADVISE_STOP = 7,
+ IPC_REQUEST_REPLY = 8,
+ IPC_FAIL = 9,
+ IPC_CONNECT = 10,
+ IPC_DISCONNECT = 11,
+ IPC_MAX
+};
+
+} // anonymous namespace
+
+// headers needed for umask()
+#ifdef __UNIX_LIKE__
+ #include <sys/types.h>
+ #include <sys/stat.h>
+#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__)
+ // under Unix, if the server name looks like a path, create a AF_UNIX
+ // socket instead of AF_INET one
+ if ( serverName.Find(wxT('/')) != 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);
+
+private:
+ void HandleDisconnect(wxTCPConnection *connection);
+
+ DECLARE_EVENT_TABLE()
+ wxDECLARE_NO_COPY_CLASS(wxTCPEventHandler);
+};
+
+enum
+{
+ _CLIENT_ONREQUEST_ID = 1000,
+ _SERVER_ONREQUEST_ID
+};
+
+// --------------------------------------------------------------------------
+// wxTCPEventHandlerModule (private class)
+// --------------------------------------------------------------------------
+
+class wxTCPEventHandlerModule : public wxModule
+{
+public:
+ wxTCPEventHandlerModule() : wxModule() { }
+
+ // get the global wxTCPEventHandler creating it if necessary
+ static wxTCPEventHandler& GetHandler()
+ {
+ if ( !ms_handler )
+ ms_handler = new wxTCPEventHandler;
+
+ return *ms_handler;
+ }
+
+ // as ms_handler is initialized on demand, don't do anything in OnInit()
+ virtual bool OnInit() { return true; }
+ virtual void OnExit() { wxDELETE(ms_handler); }
+
+private:
+ static wxTCPEventHandler *ms_handler;
+
+ DECLARE_DYNAMIC_CLASS(wxTCPEventHandlerModule)
+ wxDECLARE_NO_COPY_CLASS(wxTCPEventHandlerModule);
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxTCPEventHandlerModule, wxModule)
+
+wxTCPEventHandler *wxTCPEventHandlerModule::ms_handler = NULL;
+
+// --------------------------------------------------------------------------
+// wxIPCSocketStreams
+// --------------------------------------------------------------------------
+
+#define USE_BUFFER
+
+// this class contains the various (related) streams used by wxTCPConnection
+// and also provides a way to read from the socket stream directly
+//
+// for writing to the stream use the IPCOutput class below
+class wxIPCSocketStreams
+{
+public:
+ // ctor initializes all the streams on top of the given socket
+ //
+ // note that we use a bigger than default buffer size which matches the
+ // typical Ethernet MTU (minus TCP header overhead)
+ wxIPCSocketStreams(wxSocketBase& sock)
+ : m_socketStream(sock),
+#ifdef USE_BUFFER
+ m_bufferedOut(m_socketStream, 1448),
+#else
+ m_bufferedOut(m_socketStream),