зеркало из https://github.com/mozilla/gecko-dev.git
adding IPC framework -- NOT PART OF THE BUILD
This commit is contained in:
Родитель
8546c64322
Коммит
d34899750d
|
@ -0,0 +1,31 @@
|
|||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = common daemon testmodule public src build test
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,12 @@
|
|||
DAEMON ONLY DIRECTORIES:
|
||||
daemon/
|
||||
testmodule/
|
||||
|
||||
CLIENT ONLY DIRECTORIES:
|
||||
public/
|
||||
src/
|
||||
build/
|
||||
test/
|
||||
|
||||
SHARED CODE DIRECTORY:
|
||||
common/
|
|
@ -0,0 +1,75 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla IPC.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2002
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Darin Fisher <darin@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = ipc
|
||||
LIBRARY_NAME = ipc
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = ipc
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
necko \
|
||||
ipc \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = ipcModule.cpp
|
||||
EXPORTS = ipcCID.h
|
||||
|
||||
SHARED_LIBRARY_LIBS = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)ipc_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)ipccom_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../src \
|
||||
-I$(srcdir)/../util \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,63 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcCID_h__
|
||||
#define ipcCID_h__
|
||||
|
||||
#define IPC_SERVICE_CLASSNAME \
|
||||
"ipcService"
|
||||
#define IPC_SERVICE_CONTRACTID \
|
||||
"@mozilla.org/ipc/service;1"
|
||||
#define IPC_SERVICE_CID \
|
||||
{ /* 9f12676a-5168-4a08-beb8-edf8a593a1ca */ \
|
||||
0x9f12676a, \
|
||||
0x5168, \
|
||||
0x4a08, \
|
||||
{0xbe, 0xb8, 0xed, 0xf8, 0xa5, 0x93, 0xa1, 0xca} \
|
||||
}
|
||||
|
||||
#define IPC_SOCKETPROVIDER_CLASSNAME \
|
||||
"ipcSocketProvider"
|
||||
#define IPC_SOCKETPROVIDER_CID \
|
||||
{ /* b888f500-ab5d-459c-aab0-bc61e844a503 */ \
|
||||
0xb888f500, \
|
||||
0xab5d, \
|
||||
0x459c, \
|
||||
{0xaa, 0xb0, 0xbc, 0x61, 0xe8, 0x44, 0xa5, 0x03} \
|
||||
}
|
||||
|
||||
#endif // !ipcCID_h__
|
|
@ -0,0 +1,72 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "ipcService.h"
|
||||
#include "ipcSocketProvider.h"
|
||||
#include "ipcCID.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Define the contructor function for the objects
|
||||
//
|
||||
// NOTE: This creates an instance of objects by using the default constructor
|
||||
//
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ipcService, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(ipcSocketProvider)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Define a table of CIDs implemented by this module along with other
|
||||
// information like the function to create an instance, contractid, and
|
||||
// class name.
|
||||
//
|
||||
static const nsModuleComponentInfo components[] = {
|
||||
{ IPC_SERVICE_CLASSNAME,
|
||||
IPC_SERVICE_CID,
|
||||
IPC_SERVICE_CONTRACTID,
|
||||
ipcServiceConstructor, },
|
||||
{ IPC_SOCKETPROVIDER_CLASSNAME,
|
||||
IPC_SOCKETPROVIDER_CID,
|
||||
NS_NETWORK_SOCKET_CONTRACTID_PREFIX "ipc",
|
||||
ipcSocketProviderConstructor, },
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implement the NSGetModule() exported function for your module
|
||||
// and the entire implementation of the module object.
|
||||
//
|
||||
NS_IMPL_NSGETMODULE(ipcModule, components)
|
|
@ -0,0 +1,66 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla IPC.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2002
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Darin Fisher <darin@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = ipc
|
||||
LIBRARY_NAME = ipccom_s
|
||||
EXPORT_LIBRARY = 1
|
||||
FORCE_STATIC_LIB = 1
|
||||
MODULE_NAME = ipc
|
||||
|
||||
REQUIRES = \
|
||||
xpcom \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
ipcMessage.cpp \
|
||||
ipcMessageQ.cpp \
|
||||
ipcm.cpp
|
||||
|
||||
EXPORTS = \
|
||||
ipcMessage.h \
|
||||
ipcMessageQ.h \
|
||||
ipcm.h \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,71 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcProto_h__
|
||||
#define ipcProto_h__
|
||||
|
||||
#if defined(XP_WIN)
|
||||
//
|
||||
// XXX since win9x/me doesn't support named pipes, we resort to using a
|
||||
// localhost TCP/IP socket (for now). this is not a great solution for
|
||||
// several reasons:
|
||||
// (1) we have to agree on a port number.
|
||||
// (2) opens up a big security hole that needs to be plugged somehow.
|
||||
//
|
||||
// we should probably use WM_COPYDATA instead.
|
||||
//
|
||||
#define IPC_USE_INET 1
|
||||
#define IPC_PORT 14400
|
||||
#define IPC_SOCKET_TYPE nsnull
|
||||
#define IPC_DEFAULT_SOCKET_PATH ""
|
||||
#define IPC_DAEMON_APP_NAME "mozipcd.exe"
|
||||
#define IPC_PATH_SEP_CHAR '\\'
|
||||
#define IPC_PATH_SEP_CHAR_S "\\"
|
||||
#else
|
||||
//
|
||||
// use UNIX domain socket
|
||||
//
|
||||
#define IPC_PORT 0
|
||||
#define IPC_SOCKET_TYPE "ipc"
|
||||
#define IPC_DEFAULT_SOCKET_PATH "/tmp/sock"
|
||||
#define IPC_DAEMON_APP_NAME "mozipcd"
|
||||
#define IPC_PATH_SEP_CHAR '/'
|
||||
#define IPC_PATH_SEP_CHAR_S "/"
|
||||
#endif
|
||||
|
||||
|
||||
#endif // !ipcProto_h__
|
|
@ -0,0 +1,245 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "prlog.h"
|
||||
#include "ipcMessage.h"
|
||||
|
||||
ipcMessage::~ipcMessage()
|
||||
{
|
||||
if (mMsgHdr)
|
||||
free(mMsgHdr);
|
||||
}
|
||||
|
||||
void
|
||||
ipcMessage::Reset()
|
||||
{
|
||||
if (mMsgHdr) {
|
||||
free(mMsgHdr);
|
||||
mMsgHdr = NULL;
|
||||
}
|
||||
|
||||
mMsgOffset = 0;
|
||||
mMsgComplete = PR_FALSE;
|
||||
}
|
||||
|
||||
ipcMessage *
|
||||
ipcMessage::Clone()
|
||||
{
|
||||
ipcMessage *clone = new ipcMessage();
|
||||
if (!clone)
|
||||
return NULL;
|
||||
|
||||
// copy buf if non-null
|
||||
if (mMsgHdr) {
|
||||
clone->mMsgHdr = (ipcMessageHeader *) malloc(mMsgHdr->mLen);
|
||||
memcpy(clone->mMsgHdr, mMsgHdr, mMsgHdr->mLen);
|
||||
}
|
||||
else
|
||||
clone->mMsgHdr = NULL;
|
||||
|
||||
clone->mMsgOffset = mMsgOffset;
|
||||
clone->mMsgComplete = mMsgComplete;
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
ipcMessage::Init(const nsID &target, const char *data, PRUint32 dataLen)
|
||||
{
|
||||
if (mMsgHdr)
|
||||
free(mMsgHdr);
|
||||
mMsgComplete = PR_FALSE;
|
||||
|
||||
// allocate message data
|
||||
PRUint32 msgLen = IPC_MSG_HEADER_SIZE + dataLen;
|
||||
mMsgHdr = (ipcMessageHeader *) malloc(msgLen);
|
||||
if (!mMsgHdr) {
|
||||
mMsgHdr = NULL;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
// fill in message data
|
||||
mMsgHdr->mLen = msgLen;
|
||||
mMsgHdr->mVersion = IPC_MSG_VERSION;
|
||||
mMsgHdr->mFlags = 0;
|
||||
mMsgHdr->mTarget = target;
|
||||
|
||||
if (data)
|
||||
SetData(0, data, dataLen);
|
||||
|
||||
mMsgComplete = PR_TRUE;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
ipcMessage::SetData(PRUint32 offset, const char *data, PRUint32 dataLen)
|
||||
{
|
||||
PR_ASSERT(mMsgHdr != NULL);
|
||||
|
||||
if (offset + dataLen > DataLen())
|
||||
return PR_FAILURE;
|
||||
|
||||
memcpy((char *) Data() + offset, data, dataLen);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ipcMessage::Equals(const nsID &target, const char *data, PRUint32 dataLen) const
|
||||
{
|
||||
return mMsgComplete &&
|
||||
mMsgHdr->mTarget.Equals(target) &&
|
||||
DataLen() == dataLen &&
|
||||
memcmp(Data(), data, dataLen) == 0;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ipcMessage::Equals(const ipcMessage *msg) const
|
||||
{
|
||||
PRUint32 msgLen = MsgLen();
|
||||
return mMsgComplete && msg->mMsgComplete &&
|
||||
msgLen == msg->MsgLen() &&
|
||||
memcmp(MsgBuf(), msg->MsgBuf(), msgLen) == 0;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
ipcMessage::WriteTo(char *buf,
|
||||
PRUint32 bufLen,
|
||||
PRUint32 *bytesWritten,
|
||||
PRBool *complete)
|
||||
{
|
||||
if (!mMsgComplete)
|
||||
return PR_FAILURE;
|
||||
|
||||
if (mMsgOffset == MsgLen()) {
|
||||
*bytesWritten = 0;
|
||||
*complete = PR_TRUE;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRUint32 count = MsgLen() - mMsgOffset;
|
||||
if (count > bufLen)
|
||||
count = bufLen;
|
||||
|
||||
memcpy(buf, MsgBuf() + mMsgOffset, count);
|
||||
mMsgOffset += count;
|
||||
|
||||
*bytesWritten = count;
|
||||
*complete = (mMsgOffset == MsgLen());
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
ipcMessage::ReadFrom(const char *buf,
|
||||
PRUint32 bufLen,
|
||||
PRUint32 *bytesRead,
|
||||
PRBool *complete)
|
||||
{
|
||||
*bytesRead = 0;
|
||||
|
||||
if (mMsgComplete) {
|
||||
*complete = PR_TRUE;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
if (mMsgHdr) {
|
||||
// appending data to buffer
|
||||
if (mMsgOffset < sizeof(PRUint32)) {
|
||||
// we haven't learned the message length yet
|
||||
if (mMsgOffset + bufLen < sizeof(PRUint32)) {
|
||||
// we still don't know the length of the message!
|
||||
memcpy((char *) mMsgHdr + mMsgOffset, buf, bufLen);
|
||||
mMsgOffset += bufLen;
|
||||
*bytesRead = bufLen;
|
||||
*complete = PR_FALSE;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
else {
|
||||
// we now have enough data to determine the message length
|
||||
PRUint32 count = sizeof(PRUint32) - mMsgOffset;
|
||||
memcpy((char *) MsgBuf() + mMsgOffset, buf, count);
|
||||
mMsgOffset += count;
|
||||
buf += count;
|
||||
bufLen -= count;
|
||||
*bytesRead = count;
|
||||
|
||||
if (MsgLen() > IPC_MSG_GUESSED_SIZE) {
|
||||
// realloc message buffer to the correct size
|
||||
mMsgHdr = (ipcMessageHeader *) realloc(mMsgHdr, MsgLen());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (bufLen < sizeof(PRUint32)) {
|
||||
// not enough data available in buffer to determine allocation size
|
||||
// allocate a partial buffer
|
||||
PRUint32 msgLen = IPC_MSG_GUESSED_SIZE;
|
||||
mMsgHdr = (ipcMessageHeader *) malloc(msgLen);
|
||||
if (!mMsgHdr)
|
||||
return PR_FAILURE;
|
||||
memcpy(mMsgHdr, buf, bufLen);
|
||||
mMsgOffset = bufLen;
|
||||
*bytesRead = bufLen;
|
||||
*complete = PR_FALSE;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
else {
|
||||
PRUint32 msgLen = *(PRUint32 *) buf;
|
||||
mMsgHdr = (ipcMessageHeader *) malloc(msgLen);
|
||||
if (!mMsgHdr)
|
||||
return PR_FAILURE;
|
||||
mMsgHdr->mLen = msgLen;
|
||||
mMsgOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// have mMsgHdr at this point
|
||||
|
||||
PRUint32 count = MsgLen() - mMsgOffset;
|
||||
if (count > bufLen)
|
||||
count = bufLen;
|
||||
|
||||
memcpy((char *) mMsgHdr + mMsgOffset, buf, count);
|
||||
mMsgOffset += count;
|
||||
*bytesRead += count;
|
||||
|
||||
*complete = mMsgComplete = (mMsgOffset == MsgLen());
|
||||
return PR_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcMessage_h__
|
||||
#define ipcMessage_h__
|
||||
|
||||
#include "nsID.h"
|
||||
|
||||
//
|
||||
// ipc message format:
|
||||
//
|
||||
// +------------------------------------+
|
||||
// | DWORD : length |
|
||||
// +------------------+-----------------+
|
||||
// | WORD : version | WORD : flags |
|
||||
// +------------------+-----------------+
|
||||
// | nsID : target |
|
||||
// +------------------------------------+
|
||||
// | data |
|
||||
// +------------------------------------+
|
||||
//
|
||||
// header is 24 bytes. flags are for future use and must be zero in this
|
||||
// version of the ipc message format. target is a 16 byte UUID indicating
|
||||
// the intended receiver of this message.
|
||||
//
|
||||
|
||||
struct ipcMessageHeader
|
||||
{
|
||||
PRUint32 mLen;
|
||||
PRUint16 mVersion;
|
||||
PRUint16 mFlags;
|
||||
nsID mTarget;
|
||||
};
|
||||
|
||||
#define IPC_MSG_VERSION (0x1)
|
||||
#define IPC_MSG_HEADER_SIZE (sizeof(ipcMessageHeader))
|
||||
#define IPC_MSG_GUESSED_SIZE (IPC_MSG_HEADER_SIZE + 64)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcMessage
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ipcMessage
|
||||
{
|
||||
public:
|
||||
ipcMessage()
|
||||
: mNext(NULL)
|
||||
, mMsgHdr(NULL)
|
||||
, mMsgOffset(0)
|
||||
, mMsgComplete(PR_FALSE)
|
||||
{ }
|
||||
~ipcMessage();
|
||||
|
||||
//
|
||||
// reset message to uninitialized state
|
||||
//
|
||||
void Reset();
|
||||
|
||||
//
|
||||
// create a copy of this message
|
||||
//
|
||||
ipcMessage *Clone();
|
||||
|
||||
//
|
||||
// initialize message
|
||||
//
|
||||
// param:
|
||||
// topic - message topic string
|
||||
// data - message data (may be null to leave data uninitialized)
|
||||
// dataLen - message data len
|
||||
//
|
||||
PRStatus Init(const nsID &target, const char *data, PRUint32 dataLen);
|
||||
|
||||
//
|
||||
// copy data into the message's data section, starting from offset. this
|
||||
// function can be used to write only a portion of the message's data.
|
||||
//
|
||||
// param:
|
||||
// offset - destination offset
|
||||
// data - data to write
|
||||
// dataLen - number of bytes to write
|
||||
//
|
||||
PRStatus SetData(PRUint32 offset, const char *data, PRUint32 dataLen);
|
||||
|
||||
//
|
||||
// if true, the message is complete and the members of the message
|
||||
// can be accessed.
|
||||
//
|
||||
PRBool IsComplete() const { return mMsgComplete; }
|
||||
|
||||
//
|
||||
// readonly accessors
|
||||
//
|
||||
const ipcMessageHeader *Header() const { return mMsgHdr; }
|
||||
const nsID &Target() const { return mMsgHdr->mTarget; }
|
||||
const char *Data() const { return (char *) mMsgHdr + IPC_MSG_HEADER_SIZE; }
|
||||
PRUint32 DataLen() const { return mMsgHdr->mLen - IPC_MSG_HEADER_SIZE; }
|
||||
const char *MsgBuf() const { return (char *) mMsgHdr; }
|
||||
PRUint32 MsgLen() const { return mMsgHdr->mLen; }
|
||||
|
||||
//
|
||||
// message comparison functions
|
||||
//
|
||||
// param:
|
||||
// topic - message topic (may be null)
|
||||
// data - message data (must not be null)
|
||||
// dataLen - message data length
|
||||
//
|
||||
PRBool Equals(const nsID &target, const char *data, PRUint32 dataLen) const;
|
||||
PRBool Equals(const ipcMessage *msg) const;
|
||||
|
||||
//
|
||||
// write the message to a buffer segment; segment need not be large
|
||||
// enough to hold entire message. called repeatedly.
|
||||
//
|
||||
PRStatus WriteTo(char *buf,
|
||||
PRUint32 bufLen,
|
||||
PRUint32 *bytesWritten,
|
||||
PRBool *complete);
|
||||
|
||||
//
|
||||
// read the message from a buffer segment; segment need not contain
|
||||
// the entire messgae. called repeatedly.
|
||||
//
|
||||
PRStatus ReadFrom(const char *buf,
|
||||
PRUint32 bufLen,
|
||||
PRUint32 *bytesRead,
|
||||
PRBool *complete);
|
||||
|
||||
//
|
||||
// a message can be added to a singly-linked list.
|
||||
//
|
||||
class ipcMessage *mNext;
|
||||
|
||||
private:
|
||||
ipcMessageHeader *mMsgHdr;
|
||||
|
||||
// XXX document me
|
||||
PRUint32 mMsgOffset;
|
||||
PRPackedBool mMsgComplete;
|
||||
};
|
||||
|
||||
#endif // !ipcMessage_h__
|
|
@ -0,0 +1,76 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ipcMessageQ.h"
|
||||
#include "ipcMessage.h"
|
||||
|
||||
void
|
||||
ipcMessageQ::Append(ipcMessage *msg)
|
||||
{
|
||||
msg->mNext = NULL;
|
||||
if (mTail) {
|
||||
mTail->mNext = msg;
|
||||
mTail = msg;
|
||||
}
|
||||
else
|
||||
mTail = mHead = msg;
|
||||
}
|
||||
|
||||
void
|
||||
ipcMessageQ::AdvanceHead()
|
||||
{
|
||||
mHead = mHead->mNext;
|
||||
if (!mHead)
|
||||
mTail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ipcMessageQ::DeleteFirst()
|
||||
{
|
||||
ipcMessage *first = mHead;
|
||||
if (first) {
|
||||
AdvanceHead();
|
||||
delete first;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ipcMessageQ::DeleteAll()
|
||||
{
|
||||
while (mHead)
|
||||
DeleteFirst();
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcMessageQ_h__
|
||||
#define ipcMessageQ_h__
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
class ipcMessage;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// simple queue of ipcMessage objects
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ipcMessageQ
|
||||
{
|
||||
public:
|
||||
ipcMessageQ()
|
||||
: mHead(NULL)
|
||||
, mTail(NULL)
|
||||
{ }
|
||||
~ipcMessageQ() { DeleteAll(); }
|
||||
|
||||
//
|
||||
// appends msg to the end of the queue. caller loses ownership of |msg|.
|
||||
//
|
||||
void Append(ipcMessage *msg);
|
||||
|
||||
//
|
||||
// removes first element w/o deleting it
|
||||
//
|
||||
void RemoveFirst() { if (mHead) AdvanceHead(); }
|
||||
|
||||
//
|
||||
// deletes first element
|
||||
//
|
||||
void DeleteFirst();
|
||||
|
||||
//
|
||||
// deletes all elements
|
||||
//
|
||||
void DeleteAll();
|
||||
|
||||
ipcMessage *First() { return mHead; }
|
||||
PRBool IsEmpty() { return mHead == NULL; }
|
||||
|
||||
private:
|
||||
void AdvanceHead();
|
||||
|
||||
ipcMessage *mHead;
|
||||
ipcMessage *mTail;
|
||||
};
|
||||
|
||||
#endif // !ipcMessageQ_h__
|
|
@ -0,0 +1,248 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <string.h>
|
||||
#include "ipcm.h"
|
||||
#include "prlog.h"
|
||||
|
||||
const nsID IPCM_TARGET =
|
||||
{ /* 753ca8ff-c8c2-4601-b115-8c2944da1150 */
|
||||
0x753ca8ff,
|
||||
0xc8c2,
|
||||
0x4601,
|
||||
{0xb1, 0x15, 0x8c, 0x29, 0x44, 0xda, 0x11, 0x50}
|
||||
};
|
||||
|
||||
static const char IPCM_PING[] = { (char) IPCM_MSG_PING };
|
||||
static const PRUint32 IPCM_PING_LEN = sizeof(IPCM_PING);
|
||||
|
||||
static const char IPCM_CNAME[] = { (char) IPCM_MSG_CNAME };
|
||||
static const PRUint32 IPCM_CNAME_LEN = sizeof(IPCM_CNAME);
|
||||
|
||||
//
|
||||
// +--------------------+
|
||||
// | BYTE : msgType |
|
||||
// +--------------------+
|
||||
// | (variable) |
|
||||
// +--------------------+
|
||||
//
|
||||
|
||||
int
|
||||
IPCM_GetMsgType(const ipcMessage *msg)
|
||||
{
|
||||
// make sure message topic matches
|
||||
if (msg->Target().Equals(IPCM_TARGET)) {
|
||||
// the type is encoded as the first byte
|
||||
char type = msg->Data()[0];
|
||||
if (type < IPCM_MSG_UNKNOWN)
|
||||
return type;
|
||||
}
|
||||
return IPCM_MSG_UNKNOWN;
|
||||
}
|
||||
|
||||
//
|
||||
// PING message
|
||||
//
|
||||
// +----------------------+
|
||||
// | BYTE - IPCM_MSG_PING |
|
||||
// +----------------------+
|
||||
//
|
||||
|
||||
const char ipcmMessagePING::MSG_TYPE = (char) IPCM_MSG_PING;
|
||||
|
||||
ipcmMessagePING::ipcmMessagePING()
|
||||
{
|
||||
Init(IPCM_TARGET, &MSG_TYPE, 1);
|
||||
}
|
||||
|
||||
//
|
||||
// CNAME message
|
||||
//
|
||||
// +-----------------------+
|
||||
// | BYTE - IPCM_MSG_CNAME |
|
||||
// +-----------------------+
|
||||
// | clientName |
|
||||
// +-----------------------+
|
||||
// | null |
|
||||
// +-----------------------+
|
||||
//
|
||||
|
||||
const char ipcmMessageCNAME::MSG_TYPE = (char) IPCM_MSG_CNAME;
|
||||
|
||||
ipcmMessageCNAME::ipcmMessageCNAME(const char *cName)
|
||||
{
|
||||
int cLen = strlen(cName);
|
||||
int dataLen = 1 + // msg_type
|
||||
cLen + // cName
|
||||
1; // null
|
||||
|
||||
Init(IPCM_TARGET, NULL, dataLen);
|
||||
SetData(0, &MSG_TYPE, 1);
|
||||
SetData(1, cName, cLen + 1);
|
||||
}
|
||||
|
||||
const char *
|
||||
ipcmMessageCNAME::ClientName() const
|
||||
{
|
||||
// make sure data is null terminated
|
||||
const char *data = Data();
|
||||
if (data[DataLen() - 1] != '\0')
|
||||
return NULL;
|
||||
|
||||
return Data() + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// CENUM message
|
||||
//
|
||||
// +-----------------------+
|
||||
// | BYTE - IPCM_MSG_CENUM |
|
||||
// +-----------------------+
|
||||
//
|
||||
|
||||
const char ipcmMessageCENUM::MSG_TYPE = (char) IPCM_MSG_CENUM;
|
||||
|
||||
ipcmMessageCENUM::ipcmMessageCENUM()
|
||||
{
|
||||
Init(IPCM_TARGET, &MSG_TYPE, 1);
|
||||
}
|
||||
|
||||
//
|
||||
// CLIST message
|
||||
//
|
||||
// +-----------------------+
|
||||
// | BYTE - IPCM_MSG_CLIST |
|
||||
// +-----------------------+
|
||||
// | cname[0] |
|
||||
// +-----------------------+
|
||||
// | null |
|
||||
// +-----------------------+
|
||||
// . .
|
||||
// . .
|
||||
// +-----------------------+
|
||||
// | cname[num - 1] |
|
||||
// +-----------------------+
|
||||
// | null |
|
||||
// +-----------------------+
|
||||
//
|
||||
|
||||
const char ipcmMessageCLIST::MSG_TYPE = (char) IPCM_MSG_CLIST;
|
||||
|
||||
ipcmMessageCLIST::ipcmMessageCLIST(const char *cNames[], PRUint32 num)
|
||||
{
|
||||
PRUint32 i, dataLen = 1;
|
||||
|
||||
for (i = 0; i < num; ++i) {
|
||||
dataLen += strlen(cNames[i]);
|
||||
dataLen ++;
|
||||
}
|
||||
|
||||
Init(IPCM_TARGET, NULL, dataLen);
|
||||
|
||||
PRUint32 offset = 1;
|
||||
for (i = 0; i < num; ++i) {
|
||||
PRUint32 len = strlen(cNames[i]);
|
||||
SetData(offset, cNames[i], len + 1);
|
||||
offset += len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
ipcmMessageCLIST::NextClientName(const char *cName) const
|
||||
{
|
||||
if (!cName)
|
||||
return Data() + 1;
|
||||
|
||||
cName += strlen(cName) + 1;
|
||||
if (cName == MsgBuf() + MsgLen())
|
||||
cName = NULL;
|
||||
return cName;
|
||||
}
|
||||
|
||||
//
|
||||
// FWD message
|
||||
//
|
||||
// +----------------------+
|
||||
// | BYTE - IPCM_MSG_FWD |
|
||||
// +----------------------+
|
||||
// | dest_client |
|
||||
// +----------------------+
|
||||
// | null |
|
||||
// +----------------------+
|
||||
// | dest_msg |
|
||||
// +----------------------+
|
||||
//
|
||||
|
||||
const char ipcmMessageFWD::MSG_TYPE = (char) IPCM_MSG_FWD;
|
||||
|
||||
ipcmMessageFWD::ipcmMessageFWD(const char *dClient, const ipcMessage *dMsg)
|
||||
{
|
||||
int cLen = strlen(dClient);
|
||||
int dataLen = 1 + // msg_type
|
||||
cLen + // dest_client
|
||||
1 + // null
|
||||
dMsg->MsgLen(); // dest_msg
|
||||
|
||||
Init(IPCM_TARGET, NULL, dataLen);
|
||||
SetData(0, &MSG_TYPE, 1);
|
||||
SetData(1, dClient, cLen + 1);
|
||||
SetData(1 + cLen + 1, dMsg->MsgBuf(), dMsg->MsgLen());
|
||||
}
|
||||
|
||||
const char *
|
||||
ipcmMessageFWD::DestClient() const
|
||||
{
|
||||
return Data() + 1;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
ipcmMessageFWD::DestMessage(ipcMessage *msg) const
|
||||
{
|
||||
const char *ptr = DestClient();
|
||||
|
||||
// XXX use a custom loop here to avoid walking off the end of the buffer
|
||||
PRUint32 cLen = strlen(ptr);
|
||||
PRUint32 dLen = MsgLen() - 1 - cLen - 1;
|
||||
PRUint32 bytesRead;
|
||||
PRBool complete;
|
||||
|
||||
ptr += (cLen + 1);
|
||||
if (msg->ReadFrom(ptr, dLen, &bytesRead, &complete) != PR_SUCCESS || !complete)
|
||||
return PR_FAILURE;
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcm_h__
|
||||
#define ipcm_h__
|
||||
|
||||
#include "ipcMessage.h"
|
||||
|
||||
//
|
||||
// IPCM (IPC Manager) protocol support
|
||||
//
|
||||
|
||||
extern const nsID IPCM_TARGET;
|
||||
|
||||
enum {
|
||||
IPCM_MSG_PING,
|
||||
IPCM_MSG_CNAME,
|
||||
IPCM_MSG_CENUM,
|
||||
IPCM_MSG_CLIST,
|
||||
IPCM_MSG_FWD,
|
||||
IPCM_MSG_UNKNOWN // unknown message type
|
||||
};
|
||||
|
||||
//
|
||||
// returns IPCM message type.
|
||||
//
|
||||
int IPCM_GetMsgType(const ipcMessage *msg);
|
||||
|
||||
//
|
||||
// NOTE: this file declares some helper classes that simplify construction
|
||||
// and parsing of IPCM messages. each class subclasses ipcMessage, but
|
||||
// adds no additional member variables. operator new should be used
|
||||
// to allocate one of the IPCM helper classes, e.g.:
|
||||
//
|
||||
// ipcMessage *msg = new ipcmMessageCNAME("foo");
|
||||
//
|
||||
// given an arbitrary ipcMessage, it can be parsed using logic similar
|
||||
// to the following:
|
||||
//
|
||||
// ipcMessage *msg = ...
|
||||
// if (strcmp(msg->Topic(), "ipcm") == 0) {
|
||||
// if (IPCM_GetMsgType(msg) == IPCM_MSG_CNAME) {
|
||||
// ipcmMessageCNAME *cnameMsg = (ipcmMessageCNAME *) msg;
|
||||
// printf("client name: %s\n", cnameMsg->ClientName());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// in other words, these classes are very very lightweight.
|
||||
//
|
||||
|
||||
//
|
||||
// IPCM_MSG_PING
|
||||
//
|
||||
// this message may be sent from either the client or the daemon.
|
||||
//
|
||||
class ipcmMessagePING : public ipcMessage
|
||||
{
|
||||
public:
|
||||
static const char MSG_TYPE;
|
||||
|
||||
ipcmMessagePING();
|
||||
};
|
||||
|
||||
//
|
||||
// IPCM_MSG_CNAME
|
||||
//
|
||||
// this message is sent from a client to specify its name.
|
||||
//
|
||||
class ipcmMessageCNAME : public ipcMessage
|
||||
{
|
||||
public:
|
||||
static const char MSG_TYPE;
|
||||
|
||||
ipcmMessageCNAME(const char *cName);
|
||||
|
||||
//
|
||||
// extracts the "client name"
|
||||
//
|
||||
const char *ClientName() const;
|
||||
};
|
||||
|
||||
//
|
||||
// IPCM_MSG_CENUM
|
||||
//
|
||||
// this message is sent from a client to request a CLIST response.
|
||||
//
|
||||
class ipcmMessageCENUM : public ipcMessage
|
||||
{
|
||||
public:
|
||||
static const char MSG_TYPE;
|
||||
|
||||
ipcmMessageCENUM();
|
||||
};
|
||||
|
||||
//
|
||||
// IPCM_MSG_CLIST
|
||||
//
|
||||
// this message is sent from the daemon in response to a CENUM request. the
|
||||
// message contains the list of clients by name.
|
||||
//
|
||||
class ipcmMessageCLIST : public ipcMessage
|
||||
{
|
||||
public:
|
||||
static const char MSG_TYPE;
|
||||
|
||||
ipcmMessageCLIST(const char *clientNames[], PRUint32 numClients);
|
||||
|
||||
//
|
||||
// extracts the next client name from the message. if null is passed in, then
|
||||
// the first client name in the list is returned. null is returned if there
|
||||
// aren't anymore client names. (the returned client name acts as an iterator.)
|
||||
//
|
||||
const char *NextClientName(const char *clientName = NULL) const;
|
||||
};
|
||||
|
||||
//
|
||||
// IPCM_MSG_FWD
|
||||
//
|
||||
// this message is only sent from the client to the daemon. the daemon
|
||||
// will forward the contained message to the specified client.
|
||||
//
|
||||
class ipcmMessageFWD : public ipcMessage
|
||||
{
|
||||
public:
|
||||
static const char MSG_TYPE;
|
||||
|
||||
ipcmMessageFWD(const char *destClient, const ipcMessage *destMsg);
|
||||
|
||||
//
|
||||
// extracts the "destination client name"
|
||||
//
|
||||
const char *DestClient() const;
|
||||
|
||||
//
|
||||
// extracts (a copy of) the "destination message"
|
||||
//
|
||||
PRStatus DestMessage(ipcMessage *destMsg) const;
|
||||
};
|
||||
|
||||
#endif // !ipcm_h__
|
|
@ -0,0 +1,87 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla IPC.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2002
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Darin Fisher <darin@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = ipc
|
||||
REQUIRES = \
|
||||
xpcom \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
ipcd.cpp \
|
||||
ipcClient.cpp \
|
||||
ipcModuleReg.cpp \
|
||||
ipcCommandModule.cpp \
|
||||
$(NULL)
|
||||
|
||||
PROGRAM = mozipcd$(BIN_SUFFIX)
|
||||
|
||||
EXPORTS = \
|
||||
ipcModule.h \
|
||||
ipcd.h \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../common \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
LIBS = \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)ipccom_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -DIPC_DAEMON
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
#
|
||||
# need to install mozipcd.lib, which contains the symbols exported by the
|
||||
# daemon that modules will need to import.
|
||||
#
|
||||
libs:: $(PROGRAM)
|
||||
$(INSTALL) mozipcd.lib $(DIST)/lib
|
||||
endif
|
|
@ -0,0 +1,191 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ipcClient.h"
|
||||
#include "ipcMessage.h"
|
||||
#include "ipcd.h"
|
||||
#include "prio.h"
|
||||
#include "plstr.h"
|
||||
|
||||
int ipcClient::gLastID = 0;
|
||||
|
||||
//
|
||||
// called to initialize this client context
|
||||
//
|
||||
// return:
|
||||
// PR_POLL_READ - to wait for the client socket to become readable
|
||||
// PR_POLL_WRITE - to wait for the client socket to become writable
|
||||
//
|
||||
int
|
||||
ipcClient::Init()
|
||||
{
|
||||
mID = ++gLastID;
|
||||
mName = NULL;
|
||||
mInMsg = new ipcMessage();
|
||||
|
||||
mSendOffset = 0;
|
||||
|
||||
// wait for the client to send us a command
|
||||
return PR_POLL_READ;
|
||||
}
|
||||
|
||||
//
|
||||
// called when this client context is going away
|
||||
//
|
||||
int
|
||||
ipcClient::Finalize()
|
||||
{
|
||||
if (mName)
|
||||
PL_strfree(mName);
|
||||
if (mInMsg)
|
||||
delete mInMsg;
|
||||
mOutMsgQ.DeleteAll();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// called to process a client socket
|
||||
//
|
||||
// params:
|
||||
// fd - the client socket
|
||||
// poll_flags - the state of the client socket
|
||||
//
|
||||
// return:
|
||||
// 0 - to end session with this client
|
||||
// PR_POLL_READ - to wait for the client socket to become readable
|
||||
// PR_POLL_WRITE - to wait for the client socket to become writable
|
||||
//
|
||||
int
|
||||
ipcClient::Process(PRFileDesc *fd, int poll_flags)
|
||||
{
|
||||
if ((poll_flags & PR_POLL_ERR) ||
|
||||
(poll_flags & PR_POLL_HUP) ||
|
||||
(poll_flags & PR_POLL_EXCEPT) ||
|
||||
(poll_flags & PR_POLL_NVAL)) {
|
||||
//
|
||||
// expect Finalize method to be called next.
|
||||
//
|
||||
printf("### client socket appears to have closed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// always wait for more data
|
||||
int ret_flags = PR_POLL_READ;
|
||||
|
||||
if (poll_flags & PR_POLL_READ) {
|
||||
printf("### client socket is now readable\n");
|
||||
|
||||
char buf[1024];
|
||||
PRInt32 n;
|
||||
|
||||
// find out how much data is available for reading...
|
||||
// n = PR_Available(fd);
|
||||
|
||||
n = PR_Read(fd, buf, sizeof(buf));
|
||||
if (n <= 0)
|
||||
return 0; // cancel connection
|
||||
|
||||
char *ptr = buf;
|
||||
while (n) {
|
||||
PRUint32 nread;
|
||||
PRBool complete;
|
||||
|
||||
mInMsg->ReadFrom(ptr, PRUint32(n), &nread, &complete);
|
||||
|
||||
if (complete) {
|
||||
IPC_DispatchMsg(this, mInMsg);
|
||||
mInMsg->Reset();
|
||||
}
|
||||
|
||||
n -= nread;
|
||||
ptr += nread;
|
||||
}
|
||||
}
|
||||
|
||||
if (poll_flags & PR_POLL_WRITE) {
|
||||
printf("### client socket is now writable\n");
|
||||
|
||||
if (mOutMsgQ.First())
|
||||
WriteMsgs(fd);
|
||||
}
|
||||
|
||||
if (mOutMsgQ.First())
|
||||
ret_flags |= PR_POLL_WRITE;
|
||||
|
||||
return ret_flags;
|
||||
}
|
||||
|
||||
void
|
||||
ipcClient::SetName(const char *name)
|
||||
{
|
||||
printf("### setting client name to \"%s\"\n", name);
|
||||
|
||||
if (mName)
|
||||
PL_strfree(mName);
|
||||
mName = PL_strdup(name);
|
||||
}
|
||||
|
||||
//
|
||||
// called to write out any messages from the outgoing queue.
|
||||
//
|
||||
int
|
||||
ipcClient::WriteMsgs(PRFileDesc *fd)
|
||||
{
|
||||
while (mOutMsgQ.First()) {
|
||||
const char *buf = (const char *) mOutMsgQ.First()->MsgBuf();
|
||||
PRInt32 bufLen = (PRInt32) mOutMsgQ.First()->MsgLen();
|
||||
|
||||
if (mSendOffset) {
|
||||
buf += mSendOffset;
|
||||
bufLen -= mSendOffset;
|
||||
}
|
||||
|
||||
PRInt32 nw = PR_Write(fd, buf, bufLen);
|
||||
if (nw <= 0)
|
||||
break;
|
||||
|
||||
printf("### wrote %d bytes\n", nw);
|
||||
|
||||
if (nw == bufLen)
|
||||
mOutMsgQ.DeleteFirst();
|
||||
else
|
||||
mSendOffset += nw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcClient_h__
|
||||
#define ipcClient_h__
|
||||
|
||||
#include "ipcMessageQ.h"
|
||||
#include "prio.h"
|
||||
|
||||
class ipcMessage;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcClient
|
||||
//
|
||||
// NOTE: this class is an implementation detail of the IPC daemon. IPC daemon
|
||||
// modules (other than the built-in IPCM module) must not access methods on
|
||||
// this class directly. use the API provided via ipcd.h instead.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ipcClient
|
||||
{
|
||||
public:
|
||||
int Init();
|
||||
int Finalize();
|
||||
int Process(PRFileDesc *fd, int poll_flags);
|
||||
|
||||
int ID() const { return mID; }
|
||||
const char *Name() const { return mName; }
|
||||
|
||||
void SetName(const char *name);
|
||||
void EnqueueOutboundMsg(ipcMessage *msg) { mOutMsgQ.Append(msg); }
|
||||
|
||||
private:
|
||||
int WriteMsgs(PRFileDesc *fd);
|
||||
|
||||
static int gLastID;
|
||||
|
||||
int mID;
|
||||
char *mName;
|
||||
ipcMessage *mInMsg; // buffer for incoming message
|
||||
ipcMessageQ mOutMsgQ; // outgoing message queue
|
||||
|
||||
// keep track of the amount of the first message sent
|
||||
PRUint32 mSendOffset;
|
||||
};
|
||||
|
||||
#endif // !ipcClient_h__
|
|
@ -0,0 +1,117 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "ipcCommandModule.h"
|
||||
#include "ipcModule.h"
|
||||
#include "ipcClient.h"
|
||||
#include "ipcMessage.h"
|
||||
#include "ipcd.h"
|
||||
#include "ipcm.h"
|
||||
|
||||
typedef const char * constCharPtr;
|
||||
|
||||
class ipcCommandModule : public ipcModule
|
||||
{
|
||||
public:
|
||||
void Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
const nsID &ID()
|
||||
{
|
||||
return IPCM_TARGET;
|
||||
}
|
||||
|
||||
void HandleMsg(ipcClient *client, const ipcMessage *msg)
|
||||
{
|
||||
// XXX replace w/ function table
|
||||
switch (IPCM_GetMsgType(msg)) {
|
||||
case IPCM_MSG_PING:
|
||||
printf("### got ping\n");
|
||||
{
|
||||
IPC_SendMsg(client, new ipcmMessagePING());
|
||||
}
|
||||
break;
|
||||
case IPCM_MSG_CNAME:
|
||||
printf("### got cname\n");
|
||||
{
|
||||
const char *name = ((const ipcmMessageCNAME *) msg)->ClientName();
|
||||
if (name)
|
||||
client->SetName(name);
|
||||
}
|
||||
break;
|
||||
case IPCM_MSG_CENUM:
|
||||
printf("### got cenum\n");
|
||||
{
|
||||
int len;
|
||||
ipcClient *clients = IPC_GetClients(&len);
|
||||
if (clients) {
|
||||
constCharPtr *clist = new constCharPtr[len-1];
|
||||
if (clist) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (clients + i != client)
|
||||
clist[i] = clients[i].Name();
|
||||
}
|
||||
IPC_SendMsg(client, new ipcmMessageCLIST(clist, len-1));
|
||||
delete[] clist;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IPCM_MSG_FWD:
|
||||
printf("### got fwd\n");
|
||||
{
|
||||
const ipcmMessageFWD *fMsg = (const ipcmMessageFWD *) msg;
|
||||
ipcClient *client = IPC_GetClientByName(fMsg->DestClient());
|
||||
ipcMessage *newMsg = new ipcMessage();
|
||||
if (fMsg->DestMessage(newMsg) == PR_SUCCESS)
|
||||
IPC_SendMsg(client, newMsg);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("### got unknown message\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ipcModule *IPC_GetCommandModule()
|
||||
{
|
||||
static ipcCommandModule module;
|
||||
return &module;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcCommandModule_h__
|
||||
#define ipcCommandModule_h__
|
||||
|
||||
#include "ipcm.h"
|
||||
|
||||
class ipcModule *IPC_GetCommandModule();
|
||||
|
||||
#endif // !ipcCommandModule_h__
|
|
@ -0,0 +1,95 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcModule_h__
|
||||
#define ipcModule_h__
|
||||
|
||||
#include "nsID.h"
|
||||
|
||||
class ipcMessage;
|
||||
class ipcClient;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// abstract module class
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ipcModule
|
||||
{
|
||||
public:
|
||||
//
|
||||
// called when this module will no longer be accessed. if this module was
|
||||
// allocated on the heap, then it can be free'd.
|
||||
//
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
//
|
||||
// called to determine the ID of this module. the ID of a module
|
||||
// indicates the "message target" for which it will be registered
|
||||
// as a handler.
|
||||
//
|
||||
virtual const nsID &ID() = 0;
|
||||
|
||||
//
|
||||
// called when a new message arrives for this module.
|
||||
//
|
||||
// params:
|
||||
//
|
||||
// client - an opaque "handle" to an object representing the client that
|
||||
// sent the message. modules should not store the value of this
|
||||
// beyond the duration fo this function call. (e.g., the handle
|
||||
// may be invalid after this function call returns.) modules
|
||||
// wishing to hold onto a reference to a "client" should store
|
||||
// the client's ID (see IPC_GetClientID).
|
||||
//
|
||||
// msg - the message sent from the client. the target of this message
|
||||
// matches the ID of this module.
|
||||
//
|
||||
virtual void HandleMsg(ipcClient *client, const ipcMessage *msg) = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// factory method signature for DLLs, which may define more than one ipcModule
|
||||
// implementation. the DLL must export the following symbol:
|
||||
//
|
||||
// extern "C" ipcModule **IPC_GetModuleList();
|
||||
//
|
||||
// return:
|
||||
// null terminated array of modules.
|
||||
//
|
||||
typedef ipcModule ** (*ipcGetModuleListFunc)(void);
|
||||
|
||||
#endif // !ipcModule_h__
|
|
@ -0,0 +1,173 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "prlink.h"
|
||||
#include "prio.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#include "ipcConfig.h"
|
||||
#include "ipcModuleReg.h"
|
||||
#include "ipcModule.h"
|
||||
#include "ipcCommandModule.h"
|
||||
#include "ipcd.h"
|
||||
|
||||
struct ipcModuleRegEntry
|
||||
{
|
||||
nsID id;
|
||||
ipcModule *module;
|
||||
PRLibrary *lib;
|
||||
};
|
||||
|
||||
#define IPC_MAX_MODULE_COUNT 64
|
||||
|
||||
static ipcModuleRegEntry ipcModules[IPC_MAX_MODULE_COUNT];
|
||||
static int ipcModuleCount;
|
||||
|
||||
static PRStatus
|
||||
AddModule(const nsID &id, ipcModule *module, PRLibrary *lib)
|
||||
{
|
||||
if (ipcModuleCount == IPC_MAX_MODULE_COUNT) {
|
||||
printf("### too many modules!\n");
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
ipcModules[ipcModuleCount].id = id;
|
||||
ipcModules[ipcModuleCount].module = module;
|
||||
ipcModules[ipcModuleCount].lib = lib;
|
||||
|
||||
++ipcModuleCount;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
InitModuleFromLib(const char *modulesDir, const char *fileName)
|
||||
{
|
||||
printf("### InitModuleFromLib [%s]\n", fileName);
|
||||
|
||||
int dLen = strlen(modulesDir);
|
||||
int fLen = strlen(fileName);
|
||||
|
||||
char *buf = (char *) malloc(dLen + 1 + fLen + 1);
|
||||
memcpy(buf, modulesDir, dLen);
|
||||
buf[dLen] = IPC_PATH_SEP_CHAR;
|
||||
memcpy(buf + dLen + 1, fileName, fLen);
|
||||
buf[dLen + 1 + fLen] = '\0';
|
||||
|
||||
PRLibrary *lib = PR_LoadLibrary(buf);
|
||||
if (lib) {
|
||||
ipcGetModuleListFunc func =
|
||||
(ipcGetModuleListFunc) PR_FindFunctionSymbol(lib, "IPC_GetModuleList");
|
||||
if (func) {
|
||||
ipcModule **modules = func();
|
||||
if (modules) {
|
||||
while (*modules) {
|
||||
AddModule((*modules)->ID(), *modules, PR_LoadLibrary(buf));
|
||||
++modules;
|
||||
}
|
||||
}
|
||||
}
|
||||
PR_UnloadLibrary(lib);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcModuleReg API
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// search for a module registered under the specified id
|
||||
//
|
||||
ipcModule *
|
||||
IPC_GetModuleByID(const nsID &id)
|
||||
{
|
||||
for (int i=0; i<ipcModuleCount; ++i) {
|
||||
ipcModuleRegEntry &entry = ipcModules[i];
|
||||
if (entry.id.Equals(id))
|
||||
return entry.module;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
IPC_InitModuleReg(const char *modulesDir)
|
||||
{
|
||||
ipcModule *module = IPC_GetCommandModule();
|
||||
AddModule(module->ID(), module, NULL);
|
||||
|
||||
if (modulesDir) {
|
||||
printf("### loading libraries in %s\n", modulesDir);
|
||||
//
|
||||
// scan directory for IPC modules
|
||||
//
|
||||
PRDir *dir = PR_OpenDir(modulesDir);
|
||||
if (dir) {
|
||||
PRDirEntry *ent;
|
||||
while ((ent = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
|
||||
//
|
||||
// locate extension, and check if dynamic library
|
||||
//
|
||||
char *p = strrchr(ent->name, '.');
|
||||
if (p && PL_strcasecmp(p, MOZ_DLL_SUFFIX) == 0)
|
||||
InitModuleFromLib(modulesDir, ent->name);
|
||||
}
|
||||
PR_CloseDir(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IPC_ShutdownModuleReg()
|
||||
{
|
||||
//
|
||||
// shutdown modules in reverse order
|
||||
//
|
||||
for (int i = ipcModuleCount - 1; i >= 0; --i) {
|
||||
ipcModuleRegEntry &entry = ipcModules[i];
|
||||
if (entry.module)
|
||||
entry.module->Shutdown();
|
||||
if (entry.lib)
|
||||
PR_UnloadLibrary(entry.lib);
|
||||
}
|
||||
// memset(ipcModules, 0, sizeof(ipcModules));
|
||||
ipcModuleCount = 0;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcModuleReg_h__
|
||||
#define ipcModuleReg_h__
|
||||
|
||||
#include "ipcModule.h"
|
||||
|
||||
//
|
||||
// called to init/shutdown module registry.
|
||||
//
|
||||
void IPC_InitModuleReg(const char *moduleDir);
|
||||
void IPC_ShutdownModuleReg();
|
||||
|
||||
#endif // !ipcModuleReg_h__
|
|
@ -0,0 +1,415 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include "prio.h"
|
||||
#include "prerror.h"
|
||||
#include "prthread.h"
|
||||
#include "prinrval.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#include "ipcConfig.h"
|
||||
#include "ipcMessage.h"
|
||||
#include "ipcClient.h"
|
||||
#include "ipcModuleReg.h"
|
||||
#include "ipcModule.h"
|
||||
#include "ipcd.h"
|
||||
|
||||
#ifdef IPC_USE_INET
|
||||
#include "prnetdb.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// upper limit on the number of active connections
|
||||
// XXX may want to make this more dynamic
|
||||
#define MAX_CLIENTS 100
|
||||
|
||||
//
|
||||
// the first element of this array is always zero; this is done so that the
|
||||
// n'th element of |clients| corresponds to the n'th element of |poll_fds|.
|
||||
//
|
||||
static ipcClient clients[MAX_CLIENTS + 1];
|
||||
|
||||
static PRPollDesc poll_fds[MAX_CLIENTS + 1];
|
||||
static int poll_fd_count;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int AddClient(PRFileDesc *fd)
|
||||
{
|
||||
if (poll_fd_count == MAX_CLIENTS + 1) {
|
||||
printf("### reached maximum client limit\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
poll_fds[poll_fd_count].fd = fd;
|
||||
poll_fds[poll_fd_count].in_flags = clients[poll_fd_count].Init();
|
||||
poll_fds[poll_fd_count].out_flags = 0;
|
||||
|
||||
++poll_fd_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int RemoveClient(int client_index)
|
||||
{
|
||||
PRPollDesc *pd = &poll_fds[client_index];
|
||||
|
||||
PR_Close(pd->fd);
|
||||
|
||||
clients[client_index].Finalize();
|
||||
|
||||
//
|
||||
// keep the clients and poll_fds contiguous; move the last one into
|
||||
// the spot held by the one that is going away.
|
||||
//
|
||||
int to_idx = client_index;
|
||||
int from_idx = poll_fd_count - 1;
|
||||
if (from_idx != to_idx) {
|
||||
memcpy(&clients[to_idx], &clients[from_idx], sizeof(ipcClient));
|
||||
memcpy(&poll_fds[to_idx], &poll_fds[from_idx], sizeof(PRPollDesc));
|
||||
}
|
||||
|
||||
//
|
||||
// zero out the old entries.
|
||||
//
|
||||
memset(&clients[from_idx], 0, sizeof(ipcClient));
|
||||
memset(&poll_fds[from_idx], 0, sizeof(PRPollDesc));
|
||||
|
||||
--poll_fd_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void Process(PRFileDesc *listen_fd)
|
||||
{
|
||||
poll_fd_count = 1;
|
||||
|
||||
poll_fds[0].fd = listen_fd;
|
||||
poll_fds[0].in_flags = PR_POLL_EXCEPT | PR_POLL_READ;
|
||||
|
||||
while (1) {
|
||||
PRInt32 rv;
|
||||
PRIntn i;
|
||||
|
||||
poll_fds[0].out_flags = 0;
|
||||
|
||||
//
|
||||
// poll
|
||||
//
|
||||
// timeout after 5 minutes. if no connections after timeout, then
|
||||
// exit. this timeout ensures that we don't stay resident when no
|
||||
// clients are interested in connecting after spawning the daemon.
|
||||
//
|
||||
rv = PR_Poll(poll_fds, poll_fd_count, PR_SecondsToInterval(60 * 5));
|
||||
if (rv == -1) {
|
||||
printf("### PR_Poll failed [%d]\n", PR_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if (rv > 0) {
|
||||
//
|
||||
// process clients that are ready
|
||||
//
|
||||
for (i = 1; i < poll_fd_count; ++i) {
|
||||
if (poll_fds[i].out_flags != 0) {
|
||||
poll_fds[i].in_flags = clients[i].Process(poll_fds[i].fd, poll_fds[i].out_flags);
|
||||
poll_fds[i].out_flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// cleanup any dead clients (indicated by a zero in_flags)
|
||||
//
|
||||
for (i = poll_fd_count - 1; i >= 1; --i) {
|
||||
if (poll_fds[i].in_flags == 0)
|
||||
RemoveClient(i);
|
||||
}
|
||||
|
||||
//
|
||||
// check for new connection
|
||||
//
|
||||
if (poll_fds[0].out_flags & PR_POLL_READ) {
|
||||
printf("### got new connection\n");
|
||||
|
||||
PRNetAddr client_addr;
|
||||
memset(&client_addr, 0, sizeof(client_addr));
|
||||
PRFileDesc *client_fd;
|
||||
|
||||
client_fd = PR_Accept(listen_fd, &client_addr, PR_INTERVAL_NO_WAIT);
|
||||
if (client_fd == NULL) {
|
||||
printf("### PR_Accept failed [%d]\n", PR_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
// make socket non-blocking
|
||||
PRSocketOptionData opt;
|
||||
opt.option = PR_SockOpt_Nonblocking;
|
||||
opt.value.non_blocking = PR_TRUE;
|
||||
PR_SetSocketOption(client_fd, &opt);
|
||||
|
||||
if (AddClient(client_fd) != 0)
|
||||
PR_Close(client_fd);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// shutdown if no clients
|
||||
//
|
||||
if (poll_fd_count == 1) {
|
||||
printf("### shutting down\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void InitModuleReg(const char *exePath)
|
||||
{
|
||||
static const char modDir[] = "ipc/modules";
|
||||
|
||||
char *p = PL_strrchr(exePath, IPC_PATH_SEP_CHAR);
|
||||
if (p == NULL) {
|
||||
printf("### unexpected exe path\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int baseLen = p - exePath;
|
||||
int finalLen = baseLen + 1 + sizeof(modDir);
|
||||
|
||||
// build full path to ipc modules
|
||||
char *buf = (char*) malloc(finalLen);
|
||||
memcpy(buf, exePath, baseLen);
|
||||
buf[baseLen] = IPC_PATH_SEP_CHAR;
|
||||
memcpy(buf + baseLen + 1, modDir, sizeof(modDir));
|
||||
|
||||
IPC_InitModuleReg(buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
PRFileDesc *listen_fd;
|
||||
PRNetAddr addr;
|
||||
|
||||
#ifdef XP_UNIX
|
||||
signal(SIGINT, SIG_IGN);
|
||||
umask(0077); // ensure strict file permissions
|
||||
#endif
|
||||
|
||||
start:
|
||||
#ifdef IPC_USE_INET
|
||||
listen_fd = PR_OpenTCPSocket(PR_AF_INET);
|
||||
if (!listen_fd) {
|
||||
printf("### PR_OpenUDPSocket failed [%d]\n", PR_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_InitializeNetAddr(PR_IpAddrLoopback, IPC_PORT, &addr);
|
||||
|
||||
#else
|
||||
const char *socket_path;
|
||||
if (argc < 2)
|
||||
socket_path = IPC_DEFAULT_SOCKET_PATH;
|
||||
else
|
||||
socket_path = argv[1];
|
||||
|
||||
listen_fd = PR_OpenTCPSocket(PR_AF_LOCAL);
|
||||
if (!listen_fd) {
|
||||
printf("### PR_OpenUDPSocket failed [%d]\n", PR_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr.local.family = PR_AF_LOCAL;
|
||||
PL_strncpyz(addr.local.path, socket_path, sizeof(addr.local.path));
|
||||
#endif
|
||||
|
||||
if (PR_Bind(listen_fd, &addr) != PR_SUCCESS) {
|
||||
printf("### PR_Bind failed [%d]\n", PR_GetError());
|
||||
//
|
||||
// failure here indicates that another process may be bound
|
||||
// to the socket already. let's try connecting to that socket.
|
||||
// if connect fails, then the socket is probably stale.
|
||||
//
|
||||
if (PR_Connect(listen_fd, &addr, PR_SecondsToInterval(2)) == PR_SUCCESS) {
|
||||
//
|
||||
// looks like another process is active. silently exit.
|
||||
//
|
||||
printf("### looks like another instance of the daemon is active; sleeping...\n");
|
||||
//
|
||||
// sleep here to avoid triggering the shutdown procedure in the
|
||||
// other daemon. 10 seconds should be long enough for the client
|
||||
// to have established a connection.
|
||||
//
|
||||
PR_Sleep(PR_SecondsToInterval(10));
|
||||
printf("### exiting\n");
|
||||
PR_Close(listen_fd);
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
// OK, the socket is probably stale.
|
||||
//
|
||||
printf("### socket appears to be stale\n");
|
||||
#ifdef IPC_USE_INET
|
||||
printf("### waiting for TIMEWAIT period to expire...\n");
|
||||
PR_Sleep(PR_SecondsToInterval(60));
|
||||
#else
|
||||
printf("### deleting socket at %s\n", socket_path);
|
||||
PR_Delete(socket_path);
|
||||
#endif
|
||||
PR_Close(listen_fd);
|
||||
goto start;
|
||||
}
|
||||
|
||||
InitModuleReg(argv[0]);
|
||||
|
||||
if (PR_Listen(listen_fd, 5) != PR_SUCCESS) {
|
||||
printf("### PR_Listen failed [%d]\n", PR_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
Process(listen_fd);
|
||||
|
||||
IPC_ShutdownModuleReg();
|
||||
|
||||
//
|
||||
// XXX enable this delay for startup testing
|
||||
//
|
||||
//printf("### sleeping for 5 seconds...\n");
|
||||
//PR_Sleep(PR_SecondsToInterval(5));
|
||||
|
||||
#ifndef IPC_USE_INET
|
||||
printf("### deleting socket at %s\n", socket_path);
|
||||
//
|
||||
// we delete the file itself first to avoid a race between shutting
|
||||
// ourselves down and another instance of the daemon starting up.
|
||||
//
|
||||
if (PR_Delete(socket_path) != PR_SUCCESS) {
|
||||
printf("### PR_Delete failed [%d]\n", PR_GetError());
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("### closing socket\n");
|
||||
|
||||
if (PR_Close(listen_fd) != PR_SUCCESS) {
|
||||
printf("### PR_Close failed [%d]\n", PR_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IPC API
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg)
|
||||
{
|
||||
// lookup handler for this message's topic and forward message to it.
|
||||
ipcModule *module = IPC_GetModuleByID(msg->Target());
|
||||
if (module)
|
||||
module->HandleMsg(client, msg);
|
||||
else
|
||||
printf("### no registered module; ignoring message\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IPC_SendMsg(ipcClient *client, ipcMessage *msg)
|
||||
{
|
||||
if (client == NULL) {
|
||||
int i;
|
||||
//
|
||||
// walk clients array
|
||||
//
|
||||
for (i = 1; i < poll_fd_count - 1; ++i)
|
||||
IPC_SendMsg(&clients[i], msg->Clone());
|
||||
|
||||
// send to last client w/o cloning to avoid extra malloc
|
||||
IPC_SendMsg(&clients[i], msg);
|
||||
}
|
||||
else {
|
||||
client->EnqueueOutboundMsg(msg);
|
||||
//
|
||||
// since this client's Process method may have already been
|
||||
// called, we need to explicitly set the PR_POLL_WRITE flag.
|
||||
//
|
||||
int client_index = client - clients;
|
||||
poll_fds[client_index].in_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ipcClient *IPC_GetClientByID(int clientID)
|
||||
{
|
||||
// linear search OK since number of clients should be small
|
||||
for (int i = 1; i < poll_fd_count; ++i) {
|
||||
if (clients[i].ID() == clientID)
|
||||
return &clients[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ipcClient *IPC_GetClientByName(const char *name)
|
||||
{
|
||||
// linear search OK since number of clients should be small
|
||||
for (int i = 1; i < poll_fd_count; ++i) {
|
||||
if (strcmp(clients[i].Name(), name) == 0)
|
||||
return &clients[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ipcClient *IPC_GetClients(int *count)
|
||||
{
|
||||
*count = poll_fd_count - 1;
|
||||
return &clients[1];
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef IPCD_H__
|
||||
#define IPCD_H__
|
||||
|
||||
#include "ipcModule.h"
|
||||
|
||||
#ifdef IPC_DAEMON
|
||||
#define IPC_METHOD _declspec(dllexport)
|
||||
#else
|
||||
#define IPC_METHOD _declspec(dllimport)
|
||||
#endif
|
||||
|
||||
class ipcClient;
|
||||
class ipcMessage;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IPC daemon API
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern "C" {
|
||||
|
||||
//
|
||||
// IPC_DispatchMsg
|
||||
//
|
||||
// params:
|
||||
// client - identifies the client from which this message originated.
|
||||
// msg - the message received. this function does not modify |msg|,
|
||||
// and ownership stays with the caller.
|
||||
//
|
||||
int IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg);
|
||||
|
||||
//
|
||||
// IPC_SendMsg
|
||||
//
|
||||
// params:
|
||||
// client - identifies the client that should receive the message.
|
||||
// if null, then the message is broadcast to all clients.
|
||||
// msg - the message to be sent. this function subsumes
|
||||
// ownership of the message. the caller must not attempt
|
||||
// to access |msg| after this function returns.
|
||||
// return:
|
||||
// 0 - on success
|
||||
//
|
||||
IPC_METHOD int IPC_SendMsg(ipcClient *client, ipcMessage *msg);
|
||||
|
||||
//
|
||||
// returns the client ID dynamically generated for the given client.
|
||||
//
|
||||
int IPC_GetClientID(ipcClient *client);
|
||||
|
||||
//
|
||||
// returns the client name (NULL if the client did not specify a name).
|
||||
//
|
||||
const char *IPC_GetClientName(ipcClient *client);
|
||||
|
||||
//
|
||||
// client lookup functions
|
||||
//
|
||||
ipcClient *IPC_GetClientByID(int clientID);
|
||||
ipcClient *IPC_GetClientByName(const char *clientName);
|
||||
|
||||
//
|
||||
// return array of all clients, length equal to |count|.
|
||||
//
|
||||
ipcClient *IPC_GetClients(int *count);
|
||||
|
||||
//
|
||||
// returns the ipcModule object registered under the given module ID.
|
||||
//
|
||||
ipcModule *IPC_GetModuleByID(const nsID &moduleID);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // !IPCD_H__
|
|
@ -0,0 +1,52 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla IPC.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2002
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Darin Fisher <darin@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = ipc
|
||||
|
||||
XPIDLSRCS = \
|
||||
ipcIService.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsISimpleEnumerator;
|
||||
interface ipcIMessageObserver;
|
||||
interface ipcIClientObserver;
|
||||
|
||||
/**
|
||||
* the IPC service provides the means to communicate with an external IPC
|
||||
* daemon and/or other mozilla-based applications sharing the same user
|
||||
* profile. the IPC daemon hosts modules (some builtin and others dynamically
|
||||
* loaded) with which applications may interact.
|
||||
*
|
||||
* at application startup, the IPC service will attempt to establish a
|
||||
* connection with the IPC daemon for the current profile. (there is one IPC
|
||||
* daemon per profile.) the IPC daemon will be automatically started if
|
||||
* necessary. when a connection has been established, the IPC service will
|
||||
* broadcast an "ipc-startup" notification using the observer service.
|
||||
*
|
||||
* when the connection to the IPC daemon is closed (due to error, profile
|
||||
* change, or normal shutdown), an "ipc-shutdown" notification will be
|
||||
* broadcast.
|
||||
*
|
||||
* each client has a name. the client name need not be unique across all
|
||||
* clients, but it is usually good if it is. this IPC service does not require
|
||||
* unique names. instead, the IPC daemon assigns each client a unique ID that
|
||||
* is good for the current "session." clients can query other clients by name
|
||||
* or by ID. the IPC service supports forwarding messages from one client to
|
||||
* another via the IPC daemon.
|
||||
*
|
||||
* for performance reasons, this system should not be used to transfer large
|
||||
* amounts of data. instead, applications may choose to utilize shared memory,
|
||||
* and rely on the IPC service for synchronization and small message transfer
|
||||
* only.
|
||||
*/
|
||||
[scriptable, uuid(53d3e3a7-528f-4b09-9eab-9416272568c0)]
|
||||
interface ipcIService : nsISupports
|
||||
{
|
||||
/**
|
||||
* returns the "client ID" assigned to this application by the IPC daemon.
|
||||
* this number is the name given to our application for the current
|
||||
* session. after a profile change, our client ID will change.
|
||||
*
|
||||
* @throws NS_ERROR_NOT_AVAILABLE if no connection to the IPC daemon.
|
||||
*/
|
||||
readonly attribute unsigned long clientID;
|
||||
|
||||
/**
|
||||
* client aliases give the client a way to register itself under multiple
|
||||
* names. for example, the mozilla browser might register itself under
|
||||
* the name "mozilla", but it could also register itself under the aliases
|
||||
* "browser", "mail", "news", "addrbook", and so on. aliases provide a
|
||||
* simple mechanism for clients to discover other clients.
|
||||
*/
|
||||
void addClientAlias(in ACString aAlias);
|
||||
void removeClientAlias(in ACString aAlias);
|
||||
|
||||
/**
|
||||
* query info about a particular client given its client name.
|
||||
*
|
||||
* @param aNameOrAlias name or alias of the client being queried.
|
||||
* @param aObserver client observer to be notified.
|
||||
*
|
||||
* @return integer token identifying this request.
|
||||
*/
|
||||
unsigned long queryClientByName(in ACString aNameOrAlias,
|
||||
in ipcIClientObserver aObserver);
|
||||
|
||||
/**
|
||||
* query info about a particular client given its client ID.
|
||||
*
|
||||
* @return integer token identifying this request.
|
||||
*/
|
||||
unsigned long queryClientByID(in unsigned long aClientID,
|
||||
in ipcIClientObserver aObserver);
|
||||
|
||||
/**
|
||||
* set client observer. observer is notified whenever the status of
|
||||
* a client changes.
|
||||
*
|
||||
* @param aClientID the ID of the client to observe.
|
||||
* @param aObserver the client observer.
|
||||
*/
|
||||
void setClientObserver(in unsigned long aClientID,
|
||||
in ipcIClientObserver aObserver);
|
||||
|
||||
/**
|
||||
* set a message observer for a particular message target.
|
||||
*
|
||||
* @param aTarget the message target being observed. any existing
|
||||
* observer will be replaced.
|
||||
* @param aObserver the message observer to receive incoming messages
|
||||
* for the specified target. pass null to remove the
|
||||
* existing observer.
|
||||
*/
|
||||
void setMessageObserver(in nsIDRef aTarget, in ipcIMessageObserver aObserver);
|
||||
|
||||
/**
|
||||
* send message asynchronously to the IPC daemon. there is no guarantee
|
||||
* that the message will be delivered.
|
||||
*
|
||||
* @param aTarget the target of the message. this is the ID of the
|
||||
* daemon module that should receive this message.
|
||||
* @param aData the data of the message.
|
||||
* @param aDataLen the data length of the message.
|
||||
*/
|
||||
[noscript] void sendMessage(in nsIDRef aTarget,
|
||||
in string aData,
|
||||
in unsigned long aDataLen);
|
||||
|
||||
/**
|
||||
* forward message asynchronously via the IPC daemon to another application
|
||||
* process. there is no guarantee that the message will be delivered.
|
||||
*
|
||||
* @param aClientID the client ID of the foreign application that should
|
||||
* receive this message.
|
||||
*
|
||||
* other parameters are identical to those for sendMessage.
|
||||
*/
|
||||
[noscript] void forwardMessage(in unsigned long aClientID,
|
||||
in nsIDRef aTarget,
|
||||
in string aData,
|
||||
in unsigned long aDataLen);
|
||||
};
|
||||
|
||||
[scriptable, uuid(e40a4a3c-2dc1-470e-ab7f-5675fe1f1384)]
|
||||
interface ipcIMessageObserver : nsISupports
|
||||
{
|
||||
/**
|
||||
* @param aTarget the target of the message, corresponding to the target
|
||||
* this observer was registered under. this parameter is
|
||||
* passed to allow an observer instance to receive
|
||||
* messages for more than one target.
|
||||
* @param aData the data of the message.
|
||||
* @param aDataLen the data length of the message.
|
||||
*/
|
||||
[noscript] void onMessageAvailable(in nsIDRef aTarget,
|
||||
in string aData,
|
||||
in unsigned long aDataLen);
|
||||
};
|
||||
|
||||
[scriptable, uuid(e858d450-62b2-482d-99bb-3b5425aa28cc)]
|
||||
interface ipcIClientInfo : nsISupports
|
||||
{
|
||||
readonly attribute unsigned long ID;
|
||||
readonly attribute ACString name;
|
||||
readonly attribute nsISimpleEnumerator aliases;
|
||||
readonly attribute nsISimpleEnumerator targets;
|
||||
};
|
||||
|
||||
[scriptable, uuid(42283079-030c-4b13-b069-a08b7ad5eab2)]
|
||||
interface ipcIClientObserver : nsISupports
|
||||
{
|
||||
/**
|
||||
* client status values
|
||||
*/
|
||||
const unsigned long CLIENT_UP = 1;
|
||||
const unsigned long CLIENT_DOWN = 2;
|
||||
|
||||
/**
|
||||
* @param aRequestToken the request token returned from the call that
|
||||
* initiated this observation. 0 if initiated
|
||||
* from a setClientObserver call.
|
||||
* @param aClientInfo client info.
|
||||
* @param aStatus client status (e.g. CLIENT_UP).
|
||||
*/
|
||||
void onClientStatus(in unsigned long aRequestToken,
|
||||
in ipcIClientInfo aClientInfo,
|
||||
in unsigned long aStatus);
|
||||
|
||||
// XXX do we care about changes to the aliases and targets supported
|
||||
// by a client? if so, how should we pass this information up?
|
||||
};
|
|
@ -0,0 +1,65 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla IPC.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2002
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Darin Fisher <darin@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = ipc
|
||||
LIBRARY_NAME = ipc_s
|
||||
EXPORT_LIBRARY = 1
|
||||
FORCE_STATIC_LIB = 1
|
||||
MODULE_NAME = ipc
|
||||
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
necko \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
ipcService.cpp \
|
||||
ipcTransport.cpp \
|
||||
ipcSocketProvider.cpp
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../common \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,193 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ipcConfig.h"
|
||||
#include "ipcService.h"
|
||||
#include "plstr.h"
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
{
|
||||
ipcIMessageObserver *obs = (ipcIMessageObserver *) aData;
|
||||
NS_RELEASE(obs);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcService
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ipcService::ipcService()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
ipcService::~ipcService()
|
||||
{
|
||||
if (mTransport) {
|
||||
mTransport->Shutdown();
|
||||
NS_RELEASE(mTransport);
|
||||
}
|
||||
|
||||
mObserverDB.Reset(ipcReleaseMessageObserver, nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ipcService::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
mTransport = new ipcTransport();
|
||||
if (!mTransport)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mTransport);
|
||||
|
||||
// XXX use directory service to locate socket
|
||||
rv = mTransport->Init(NS_LITERAL_CSTRING(IPC_DEFAULT_SOCKET_PATH), this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// interface impl
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ipcService, ipcIService)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::GetClientID(PRUint32 *clientID)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::AddClientAlias(const nsACString &alias)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::RemoveClientAlias(const nsACString &alias)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::QueryClientByName(const nsACString &name,
|
||||
ipcIClientObserver *observer,
|
||||
PRUint32 *token)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::QueryClientByID(PRUint32 clientID,
|
||||
ipcIClientObserver *observer,
|
||||
PRUint32 *token)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::SetClientObserver(PRUint32 clientID,
|
||||
ipcIClientObserver *observer)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::SetMessageObserver(const nsID &target, ipcIMessageObserver *observer)
|
||||
{
|
||||
nsIDKey key(target);
|
||||
|
||||
ipcIMessageObserver *cobs = (ipcIMessageObserver *) mObserverDB.Get(&key);
|
||||
if (cobs) {
|
||||
NS_RELEASE(cobs);
|
||||
if (!observer) {
|
||||
mObserverDB.Remove(&key);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
if (observer) {
|
||||
NS_ADDREF(observer);
|
||||
mObserverDB.Put(&key, observer);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::SendMessage(const nsID &target,
|
||||
const char *data,
|
||||
PRUint32 dataLen)
|
||||
{
|
||||
NS_ENSURE_TRUE(mTransport, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
ipcMessage *msg = new ipcMessage();
|
||||
if (!msg)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
msg->Init(target, data, dataLen);
|
||||
|
||||
mTransport->SendMsg(msg);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::ForwardMessage(PRUint32 clientID,
|
||||
const nsID &target,
|
||||
const char *data,
|
||||
PRUint32 dataLen)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcTransportObserver impl
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
ipcService::OnMsgAvailable(const ipcMessage *msg)
|
||||
{
|
||||
nsIDKey key(msg->Target());
|
||||
|
||||
ipcIMessageObserver *observer = (ipcIMessageObserver *) mObserverDB.Get(&key);
|
||||
if (observer)
|
||||
observer->OnMessageAvailable(msg->Target(),
|
||||
msg->Data(),
|
||||
msg->DataLen());
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcService_h__
|
||||
#define ipcService_h__
|
||||
|
||||
#include "ipcIService.h"
|
||||
#include "ipcTransport.h"
|
||||
#include "ipcMessage.h"
|
||||
#include "ipcMessageQ.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ipcService
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class ipcService : public ipcIService
|
||||
, public ipcTransportObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IPCISERVICE
|
||||
|
||||
ipcService();
|
||||
virtual ~ipcService();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
private:
|
||||
// ipcTransportObserver:
|
||||
void OnMsgAvailable(const ipcMessage *);
|
||||
|
||||
nsHashtable mObserverDB;
|
||||
ipcTransport *mTransport;
|
||||
};
|
||||
|
||||
#endif // !ipcService_h__
|
|
@ -0,0 +1,64 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ipcSocketProvider.h"
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcSocketProvider::NewSocket(const char *host,
|
||||
PRInt32 port,
|
||||
const char *proxyHost,
|
||||
PRInt32 proxyPort,
|
||||
PRFileDesc **fd,
|
||||
nsISupports **securityInfo)
|
||||
{
|
||||
*fd = PR_OpenTCPSocket(PR_AF_LOCAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcSocketProvider::AddToSocket(const char *host,
|
||||
PRInt32 port,
|
||||
const char *proxyHost,
|
||||
PRInt32 proxyPort,
|
||||
PRFileDesc *fd,
|
||||
nsISupports **securityInfo)
|
||||
{
|
||||
NS_NOTREACHED("unexpected");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(ipcSocketProvider, nsISocketProvider)
|
|
@ -0,0 +1,53 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcSocketProvider_h__
|
||||
#define ipcSocketProvider_h__
|
||||
|
||||
#include "nsISocketProvider.h"
|
||||
|
||||
class ipcSocketProvider : public nsISocketProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISOCKETPROVIDER
|
||||
|
||||
ipcSocketProvider() { NS_INIT_ISUPPORTS(); }
|
||||
virtual ~ipcSocketProvider() { }
|
||||
};
|
||||
|
||||
#endif // !ipcSocketProvider_h__
|
|
@ -0,0 +1,537 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsISocketTransportService.h"
|
||||
#include "nsISocketTransport.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIProcess.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "netCore.h"
|
||||
#include "prerror.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#include "ipcConfig.h"
|
||||
#include "ipcTransport.h"
|
||||
#include "ipcm.h"
|
||||
|
||||
#define LOG(args) printf args
|
||||
|
||||
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcTransport
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ipcTransport::~ipcTransport()
|
||||
{
|
||||
if (mFD)
|
||||
PR_Close(mFD);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ipcTransport::Init(const nsACString &socketPath, ipcTransportObserver *obs)
|
||||
{
|
||||
LOG((">>> ipcTransport::Init\n"));
|
||||
|
||||
mSocketPath = socketPath;
|
||||
mObserver = obs;
|
||||
|
||||
nsCOMPtr<nsIObserverService> observ(do_GetService("@mozilla.org/observer-service;1"));
|
||||
if (observ) {
|
||||
observ->AddObserver(this, "xpcom-shutdown", PR_FALSE);
|
||||
observ->AddObserver(this, "profile-change-net-teardown", PR_FALSE);
|
||||
}
|
||||
|
||||
return Connect();
|
||||
}
|
||||
|
||||
nsresult
|
||||
ipcTransport::Shutdown()
|
||||
{
|
||||
LOG((">>> ipcTransport::Shutdown\n"));
|
||||
|
||||
mHaveConnection = PR_FALSE;
|
||||
|
||||
if (mReadRequest) {
|
||||
mReadRequest->Cancel(NS_BINDING_ABORTED);
|
||||
mReadRequest = nsnull;
|
||||
}
|
||||
if (mWriteRequest) {
|
||||
mWriteRequest->Cancel(NS_BINDING_ABORTED);
|
||||
mWriteRequest = nsnull;
|
||||
mWriteSuspended = PR_FALSE;
|
||||
}
|
||||
mTransport = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ipcTransport::SendMsg(ipcMessage *msg)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(msg);
|
||||
|
||||
LOG((">>> ipcTransport::SendMsg [dataLen=%u]\n", msg->DataLen()));
|
||||
|
||||
if (!mHaveConnection) {
|
||||
LOG((">>> delaying message until connected\n"));
|
||||
mDelayedQ.Append(msg);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return SendMsg_Internal(msg);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ipcTransport::SendMsg_Internal(ipcMessage *msg)
|
||||
{
|
||||
LOG((">>> ipcTransport::SendMsg_Internal [dataLen=%u]\n", msg->DataLen()));
|
||||
|
||||
mSendQ.EnqueueMsg(msg);
|
||||
|
||||
if (!mWriteRequest) {
|
||||
if (!mTransport)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = mTransport->AsyncWrite(&mSendQ, nsnull, 0, PRUint32(-1), 0,
|
||||
getter_AddRefs(mWriteRequest));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
if (mWriteSuspended) {
|
||||
mWriteRequest->Resume();
|
||||
mWriteSuspended = PR_FALSE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ipcTransport::Connect()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
LOG((">>> ipcTransport::Connect\n"));
|
||||
|
||||
if (++mConnectionAttemptCount > 20) {
|
||||
LOG((">>> giving up after 20 unsuccessful connection attempts\n"));
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
rv = CreateTransport();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mTransport->AsyncRead(&mReceiver, nsnull, 0, PRUint32(-1), 0,
|
||||
getter_AddRefs(mReadRequest));
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
ipcTransport::OnMsgAvailable(const ipcMessage *msg)
|
||||
{
|
||||
LOG((">>> ipcTransport::OnMsgAvailable [dataLen=%u]\n", msg->DataLen()));
|
||||
|
||||
//
|
||||
// all IPCM messages stop here.
|
||||
//
|
||||
if (msg->Target().Equals(IPCM_TARGET)) {
|
||||
//
|
||||
// check for startup PING
|
||||
//
|
||||
if (!mHaveConnection) {
|
||||
if (IPCM_GetMsgType(msg) == IPCM_MSG_PING) {
|
||||
LOG((">>> connection established!\n"));
|
||||
mHaveConnection = PR_TRUE;
|
||||
//
|
||||
// move messages off the delayed queue
|
||||
//
|
||||
while (!mDelayedQ.IsEmpty()) {
|
||||
ipcMessage *msg = mDelayedQ.First();
|
||||
mDelayedQ.RemoveFirst();
|
||||
SendMsg_Internal(msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
LOG((">>> received bogus response to our ping!\n"));
|
||||
}
|
||||
}
|
||||
else if (mObserver)
|
||||
mObserver->OnMsgAvailable(msg);
|
||||
}
|
||||
|
||||
void
|
||||
ipcTransport::OnStartRequest(nsIRequest *req)
|
||||
{
|
||||
nsresult status;
|
||||
req->GetStatus(&status);
|
||||
|
||||
if (NS_SUCCEEDED(status) && !mHaveConnection && !mSentInitialMsgs) {
|
||||
//
|
||||
// send "startup messages"
|
||||
//
|
||||
// PING - expect a PING in response to this message
|
||||
// CNAME - expect nothing in response to this message
|
||||
//
|
||||
SendMsg_Internal(new ipcmMessagePING());
|
||||
SendMsg_Internal(new ipcmMessageCNAME("test-app")); // XXX need real client name
|
||||
|
||||
mSentInitialMsgs = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ipcTransport::OnStopRequest(nsIRequest *req, nsresult status)
|
||||
{
|
||||
LOG((">>> ipcTransport::OnStopRequest [status=%x]\n", status));
|
||||
|
||||
if (status == NS_BINDING_ABORTED)
|
||||
return;
|
||||
|
||||
if (NS_FAILED(status) && !mTimer) {
|
||||
nsresult rv;
|
||||
//
|
||||
// connection failure
|
||||
//
|
||||
rv = SpawnDaemon();
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG((">>> failed to spawn daemon [rv=%x]\n", rv));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// re-initialize connection after timeout
|
||||
//
|
||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG((">>> failed to create timer [rv=%x]\n", rv));
|
||||
return;
|
||||
}
|
||||
|
||||
// use a simple exponential growth algorithm n*2^(n-1)
|
||||
PRUint32 ms = 1000 * (1 << (mConnectionAttemptCount - 1));
|
||||
|
||||
LOG((">>> waiting %u milliseconds\n", ms));
|
||||
|
||||
rv = mTimer->Init(this, ms, nsITimer::TYPE_ONE_SHOT);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG((">>> failed to initialize timer [rv=%x]\n", rv));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (req == mReadRequest)
|
||||
mReadRequest = nsnull;
|
||||
else if (req == mWriteRequest) {
|
||||
mWriteRequest = nsnull;
|
||||
mWriteSuspended = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
ipcTransport::CreateTransport()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsISocketTransportService> sts(
|
||||
do_GetService(kSocketTransportServiceCID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = sts->CreateTransportOfType(IPC_SOCKET_TYPE,
|
||||
"127.0.0.1",
|
||||
IPC_PORT,
|
||||
nsnull,
|
||||
1024,
|
||||
1024*16,
|
||||
getter_AddRefs(mTransport));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
#ifndef IPC_USE_INET
|
||||
nsCOMPtr<nsISocketTransport> st(do_QueryInterface(mTransport, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRNetAddr addr;
|
||||
addr.local.family = PR_AF_LOCAL;
|
||||
PL_strncpyz(addr.local.path, mSocketPath.get(), sizeof(addr.local.path));
|
||||
|
||||
rv = st->SetAddress(&addr);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ipcTransport::SpawnDaemon()
|
||||
{
|
||||
LOG((">>> ipcTransport::SpawnDaemon\n"));
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> file;
|
||||
|
||||
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, getter_AddRefs(file));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = file->AppendNative(NS_LITERAL_CSTRING(IPC_DAEMON_APP_NAME));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIProcess> proc(do_CreateInstance(NS_PROCESS_CONTRACTID,&rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = proc->Init(file);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRUint32 pid;
|
||||
return proc->Run(PR_FALSE, nsnull, 0, &pid);
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS0(ipcTransport)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcTransport::Observe(nsISupports *subject, const char *topic, const PRUnichar *data)
|
||||
{
|
||||
LOG((">>> ipcTransport::Observe [topic=%s]\n", topic));
|
||||
|
||||
if (strcmp(topic, "timer-callback") == 0) {
|
||||
//
|
||||
// try reconnecting to the daemon
|
||||
//
|
||||
Shutdown();
|
||||
Connect();
|
||||
|
||||
mTimer = nsnull;
|
||||
}
|
||||
else if (strcmp(topic, "xpcom-shutdown") == 0 ||
|
||||
strcmp(topic, "profile-change-net-teardown") == 0)
|
||||
Shutdown();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcSendQueue
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
ipcSendQueue::AddRef()
|
||||
{
|
||||
return mTransport->AddRef();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
ipcSendQueue::Release()
|
||||
{
|
||||
return mTransport->Release();
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE2(ipcSendQueue, nsIStreamProvider, nsIRequestObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcSendQueue::OnStartRequest(nsIRequest *request,
|
||||
nsISupports *context)
|
||||
{
|
||||
LOG((">>> ipcSendQueue::OnStartRequest\n"));
|
||||
|
||||
if (mTransport)
|
||||
mTransport->OnStartRequest(request);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcSendQueue::OnStopRequest(nsIRequest *request,
|
||||
nsISupports *context,
|
||||
nsresult status)
|
||||
{
|
||||
LOG((">>> ipcSendQueue::OnStopRequest [status=%x]\n", status));
|
||||
|
||||
if (mTransport)
|
||||
mTransport->OnStopRequest(request, status);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct ipcWriteState
|
||||
{
|
||||
ipcMessage *msg;
|
||||
PRBool complete;
|
||||
};
|
||||
|
||||
static NS_METHOD ipcWriteMessage(nsIOutputStream *stream,
|
||||
void *closure,
|
||||
char *segment,
|
||||
PRUint32 offset,
|
||||
PRUint32 count,
|
||||
PRUint32 *countWritten)
|
||||
{
|
||||
ipcWriteState *state = (ipcWriteState *) closure;
|
||||
|
||||
if (state->msg->WriteTo(segment, count,
|
||||
countWritten, &state->complete) != PR_SUCCESS)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcSendQueue::OnDataWritable(nsIRequest *request,
|
||||
nsISupports *context,
|
||||
nsIOutputStream *stream,
|
||||
PRUint32 offset,
|
||||
PRUint32 count)
|
||||
{
|
||||
PRUint32 n;
|
||||
nsresult rv;
|
||||
ipcWriteState state;
|
||||
PRBool wroteSomething = PR_FALSE;
|
||||
|
||||
LOG((">>> ipcSendQueue::OnDataWritable\n"));
|
||||
|
||||
while (!mQueue.IsEmpty()) {
|
||||
state.msg = mQueue.First();
|
||||
state.complete = PR_FALSE;
|
||||
|
||||
rv = stream->WriteSegments(ipcWriteMessage, &state, count, &n);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
if (state.complete) {
|
||||
LOG((">>> wrote message %u bytes\n", mQueue.First()->MsgLen()));
|
||||
mQueue.DeleteFirst();
|
||||
}
|
||||
|
||||
wroteSomething = PR_TRUE;
|
||||
}
|
||||
|
||||
if (wroteSomething)
|
||||
return NS_OK;
|
||||
|
||||
LOG((">>> suspending write request\n"));
|
||||
|
||||
mTransport->SetWriteSuspended(PR_TRUE);
|
||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ipcReceiver
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
ipcReceiver::AddRef()
|
||||
{
|
||||
return mTransport->AddRef();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
ipcReceiver::Release()
|
||||
{
|
||||
return mTransport->Release();
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE2(ipcReceiver, nsIStreamListener, nsIRequestObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcReceiver::OnStartRequest(nsIRequest *request,
|
||||
nsISupports *context)
|
||||
{
|
||||
LOG((">>> ipcReceiver::OnStartRequest\n"));
|
||||
|
||||
if (mTransport)
|
||||
mTransport->OnStartRequest(request);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcReceiver::OnStopRequest(nsIRequest *request,
|
||||
nsISupports *context,
|
||||
nsresult status)
|
||||
{
|
||||
LOG((">>> ipcReceiver::OnStopRequest [status=%x]\n", status));
|
||||
|
||||
if (mTransport)
|
||||
mTransport->OnStopRequest(request, status);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_METHOD ipcReadMessage(nsIInputStream *stream,
|
||||
void *closure,
|
||||
const char *segment,
|
||||
PRUint32 offset,
|
||||
PRUint32 count,
|
||||
PRUint32 *countRead)
|
||||
{
|
||||
ipcReceiver *receiver = (ipcReceiver *) closure;
|
||||
return receiver->ReadSegment(segment, count, countRead);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcReceiver::OnDataAvailable(nsIRequest *request,
|
||||
nsISupports *context,
|
||||
nsIInputStream *stream,
|
||||
PRUint32 offset,
|
||||
PRUint32 count)
|
||||
{
|
||||
LOG((">>> ipcReceiver::OnDataAvailable [count=%u]\n", count));
|
||||
|
||||
PRUint32 countRead;
|
||||
return stream->ReadSegments(ipcReadMessage, this, count, &countRead);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ipcReceiver::ReadSegment(const char *ptr, PRUint32 count, PRUint32 *countRead)
|
||||
{
|
||||
*countRead = 0;
|
||||
while (count) {
|
||||
PRUint32 nread;
|
||||
PRBool complete;
|
||||
|
||||
mMsg.ReadFrom(ptr, count, &nread, &complete);
|
||||
|
||||
if (complete) {
|
||||
mTransport->OnMsgAvailable(&mMsg);
|
||||
mMsg.Reset();
|
||||
}
|
||||
|
||||
count -= nread;
|
||||
ptr += nread;
|
||||
*countRead += nread;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ipcTransport_h__
|
||||
#define ipcTransport_h__
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsITransport.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "prio.h"
|
||||
|
||||
#include "ipcMessage.h"
|
||||
#include "ipcMessageQ.h"
|
||||
|
||||
class ipcTransport;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ipcTransportObserver interface
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class ipcTransportObserver
|
||||
{
|
||||
public:
|
||||
virtual void OnMsgAvailable(const ipcMessage *) = 0;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ipcSendQueue
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class ipcSendQueue : public nsIStreamProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMPROVIDER
|
||||
|
||||
ipcSendQueue(ipcTransport *transport)
|
||||
: mTransport(transport)
|
||||
{ }
|
||||
virtual ~ipcSendQueue() { }
|
||||
|
||||
void EnqueueMsg(ipcMessage *msg) { mQueue.Append(msg); }
|
||||
|
||||
PRBool IsEmpty() { return mQueue.IsEmpty(); }
|
||||
|
||||
private:
|
||||
ipcTransport *mTransport;
|
||||
ipcMessageQ mQueue;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcReceiver
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ipcReceiver : public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
ipcReceiver(ipcTransport *transport)
|
||||
: mTransport(transport)
|
||||
{ }
|
||||
virtual ~ipcReceiver() { }
|
||||
|
||||
nsresult ReadSegment(const char *, PRUint32 count, PRUint32 *countRead);
|
||||
|
||||
private:
|
||||
ipcTransport *mTransport;
|
||||
ipcMessage mMsg; // message in progress
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcTransport
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ipcTransport : public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
ipcTransport()
|
||||
: mSendQ(this)
|
||||
, mReceiver(this)
|
||||
, mObserver(nsnull)
|
||||
, mFD(nsnull)
|
||||
, mWriteSuspended(PR_FALSE)
|
||||
, mSentInitialMsgs(PR_FALSE)
|
||||
, mHaveConnection(PR_FALSE)
|
||||
, mConnectionAttemptCount(0)
|
||||
{ }
|
||||
virtual ~ipcTransport();
|
||||
|
||||
nsresult Init(const nsACString &socketPath, ipcTransportObserver *);
|
||||
nsresult Shutdown();
|
||||
|
||||
// takes ownership of |msg|
|
||||
nsresult SendMsg(ipcMessage *msg);
|
||||
|
||||
public:
|
||||
// internal to implementation
|
||||
void OnMsgAvailable(const ipcMessage *);
|
||||
void SetWriteSuspended(PRBool val) { mWriteSuspended = val; }
|
||||
void OnStartRequest(nsIRequest *req);
|
||||
void OnStopRequest(nsIRequest *req, nsresult status);
|
||||
PRFileDesc *FD() { return mFD; }
|
||||
|
||||
private:
|
||||
//
|
||||
// helpers
|
||||
//
|
||||
nsresult Connect();
|
||||
nsresult SendMsg_Internal(ipcMessage *msg);
|
||||
nsresult CreateTransport();
|
||||
nsresult SpawnDaemon();
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
ipcSendQueue mSendQ;
|
||||
ipcReceiver mReceiver;
|
||||
ipcMessageQ mDelayedQ;
|
||||
ipcTransportObserver *mObserver;
|
||||
nsCOMPtr<nsITransport> mTransport;
|
||||
nsCOMPtr<nsIRequest> mReadRequest;
|
||||
nsCOMPtr<nsIRequest> mWriteRequest;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCString mSocketPath;
|
||||
PRFileDesc *mFD;
|
||||
PRPackedBool mWriteSuspended;
|
||||
PRPackedBool mSentInitialMsgs;
|
||||
PRPackedBool mHaveConnection;
|
||||
PRUint8 mConnectionAttemptCount;
|
||||
};
|
||||
|
||||
#endif // !ipcTransport_h__
|
|
@ -0,0 +1,54 @@
|
|||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = test_ipc
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
ipc \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
TestIPC.cpp \
|
||||
$(NULL)
|
||||
|
||||
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
LIBS = \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(XPCOM_LIBS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../util \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,207 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla IPC.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ipcIService.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIComponentRegistrar.h"
|
||||
#include "nsLiteralString.h"
|
||||
|
||||
static const nsID TestTargetID =
|
||||
{ /* e628fc6e-a6a7-48c7-adba-f241d1128fb8 */
|
||||
0xe628fc6e,
|
||||
0xa6a7,
|
||||
0x48c7,
|
||||
{0xad, 0xba, 0xf2, 0x41, 0xd1, 0x12, 0x8f, 0xb8}
|
||||
};
|
||||
|
||||
#define RETURN_IF_FAILED(rv, step) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (NS_FAILED(rv)) { \
|
||||
printf("*** %s failed: rv=%x\n", step, rv); \
|
||||
return rv;\
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
static nsIEventQueue* gEventQ = nsnull;
|
||||
static PRBool gKeepRunning = PR_TRUE;
|
||||
static PRInt32 gMsgCount = 0;
|
||||
|
||||
class myIpcMessageObserver : public ipcIMessageObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IPCIMESSAGEOBSERVER
|
||||
|
||||
myIpcMessageObserver()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(myIpcMessageObserver, ipcIMessageObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
myIpcMessageObserver::OnMessageAvailable(const nsID &target, const char *data, PRUint32 dataLen)
|
||||
{
|
||||
printf("*** got message: [%s]\n", data);
|
||||
|
||||
if (--gMsgCount == 0)
|
||||
gKeepRunning = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void SendMsg(ipcIService *ipc, const nsID &target, const char *data, PRUint32 dataLen)
|
||||
{
|
||||
printf("*** sending message: [dataLen=%u]\n", dataLen);
|
||||
|
||||
ipc->SendMessage(target, data, dataLen);
|
||||
gMsgCount++;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIServiceManager> servMan;
|
||||
NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
|
||||
nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
|
||||
NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
|
||||
if (registrar)
|
||||
registrar->AutoRegister(nsnull);
|
||||
|
||||
// Create the Event Queue for this thread...
|
||||
nsCOMPtr<nsIEventQueueService> eqs =
|
||||
do_GetService(kEventQueueServiceCID, &rv);
|
||||
RETURN_IF_FAILED(rv, "do_GetService(EventQueueService)");
|
||||
|
||||
rv = eqs->CreateMonitoredThreadEventQueue();
|
||||
RETURN_IF_FAILED(rv, "CreateMonitoredThreadEventQueue");
|
||||
|
||||
rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ);
|
||||
RETURN_IF_FAILED(rv, "GetThreadEventQueue");
|
||||
|
||||
nsCOMPtr<ipcIService> ipcServ(do_GetService("@mozilla.org/ipc/service;1", &rv));
|
||||
RETURN_IF_FAILED(rv, "do_GetService(ipcServ)");
|
||||
|
||||
ipcServ->SetMessageObserver(TestTargetID, new myIpcMessageObserver());
|
||||
|
||||
const char *data =
|
||||
"01 this is a really long message.\n"
|
||||
"02 this is a really long message.\n"
|
||||
"03 this is a really long message.\n"
|
||||
"04 this is a really long message.\n"
|
||||
"05 this is a really long message.\n"
|
||||
"06 this is a really long message.\n"
|
||||
"07 this is a really long message.\n"
|
||||
"08 this is a really long message.\n"
|
||||
"09 this is a really long message.\n"
|
||||
"10 this is a really long message.\n"
|
||||
"11 this is a really long message.\n"
|
||||
"12 this is a really long message.\n"
|
||||
"13 this is a really long message.\n"
|
||||
"14 this is a really long message.\n"
|
||||
"15 this is a really long message.\n"
|
||||
"16 this is a really long message.\n"
|
||||
"17 this is a really long message.\n"
|
||||
"18 this is a really long message.\n"
|
||||
"19 this is a really long message.\n"
|
||||
"20 this is a really long message.\n"
|
||||
"21 this is a really long message.\n"
|
||||
"22 this is a really long message.\n"
|
||||
"23 this is a really long message.\n"
|
||||
"24 this is a really long message.\n"
|
||||
"25 this is a really long message.\n"
|
||||
"26 this is a really long message.\n"
|
||||
"27 this is a really long message.\n"
|
||||
"28 this is a really long message.\n"
|
||||
"29 this is a really long message.\n"
|
||||
"30 this is a really long message.\n"
|
||||
"31 this is a really long message.\n"
|
||||
"32 this is a really long message.\n"
|
||||
"33 this is a really long message.\n"
|
||||
"34 this is a really long message.\n"
|
||||
"35 this is a really long message.\n"
|
||||
"36 this is a really long message.\n"
|
||||
"37 this is a really long message.\n"
|
||||
"38 this is a really long message.\n"
|
||||
"39 this is a really long message.\n"
|
||||
"40 this is a really long message.\n"
|
||||
"41 this is a really long message.\n"
|
||||
"42 this is a really long message.\n"
|
||||
"43 this is a really long message.\n"
|
||||
"44 this is a really long message.\n"
|
||||
"45 this is a really long message.\n"
|
||||
"46 this is a really long message.\n"
|
||||
"47 this is a really long message.\n"
|
||||
"48 this is a really long message.\n"
|
||||
"49 this is a really long message.\n"
|
||||
"50 this is a really long message.\n"
|
||||
"51 this is a really long message.\n"
|
||||
"52 this is a really long message.\n"
|
||||
"53 this is a really long message.\n"
|
||||
"54 this is a really long message.\n"
|
||||
"55 this is a really long message.\n"
|
||||
"56 this is a really long message.\n"
|
||||
"57 this is a really long message.\n"
|
||||
"58 this is a really long message.\n"
|
||||
"59 this is a really long message.\n"
|
||||
"60 this is a really long message.\n";
|
||||
SendMsg(ipcServ, TestTargetID, data, strlen(data)+1);
|
||||
|
||||
while (gKeepRunning)
|
||||
gEventQ->ProcessPendingEvents();
|
||||
|
||||
printf("*** processing remaining events\n");
|
||||
|
||||
// process any remaining events
|
||||
PLEvent *ev;
|
||||
while (NS_SUCCEEDED(gEventQ->GetEvent(&ev)) && ev)
|
||||
gEventQ->HandleEvent(ev);
|
||||
|
||||
printf("*** done\n");
|
||||
} // this scopes the nsCOMPtrs
|
||||
|
||||
// no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
|
||||
rv = NS_ShutdownXPCOM(nsnull);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla IPC.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2002
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Darin Fisher <darin@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = testmodule
|
||||
LIBRARY_NAME = testmodule
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = testmodule
|
||||
REQUIRES = xpcom \
|
||||
ipc \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = TestModule.cpp
|
||||
|
||||
SHARED_LIBRARY_LIBS = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)ipccom_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../common \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
EXTRA_DSO_LIBS = mozipcd
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
$(NSPR_LIBS) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_IPC_FILES = \
|
||||
$(LIB_PREFIX)$(LIBRARY_NAME)$(DLL_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_IPC_FILES)
|
||||
$(INSTALL) $^ $(DIST)/bin/ipc/modules
|
||||
|
||||
install:: $(_IPC_FILES)
|
||||
$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/ipc/modules
|
|
@ -0,0 +1,51 @@
|
|||
#include <stdio.h>
|
||||
#include "nscore.h"
|
||||
#include "ipcModule.h"
|
||||
#include "ipcMessage.h"
|
||||
#include "ipcd.h"
|
||||
|
||||
extern "C" NS_EXPORT ipcModule **IPC_GetModuleList();
|
||||
|
||||
static const nsID TestModuleID =
|
||||
{ /* e628fc6e-a6a7-48c7-adba-f241d1128fb8 */
|
||||
0xe628fc6e,
|
||||
0xa6a7,
|
||||
0x48c7,
|
||||
{0xad, 0xba, 0xf2, 0x41, 0xd1, 0x12, 0x8f, 0xb8}
|
||||
};
|
||||
|
||||
class TestModule : public ipcModule
|
||||
{
|
||||
public:
|
||||
void Shutdown()
|
||||
{
|
||||
printf("*** TestModule::Shutdown\n");
|
||||
}
|
||||
|
||||
const nsID &ID()
|
||||
{
|
||||
printf("*** TestModule::ID\n");
|
||||
return TestModuleID;
|
||||
}
|
||||
|
||||
void HandleMsg(ipcClient *client, const ipcMessage *msg)
|
||||
{
|
||||
printf("*** TestModule::HandleMsg [%s]\n", msg->Data());
|
||||
ipcMessage *outMsg = new ipcMessage();
|
||||
static const char buf[] = "pong";
|
||||
outMsg->Init(TestModuleID, buf, sizeof(buf));
|
||||
IPC_SendMsg(client, outMsg);
|
||||
}
|
||||
};
|
||||
|
||||
ipcModule **
|
||||
IPC_GetModuleList()
|
||||
{
|
||||
static TestModule testMod;
|
||||
static ipcModule *modules[2];
|
||||
|
||||
modules[0] = &testMod;
|
||||
modules[1] = NULL;
|
||||
|
||||
return modules;
|
||||
}
|
Загрузка…
Ссылка в новой задаче