SUBDIRS += vmblock-fuse
endif
SUBDIRS += xferlogs
-SUBDIRS += tests
+if ENABLE_TESTS
+ SUBDIRS += tests
+endif
if WITH_KERNEL_MODULES
SUBDIRS += modules
endif
[enable_docs="$enableval"],
[enable_docs="yes"])
+AC_ARG_ENABLE(
+ tests,
+ AS_HELP_STRING(
+ [--disable-tests],
+ [disable compilation of test code.]),
+ [enable_tests="$enableval"],
+ [enable_tests="auto"])
+
# If we're not going to use Gtk 2.0, disable Unity.
if test "$with_gtk2" != "yes"; then
enable_unity="no"
fi
fi
+#
+# Check for CUnit and disable test code if not available.
+#
+if test "$enable_tests" = "auto" -o "$enable_tests" = "yes"; then
+ AC_VMW_CHECK_LIB([cunit],
+ [CUNIT],
+ [],
+ [],
+ [],
+ [CUnit/CUnit.h],
+ [CU_initialize_registry],
+ [have_cunit=yes],
+ [have_cunit=no])
+ if test "$have_cunit" = "no"; then
+ if test "$enable_tests" = "yes"; then
+ AC_VMW_LIB_ERROR([CUNIT], [cunit])
+ else
+ AC_MSG_WARN([CUnit not found, tests won't be compiled.])
+ fi
+ fi
+fi
# If the user explicitly disables X11, then don't try to detect the X-related libraries
if test "$have_x" = "disabled"; then
AM_CONDITIONAL(HAVE_ICU, test "$with_icu" = "yes")
AM_CONDITIONAL(WITH_KERNEL_MODULES, test "$with_kernel_modules" = "yes")
AM_CONDITIONAL(ENABLE_UNITY, test "$enable_unity" = "yes")
+AM_CONDITIONAL(ENABLE_TESTS, test "$have_cunit" = "yes")
AM_CONDITIONAL(WITH_ROOT_PRIVILEGES, test "$with_root_privileges" = "yes")
AM_CONDITIONAL(HAVE_DOXYGEN, test "$have_doxygen" = "yes")
AM_CONDITIONAL(HAVE_FUSE, test "$have_fuse" = "yes")
#include "vmware/tools/plugin.h"
+
+/**
+ * Shorthand macro to both call CU_ASSERT() and return from the
+ * function if the assertion fails. Note that this file doesn't
+ * include CUnit.h, so you'll need to include that header to use
+ * this macro.
+ */
+#define RPCDEBUG_ASSERT(test, retval) do { \
+ CU_ASSERT(test); \
+ g_return_val_if_fail(test, retval); \
+} while (0)
+
+
struct RpcDebugPlugin;
/**
* the library to use the debugging functionality.
*/
typedef struct RpcDebugLibData {
- RpcChannel * (*newDebugChannel) (ToolsAppCtx *, struct RpcDebugLibData *);
- void (*shutdown) (ToolsAppCtx *, struct RpcDebugLibData *);
+ RpcChannel * (*newDebugChannel) (ToolsAppCtx *,
+ struct RpcDebugLibData *);
+ int (*run) (ToolsAppCtx *,
+ gpointer runMainLoop,
+ gpointer runData,
+ struct RpcDebugLibData *);
RpcDebugPlugin *debugPlugin;
} RpcDebugLibData;
RpcDebug_Initialize(ToolsAppCtx *ctx,
gchar *dbgPlugin);
-RpcChannel *
-RpcDebug_NewDebugChannel(ToolsAppCtx *ctx,
- RpcDebugLibData *data);
-
gboolean
RpcDebug_SendNext(RpcDebugMsgMapping *rpcdata,
RpcDebugMsgList *list);
char **res,
size_t *len);
-void
-RpcDebug_Shutdown(ToolsAppCtx *ctx,
- RpcDebugLibData *data);
-
G_END_DECLS
/** @} */
#include "vmware/tools/utils.h"
+/*
+ ******************************************************************************
+ * ToolsCoreCleanup -- */ /**
+ *
+ * Cleans up the main loop after it has executed. After this function
+ * returns, the fields of the state object shouldn't be used anymore.
+ *
+ * @param[in] state Service state.
+ *
+ ******************************************************************************
+ */
+
+static void
+ToolsCoreCleanup(ToolsServiceState *state)
+{
+ ToolsCore_UnloadPlugins(state);
+ if (state->ctx.rpc != NULL) {
+ RpcChannel_Destroy(state->ctx.rpc);
+ state->ctx.rpc = NULL;
+ }
+ g_key_file_free(state->ctx.config);
+ g_main_loop_unref(state->ctx.mainLoop);
+
+#if defined(G_PLATFORM_WIN32)
+ if (state->ctx.comInitialized) {
+ CoUninitialize();
+ state->ctx.comInitialized = FALSE;
+ }
+#endif
+
+#if !defined(_WIN32)
+ if (state->ctx.envp) {
+ System_FreeNativeEnviron(state->ctx.envp);
+ state->ctx.envp = NULL;
+ }
+#endif
+
+ g_object_unref(state->ctx.serviceObj);
+ state->ctx.serviceObj = NULL;
+ state->ctx.config = NULL;
+ state->ctx.mainLoop = NULL;
+}
+
+
/**
* Loads the debug library and calls its initialization function. This function
* panics is something goes wrong.
}
-/**
- * Cleans up the main loop after it has executed. After this function
- * returns, the fields of the state object shouldn't be used anymore.
+/*
+ ******************************************************************************
+ * ToolsCoreRunLoop -- */ /**
+ *
+ * Loads and registers all plugins, and runs the service's main loop.
*
* @param[in] state Service state.
+ *
+ * @return Exit code.
+ *
+ ******************************************************************************
*/
-void
-ToolsCore_Cleanup(ToolsServiceState *state)
+static int
+ToolsCoreRunLoop(ToolsServiceState *state)
{
- ToolsCore_UnloadPlugins(state);
- if (state->ctx.rpc != NULL) {
- RpcChannel_Destroy(state->ctx.rpc);
- state->ctx.rpc = NULL;
+ if (ToolsCore_GetTcloName(state) != NULL && !ToolsCore_InitRpc(state)) {
+ return 1;
}
- g_key_file_free(state->ctx.config);
- g_main_loop_unref(state->ctx.mainLoop);
-#if defined(G_PLATFORM_WIN32)
- if (state->ctx.comInitialized) {
- CoUninitialize();
- state->ctx.comInitialized = FALSE;
+ /*
+ * Start the RPC channel if it's been created. The channel may be NULL if this is
+ * not running in the context of a VM.
+ */
+ if (state->ctx.rpc && !RpcChannel_Start(state->ctx.rpc)) {
+ return 1;
}
-#endif
- if (state->debugData != NULL) {
- state->debugData->shutdown(&state->ctx, state->debugData);
- g_module_close(state->debugLib);
- state->debugData = NULL;
- state->debugLib = NULL;
+ if (!ToolsCore_LoadPlugins(state)) {
+ return 1;
}
-#if !defined(_WIN32)
- if (state->ctx.envp) {
- System_FreeNativeEnviron(state->ctx.envp);
- state->ctx.envp = NULL;
+ /*
+ * If not in a VM then there's no point in trying to run the loop, just exit
+ * with a '0' return status (see bug 297528 for why '0'). If we ever want
+ * to run vmtoolsd on physical hardware (or another hypervisor), we'll have
+ * to revisit this code.
+ */
+ if (!state->ctx.isVMware) {
+ return 0;
}
+
+ ToolsCore_RegisterPlugins(state);
+ g_timeout_add(CONF_POLL_TIME * 10, ToolsCoreConfFileCb, state);
+
+#if defined(__APPLE__)
+ ToolsCore_CFRunLoop(state);
+#else
+ g_main_loop_run(state->ctx.mainLoop);
#endif
- g_object_unref(state->ctx.serviceObj);
- state->ctx.serviceObj = NULL;
- state->ctx.config = NULL;
- state->ctx.mainLoop = NULL;
+ ToolsCoreCleanup(state);
+ return state->ctx.errorCode;
}
* Performs any initial setup steps for the service's main loop.
*
* @param[in] state Service state.
- *
- * @return Whether initialization was successful.
*/
-gboolean
+void
ToolsCore_Setup(ToolsServiceState *state)
{
GMainContext *gctx;
if (state->debugPlugin != NULL) {
ToolsCoreInitializeDebug(state);
}
-
- /* Initialize the RpcIn channel for the known tools services. */
- if (ToolsCore_GetTcloName(state) != NULL &&
- !ToolsCore_InitRpc(state)) {
- goto error;
- }
-
- /*
- * Start the RPC channel if it's been created. The channel may be NULL if this is
- * not running in the context of a VM.
- */
- if (state->ctx.rpc && !RpcChannel_Start(state->ctx.rpc)) {
- goto error;
- }
-
- if (!ToolsCore_LoadPlugins(state)) {
- goto error;
- }
-
- ToolsCore_RegisterPlugins(state);
- goto exit;
-
-error:
- if (state->ctx.rpc != NULL) {
- RpcChannel_Destroy(state->ctx.rpc);
- state->ctx.rpc = NULL;
- }
- if (state->ctx.mainLoop != NULL) {
- g_main_loop_unref(state->ctx.mainLoop);
- state->ctx.mainLoop = NULL;
- }
-
-exit:
- return (state->ctx.mainLoop != NULL);
}
int
ToolsCore_Run(ToolsServiceState *state)
{
- /*
- * If there's no RPC channel (not in a VM) then there's no point in trying to
- * run the loop, just exit with a '0' return status (see bug 297528 for why '0').
- */
- if (!state->ctx.rpc) {
- return 0;
+ if (state->debugData != NULL) {
+ int ret = state->debugData->run(&state->ctx,
+ ToolsCoreRunLoop,
+ state,
+ state->debugData);
+ g_module_close(state->debugLib);
+ state->debugData = NULL;
+ state->debugLib = NULL;
+ return ret;
}
-
- g_timeout_add(CONF_POLL_TIME * 10, ToolsCoreConfFileCb, state);
-
-#if defined(__APPLE__)
- ToolsCore_CFRunLoop(state);
-#else
- g_main_loop_run(state->ctx.mainLoop);
-#endif
- return state->ctx.errorCode;
+ return ToolsCoreRunLoop(state);
}
return 0;
}
- if (!ToolsCore_Setup(&gState)) {
- goto exit;
- }
+ ToolsCore_Setup(&gState);
src = VMTools_NewSignalSource(SIGHUP);
VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src,
ret = ToolsCore_Run(&gState);
- ToolsCore_Cleanup(&gState);
-
if (gState.pidFile != NULL) {
g_unlink(gState.pidFile);
}
int argc,
char *argv[]);
-void
-ToolsCore_Cleanup(ToolsServiceState *state);
-
void
ToolsCore_DumpPluginInfo(ToolsServiceState *state);
int
ToolsCore_Run(ToolsServiceState *state);
-gboolean
+void
ToolsCore_Setup(ToolsServiceState *state);
gboolean
plugin_LTLIBRARIES = libtestDebug.la
libtestDebug_la_CPPFLAGS =
+libtestDebug_la_CPPFLAGS += @CUNIT_CPPFLAGS@
libtestDebug_la_CPPFLAGS += @GOBJECT_CPPFLAGS@
libtestDebug_la_CPPFLAGS += @PLUGIN_CPPFLAGS@
libtestDebug_la_LDFLAGS += @PLUGIN_LDFLAGS@
libtestDebug_la_LIBADD =
+libtestDebug_la_LIBADD += @CUNIT_LIBS@
libtestDebug_la_LIBADD += @GOBJECT_LIBS@
libtestDebug_la_LIBADD += @VMTOOLS_LIBS@
libtestDebug_la_LIBADD += ../vmrpcdbg/libvmrpcdbg.la
#define G_LOG_DOMAIN "testDebug"
#include <glib-object.h>
+#include <CUnit/CUnit.h>
+
#include "util.h"
#include "guestrpc/ghiGetBinaryHandlers.h"
#include "vmware/guestrpc/tclodefs.h"
gboolean ret)
{
ToolsAppCtx *ctx = data->appCtx;
- g_assert(data->result != NULL);
- if (strcmp(data->result, "ATR debug") != 0) {
- g_error("Unexpected response to reset: %s\n", data->result);
- }
+ RPCDEBUG_ASSERT(data->result != NULL, FALSE);
+ CU_ASSERT_STRING_EQUAL(data->result, "ATR debug");
/*
* If reset was successful, connect the "test-signal" signal so we
{
GHIBinaryHandlersIconDetails *details = (GHIBinaryHandlersIconDetails *) data;
- g_assert(gSignalReceived);
- g_assert(details->width == 100);
- g_assert(details->height == 200);
- g_assert(strcmp(details->identifier, "rpc1test") == 0);
+ CU_ASSERT(gSignalReceived);
+ CU_ASSERT(details->width == 100);
+ CU_ASSERT(details->height == 200);
+ CU_ASSERT_STRING_EQUAL(details->identifier, "rpc1test");
- g_debug("Successfully validated rpc1!\n");
return TRUE;
}
TestDebugValidateUnknown(RpcInData *data,
gboolean ret)
{
- g_assert(strcmp(data->result, "Unknown Command") == 0);
+ CU_ASSERT_STRING_EQUAL(data->result, "Unknown Command");
return !ret;
}
plugin_LTLIBRARIES = libtestPlugin.la
libtestPlugin_la_CPPFLAGS =
+libtestPlugin_la_CPPFLAGS += @CUNIT_CPPFLAGS@
libtestPlugin_la_CPPFLAGS += @GOBJECT_CPPFLAGS@
libtestPlugin_la_CPPFLAGS += @PLUGIN_CPPFLAGS@
libtestPlugin_la_LDFLAGS += @PLUGIN_LDFLAGS@
libtestPlugin_la_LIBADD =
+libtestPlugin_la_LIBADD += @CUNIT_LIBS@
libtestPlugin_la_LIBADD += @GOBJECT_LIBS@
libtestPlugin_la_LIBADD += @VMTOOLS_LIBS@
libtestPlugin_la_LIBADD += @XDR_LIBS@
#include <glib-object.h>
#include <gmodule.h>
+#include <CUnit/CUnit.h>
+
#include "testData.h"
#include "util.h"
#include "guestrpc/ghiGetBinaryHandlers.h"
#include "vmware/tools/plugin.h"
+#include "vmware/tools/rpcdebug.h"
#include "vmware/tools/utils.h"
#define TEST_APP_PROVIDER "TestProvider"
char *cmd;
size_t cmdLen;
- g_assert(details->width == 100);
- g_assert(details->height == 200);
- g_assert(strcmp(details->identifier, "rpc1test") == 0);
+ CU_ASSERT_EQUAL(details->width, 100);
+ CU_ASSERT_EQUAL(details->height, 200);
+ CU_ASSERT_STRING_EQUAL(details->identifier, "rpc1test");
g_signal_emit_by_name(ctx->serviceObj, "test-signal");
ToolsAppCtx *ctx,
ToolsPluginData *plugin)
{
- g_assert(ctx != NULL);
+ RPCDEBUG_ASSERT(ctx != NULL, FALSE);
g_debug("%s: reset signal for app %s\n", __FUNCTION__, ctx->name);
return TRUE;
}
ToolsPluginData *plugin)
{
g_debug("%s: shutdown signal.\n", __FUNCTION__);
- ASSERT(gInvalidSigError);
- ASSERT(gInvalidAppError);
- ASSERT(gInvalidAppProvider);
- ASSERT(gValidAppRegistration);
+ CU_ASSERT(gInvalidSigError);
+ CU_ASSERT(gInvalidAppError);
+ CU_ASSERT(gInvalidAppProvider);
+ CU_ASSERT(gValidAppRegistration);
}
TestApp *app = reg;
g_debug("%s: registration data is '%s'\n", __FUNCTION__, app->name);
gValidAppRegistration |= strcmp(app->name, TEST_APP_NAME) == 0;
- ASSERT(strcmp(app->name, TEST_APP_DONT_REGISTER) != 0);
+ CU_ASSERT(strcmp(app->name, TEST_APP_DONT_REGISTER) != 0);
return (strcmp(app->name, TEST_APP_ERROR) != 0);
}
/* Make sure the non-existant signal we tried to register fires an error. */
if (type == TOOLS_APP_SIGNALS) {
ToolsPluginSignalCb *sig = data;
- ASSERT(strcmp(sig->signame, TEST_SIG_INVALID) == 0);
- (void) sig;
+ CU_ASSERT(strcmp(sig->signame, TEST_SIG_INVALID) == 0);
gInvalidSigError = TRUE;
}
/* Make sure we're notified about the "error" app we tried to register. */
if (type == 42) {
TestApp *app = data;
- ASSERT(strcmp(app->name, TEST_APP_ERROR) == 0);
- (void) app;
+ CU_ASSERT(strcmp(app->name, TEST_APP_ERROR) == 0);
gInvalidAppError = TRUE;
return FALSE;
}
/* Make sure we're notified about a non-existant app provider. */
if (type == 43) {
- ASSERT(data == NULL);
+ CU_ASSERT(data == NULL);
gInvalidAppProvider = TRUE;
}
noinst_LTLIBRARIES = libvmrpcdbg.la
libvmrpcdbg_la_CPPFLAGS =
+libvmrpcdbg_la_CPPFLAGS += @CUNIT_CPPFLAGS@
libvmrpcdbg_la_CPPFLAGS += @GMODULE_CPPFLAGS@
libvmrpcdbg_la_CPPFLAGS += @VMTOOLS_CPPFLAGS@
libvmrpcdbg_la_LDFLAGS += @PLUGIN_LDFLAGS@
libvmrpcdbg_la_LIBADD =
+libvmrpcdbg_la_LIBADD += @CUNIT_LIBS@
libvmrpcdbg_la_LIBADD += @GMODULE_LIBS@
libvmrpcdbg_la_LIBADD += @VMTOOLS_LIBS@
libvmrpcdbg_la_LIBADD += @XDR_LIBS@
#include "strutil.h"
#include "util.h"
+#include "vmrpcdbgInt.h"
#include "vmxrpc.h"
#include "xdrutil.h"
-#include "vmware/tools/rpcdebug.h"
#include "vmware/tools/utils.h"
typedef struct DbgChannelData {
RpcDebugRecvFn recvFn = NULL;
gboolean ret = TRUE;
- g_assert(chan->appName != NULL);
+ ASSERT(chan->appName != NULL);
/* Be paranoid. Like the VMX, NULL-terminate the incoming data. */
copy = g_malloc(dataLen + 1);
if (mapping->xdrProc != NULL) {
char *start;
- g_assert(mapping->xdrSize > 0);
+ ASSERT(mapping->xdrSize > 0);
/* Find out where the XDR data starts. */
start = strchr(copy, ' ');
RpcDebugShutdown(RpcChannel *chan)
{
DbgChannelData *cdata = chan->_private;
- g_assert(chan->appName != NULL);
+ ASSERT(chan->appName != NULL);
if (cdata->hasLibRef) {
RpcDebug_DecRef(chan->appCtx);
}
DbgChannelData *cdata;
RpcChannel *ret;
- g_assert(data != NULL);
+ ASSERT(data != NULL);
ret = g_malloc0(sizeof *ret);
ret->start = RpcDebugStart;
#define G_LOG_DOMAIN "rpcdbg"
#include <gmodule.h>
-#include <rpc/rpc.h>
+#include "CUnit/Basic.h"
+#include <CUnit/CUnit.h>
+
#include "util.h"
-#include "vmware/tools/rpcdebug.h"
+#include "vmrpcdbgInt.h"
-#if !defined(__APPLE__)
#include "embed_version.h"
#include "vmtoolsd_version.h"
VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING);
-#endif
static GModule *gPlugin = NULL;
#endif
+/*
+ * Static variables to hold the app's main loop data. CUnit test functions
+ * don't take any parameters so there's no other way to do this...
+ */
+static void (*gRunMainLoop)(gpointer);
+static gpointer gRunData;
+
+
+/*
+ ******************************************************************************
+ * RpcDebugRunLoop -- */ /**
+ *
+ * Runs the app's main loop as part of a CUnit test.
+ *
+ ******************************************************************************
+ */
+
+static void
+RpcDebugRunLoop(void)
+{
+ ASSERT(gRunMainLoop);
+ ASSERT(gRunData);
+ gRunMainLoop(gRunData);
+}
+
+
+/*
+ ******************************************************************************
+ * RpcDebugRun -- */ /**
+ *
+ * Runs the main application's main loop function through CUnit so that we
+ * get all the test tracking / reporting goodness that it provides.
+ *
+ * @param[in] runMainLoop A function that runs the application's main loop.
+ * The function should take one argument,
+ * @param[in] runData Argument to be passed to the main loop function.
+ * @param[in] ldata Debug library data.
+ *
+ * @return CUnit test run result (cast to int).
+ *
+ ******************************************************************************
+ */
+
+static int
+RpcDebugRun(ToolsAppCtx *ctx,
+ gpointer runMainLoop,
+ gpointer runData,
+ RpcDebugLibData *ldata)
+{
+ CU_ErrorCode err;
+ CU_Suite *suite;
+ CU_Test *test;
+
+ ASSERT(runMainLoop != NULL);
+ ASSERT(ldata != NULL);
+
+ err = CU_initialize_registry();
+ ASSERT(err == CUE_SUCCESS);
+
+ suite = CU_add_suite(g_module_name(gPlugin), NULL, NULL);
+ ASSERT(suite != NULL);
+
+ test = CU_add_test(suite, g_module_name(gPlugin), RpcDebugRunLoop);
+ ASSERT(test != NULL);
+
+ gRunMainLoop = runMainLoop;
+ gRunData = runData;
+
+ err = CU_basic_run_tests();
+
+ /* Clean up internal library / debug plugin state. */
+ ASSERT(g_atomic_int_get(&gRefCount) == 0);
+ ASSERT(ldata != NULL);
+
+ if (ldata->debugPlugin->shutdownFn != NULL) {
+ ldata->debugPlugin->shutdownFn(ctx, ldata->debugPlugin);
+ }
+
+ if (gPlugin != NULL) {
+ g_module_close(gPlugin);
+ gPlugin = NULL;
+ }
+
+ if (CU_get_failure_list() != NULL) {
+ err = 1;
+ }
+
+ CU_cleanup_registry();
+ return (int) err;
+}
+
+
/**
* Decreases the internal ref count of the library. When the ref count reaches
* zero, this function will ask the application's main loop to stop running.
RpcDebugOnLoadFn onload;
RpcDebugLibData *ldata;
+ ASSERT(gPlugin == NULL);
+
ldata = g_malloc(sizeof *ldata);
- g_assert(gPlugin == NULL);
gPlugin = g_module_open(dbgPlugin, G_MODULE_BIND_LOCAL);
if (gPlugin == NULL) {
g_error("Can't load plugin: %s\n", dbgPlugin);
}
ldata->newDebugChannel = RpcDebug_NewDebugChannel;
- ldata->shutdown = RpcDebug_Shutdown;
+ ldata->run = RpcDebugRun;
return ldata;
}
}
}
-
-/**
- * Shuts down the debug library. Unloads the debug plugin. The plugin's data
- * shouldn't be used after this function is called.
- *
- * @param[in] ctx The application context.
- * @param[in] ldata Debug library data.
- */
-
-void
-RpcDebug_Shutdown(ToolsAppCtx *ctx,
- RpcDebugLibData *ldata)
-{
- g_assert(g_atomic_int_get(&gRefCount) == 0);
- g_assert(ldata != NULL);
-
- if (ldata->debugPlugin != NULL && ldata->debugPlugin->shutdownFn != NULL) {
- ldata->debugPlugin->shutdownFn(ctx, ldata->debugPlugin);
- }
- if (gPlugin != NULL) {
- g_module_close(gPlugin);
- gPlugin = NULL;
- }
-}
-
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *********************************************************/
+
+#ifndef _VMRPCDBGINT_H_
+#define _VMRPCDBGINT_H_
+
+/**
+ * @file vmrpcdbgInt.h
+ *
+ * Internal definitions for the vmrpcdbg library.
+ */
+
+#include "vmware/tools/rpcdebug.h"
+
+RpcChannel *
+RpcDebug_NewDebugChannel(ToolsAppCtx *ctx,
+ RpcDebugLibData *data);
+
+#endif /* _VMRPCDBGINT_H_ */
+