implemented IPC using Unix domain sockets

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15114 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2002-04-12 15:13:53 +00:00
parent 70914290a1
commit 0dbfd66d0b
4 changed files with 119 additions and 23 deletions

View File

@@ -131,6 +131,7 @@ Unix (Base/GUI):
- wxWindows may be built using BSD and Solaris (and possibly other) make
programs and not only GNU make
- wxTCP-based IPC classes now support communicating over Unix domain sockets
All (GUI):

View File

@@ -48,8 +48,14 @@ element of some messages. To create a connection (a conversation in
Windows parlance), the client application sends the message
MakeConnection to the client object, with a string service name to
identify the server and a topic name to identify the topic for the
duration of the connection. Under Unix, the service name must contain an
integer port identifier.
duration of the connection. Under Unix, the service name may be either an
integer port identifier in which case an Internet domain socket will be used
for the communications or a valid file name (which shouldn't exist and will be
deleted afterwards) in which case a Unix domain socket is created.
{\bf SECURITY NOTE:} Using Internet domain sockets if extremely insecure for
IPC as there is absolutely no access control for them, use Unix domain sockets
whenever possible!
The server then responds and either vetoes the connection or allows it.
If allowed, a connection object is created which persists until the

View File

@@ -122,6 +122,11 @@ public:
protected:
wxSocketServer *m_server;
#ifdef __UNIX_LIKE__
// the name of the file associated to the Unix domain socket, may be empty
wxString m_filename;
#endif // __UNIX_LIKE__
};
class wxTCPClient: public wxClientBase

View File

@@ -5,6 +5,7 @@
// 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
@@ -33,23 +34,19 @@
#endif
#ifndef WX_PRECOMP
#include "wx/defs.h"
#include "wx/log.h"
#endif
#if wxUSE_SOCKETS && wxUSE_IPC && wxUSE_STREAMS
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "wx/socket.h"
#include "wx/sckipc.h"
#include "wx/module.h"
#include "wx/event.h"
#include "wx/log.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// --------------------------------------------------------------------------
// macros and constants
@@ -74,10 +71,47 @@ enum
};
#endif
// All sockets will be created with the following flags
#define SCKIPC_FLAGS (wxSOCKET_WAITALL)
// 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 = _T(""))
{
// we always use INET sockets under non-Unix systems
#ifdef __UNIX_LIKE__
// 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)
// --------------------------------------------------------------------------
@@ -129,7 +163,7 @@ bool wxTCPClient::ValidHost(const wxString& host)
}
wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host,
const wxString& server_name,
const wxString& serverName,
const wxString& topic)
{
wxSocketClient *client = new wxSocketClient(SCKIPC_FLAGS);
@@ -137,11 +171,14 @@ wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host,
wxDataInputStream *data_is = new wxDataInputStream(*stream);
wxDataOutputStream *data_os = new wxDataOutputStream(*stream);
wxIPV4address addr;
addr.Service(server_name);
addr.Hostname(host);
wxSockAddress *addr = GetAddressFromName(serverName, host);
if ( !addr )
return NULL;
if (client->Connect(addr))
bool ok = client->Connect(*addr);
delete addr;
if ( ok )
{
unsigned char msg;
@@ -213,12 +250,49 @@ bool wxTCPServer::Create(const wxString& serverName)
m_server = NULL;
}
// wxIPV4address defaults to INADDR_ANY:0
wxIPV4address addr;
addr.Service(serverName);
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);
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);
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__
delete addr;
if (!m_server->Ok())
{
@@ -238,11 +312,21 @@ bool wxTCPServer::Create(const wxString& serverName)
wxTCPServer::~wxTCPServer()
{
if (m_server)
{
m_server->SetClientData(NULL);
m_server->Destroy();
}
if (m_server)
{
m_server->SetClientData(NULL);
m_server->Destroy();
}
#ifdef __UNIX_LIKE__
if ( !m_filename.empty() )
{
if ( !remove(m_filename) )
{
wxLogDebug(_T("Stale AF_UNIX file '%s' left."), m_filename.c_str());
}
}
#endif // __UNIX_LIKE__
}
wxConnectionBase *wxTCPServer::OnAcceptConnection( const wxString& WXUNUSED(topic) )