[Spice-devel] [spice-xpi 12/12] Add an abstract controller base class
Marc-André Lureau
marcandre.lureau at gmail.com
Tue Mar 12 05:37:06 PDT 2013
after this patch:
"LoadPlugin: failed to initialize"..., 212LoadPlugin: failed to
initialize shared library
/home/elmarco/.mozilla/plugins/libnsISpicec.so
[/home/elmarco/.mozilla/plugins/libnsISpicec.so: undefined symbol:
_ZN19SpiceControllerUnix14GetClientPathsEPPPcS2_
On Tue, Mar 12, 2013 at 12:23 PM, Christophe Fergeau
<cfergeau at redhat.com> wrote:
> It contains all the generic code, then platform-specific controller
> implementations will inherit from it and overload the non-generic parts
> abstract methods.
> ---
> SpiceXPI/src/plugin/Makefile.am | 2 +
> SpiceXPI/src/plugin/controller-unix.cpp | 209 +++-----------------------
> SpiceXPI/src/plugin/controller-unix.h | 96 ++++++++++++
> SpiceXPI/src/plugin/controller.cpp | 252 ++++++++++++++++++++++++++++++++
> SpiceXPI/src/plugin/controller.h | 27 ++--
> SpiceXPI/src/plugin/plugin.cpp | 22 +--
> SpiceXPI/src/plugin/plugin.h | 2 +-
> 7 files changed, 398 insertions(+), 212 deletions(-)
> create mode 100644 SpiceXPI/src/plugin/controller-unix.h
> create mode 100644 SpiceXPI/src/plugin/controller.cpp
>
> diff --git a/SpiceXPI/src/plugin/Makefile.am b/SpiceXPI/src/plugin/Makefile.am
> index 2f12e70..2db218e 100644
> --- a/SpiceXPI/src/plugin/Makefile.am
> +++ b/SpiceXPI/src/plugin/Makefile.am
> @@ -26,8 +26,10 @@ libnsISpicec_la_SOURCES = \
> $(top_srcdir)/common/rederrorcodes.h \
> glib-compat.c \
> glib-compat.h \
> + controller.cpp \
> controller.h \
> controller-unix.cpp \
> + controller-unix.h \
> npapi/npapi.h \
> npapi/npfunctions.h \
> npapi/npruntime.h \
> diff --git a/SpiceXPI/src/plugin/controller-unix.cpp b/SpiceXPI/src/plugin/controller-unix.cpp
> index ddbd8c0..b3bd832 100644
> --- a/SpiceXPI/src/plugin/controller-unix.cpp
> +++ b/SpiceXPI/src/plugin/controller-unix.cpp
> @@ -41,6 +41,7 @@
> * the terms of any one of the MPL, the GPL or the LGPL.
> *
> * ***** END LICENSE BLOCK ***** */
> +#include "config.h"
>
> #include <cstdio>
> #include <cstdlib>
> @@ -58,11 +59,11 @@ extern "C" {
> }
>
> #include "rederrorcodes.h"
> -#include "controller.h"
> +#include "controller-unix.h"
> #include "plugin.h"
>
> -SpiceController::SpiceController(nsPluginInstance *aPlugin):
> - m_plugin(aPlugin),
> +SpiceControllerUnix::SpiceControllerUnix(nsPluginInstance *aPlugin):
> + SpiceController(aPlugin),
> m_client_socket(-1)
> {
> // create temporary directory in /tmp
> @@ -70,7 +71,7 @@ SpiceController::SpiceController(nsPluginInstance *aPlugin):
> m_tmp_dir = mkdtemp(tmp_dir);
> }
>
> -SpiceController::~SpiceController()
> +SpiceControllerUnix::~SpiceControllerUnix()
> {
> g_debug(G_STRFUNC);
> Disconnect();
> @@ -79,17 +80,7 @@ SpiceController::~SpiceController()
> rmdir(m_tmp_dir.c_str());
> }
>
> -void SpiceController::SetFilename(const std::string &name)
> -{
> - m_name = name;
> -}
> -
> -void SpiceController::SetProxy(const std::string &proxy)
> -{
> - m_proxy = proxy;
> -}
> -
> -int SpiceController::Connect()
> +int SpiceControllerUnix::Connect()
> {
> // check, if we have a filename for socket to create
> if (m_name.empty())
> @@ -123,23 +114,11 @@ int SpiceController::Connect()
> return rc;
> }
>
> -int SpiceController::Connect(const int nRetries)
> +bool SpiceControllerUnix::CheckPipe()
> {
> - int rc = -1;
> - int sleep_time = 0;
> -
> - // try to connect for specified count
> - for (int i = 0; rc != 0 && i < nRetries; ++i)
> - {
> - rc = Connect();
> - g_usleep(sleep_time * G_USEC_PER_SEC);
> - ++sleep_time;
> - }
> -
> - return rc;
> }
>
> -void SpiceController::GetClientPaths(GStrv *client_argv, GStrv *fallback_argv)
> +void SpiceControllerUnixGetClientPaths(GStrv *client_argv, GStrv *fallback_argv)
> {
> if (client_argv != NULL) {
> *client_argv = g_new0(char *, 2);
> @@ -153,7 +132,7 @@ void SpiceController::GetClientPaths(GStrv *client_argv, GStrv *fallback_argv)
> }
> }
>
> -void SpiceController::SetupControllerPipe(GStrv &env)
> +void SpiceControllerUnix::SetupControllerPipe(GStrv &env)
> {
> std::string socket_file(this->m_tmp_dir);
> socket_file += "/spice-xpi";
> @@ -163,18 +142,13 @@ void SpiceController::SetupControllerPipe(GStrv &env)
> env = g_environ_setenv(env, "SPICE_XPI_SOCKET", socket_file.c_str(), TRUE);
> }
>
> -void SpiceController::Disconnect()
> +void SpiceControllerUnix::StopClient()
> {
> - // close the socket
> - close(m_client_socket);
> - m_client_socket = -1;
> -
> - // delete the temporary file, which is used for the socket
> - unlink(m_name.c_str());
> - m_name.clear();
> + if (m_pid_controller > 0)
> + kill(-m_pid_controller, SIGTERM);
> }
>
> -uint32_t SpiceController::Write(const void *lpBuffer, uint32_t nBytesToWrite)
> +uint32_t SpiceControllerUnix::Write(const void *lpBuffer, uint32_t nBytesToWrite)
> {
> ssize_t len = send(m_client_socket, lpBuffer, nBytesToWrite, 0);
>
> @@ -187,156 +161,13 @@ uint32_t SpiceController::Write(const void *lpBuffer, uint32_t nBytesToWrite)
> return len;
> }
>
> -void SpiceController::ChildExited(GPid pid, gint status, gpointer user_data)
> +void SpiceControllerUnix::Disconnect()
> {
> - SpiceController *fake_this = (SpiceController *)user_data;
> -
> - g_message("Client with pid %p exited", pid);
> -
> - g_main_loop_quit(fake_this->m_child_watch_mainloop);
> - /* FIXME: we are not in the main thread!! */
> - fake_this->m_plugin->OnSpiceClientExit(status);
> -}
> -
> -void SpiceController::WaitForPid(GPid pid)
> -{
> - GMainContext *context;
> - GSource *source;
> -
> - context = g_main_context_new();
> -
> - m_child_watch_mainloop = g_main_loop_new(context, FALSE);
> - source = g_child_watch_source_new(pid);
> - g_source_set_callback(source, (GSourceFunc)ChildExited, this, NULL);
> - g_source_attach(source, context);
> -
> - g_main_loop_run(m_child_watch_mainloop);
> -
> - g_main_loop_unref(m_child_watch_mainloop);
> - g_main_context_unref(context);
> -
> - g_spawn_close_pid(pid);
> - if (pid == m_pid_controller)
> - m_pid_controller = 0;
> -}
> -
> -
> -gpointer SpiceController::ClientThread(gpointer data)
> -{
> - SpiceController *fake_this = (SpiceController *)data;
> - gchar **env = g_get_environ();
> - GPid pid;
> - gboolean spawned = FALSE;
> - GError *error = NULL;
> - GStrv client_argv;
> - GStrv fallback_argv;
> - fake_this->GetClientPaths(&client_argv, &fallback_argv);
> -
> - {
> - char *argv_str = g_strjoinv(" ", client_argv);
> - g_warning("main client cmdline: %s", argv_str);
> - g_free(argv_str);
> - argv_str = g_strjoinv(" ", fallback_argv);
> - g_warning("fallback client cmdline: %s", argv_str);
> - g_free(argv_str);
> - }
> -
> - fake_this->SetupControllerPipe(env);
> -
> - if (!fake_this->m_proxy.empty())
> - env = g_environ_setenv(env, "SPICE_PROXY", fake_this->m_proxy.c_str(), TRUE);
> -
> - if (client_argv != NULL) {
> - spawned = g_spawn_async(NULL,
> - client_argv, env,
> - G_SPAWN_DO_NOT_REAP_CHILD,
> - NULL, NULL, /* child_func, child_arg */
> - &pid, &error);
> - if (error != NULL) {
> - g_warning("failed to start %s: %s", client_argv[0], error->message);
> - g_warn_if_fail(spawned == FALSE);
> - g_clear_error(&error);
> - }
> - }
> - if (!spawned && (fallback_argv != NULL)) {
> - // TODO: temporary fallback for backward compatibility
> - g_message("failed to run preferred client, running fallback client instead");
> - spawned = g_spawn_async(NULL, fallback_argv, env,
> - G_SPAWN_DO_NOT_REAP_CHILD,
> - NULL, NULL, /* child_func, child_arg */
> - &pid, &error);
> - if (error != NULL) {
> - g_warning("failed to start %s: %s", fallback_argv[0], error->message);
> - g_warn_if_fail(spawned == FALSE);
> - g_clear_error(&error);
> - }
> - }
> - g_strfreev(env);
> - g_strfreev(client_argv);
> - g_strfreev(fallback_argv);
> -
> - if (!spawned) {
> - g_critical("ERROR failed to run spicec fallback");
> - return NULL;
> - }
> -
> -#ifdef XP_UNIX
> - fake_this->m_pid_controller = pid;
> -#endif
> - fake_this->WaitForPid(pid);
> -
> - return NULL;
> -}
> -
> -bool SpiceController::StartClient()
> -{
> - GThread *thread;
> -
> - thread = g_thread_create(ClientThread, this, FALSE, NULL);
> -
> - return (thread != NULL);
> -}
> -
> -void SpiceController::StopClient()
> -{
> - if (m_pid_controller > 0)
> - kill(-m_pid_controller, SIGTERM);
> -}
> -
> -int SpiceController::TranslateRC(int nRC)
> -{
> - switch (nRC)
> - {
> - case SPICEC_ERROR_CODE_SUCCESS:
> - return 0;
> -
> - case SPICEC_ERROR_CODE_GETHOSTBYNAME_FAILED:
> - return RDP_ERROR_CODE_HOST_NOT_FOUND;
> -
> - case SPICEC_ERROR_CODE_CONNECT_FAILED:
> - return RDP_ERROR_CODE_WINSOCK_CONNECT_FAILED;
> -
> - case SPICEC_ERROR_CODE_ERROR:
> - case SPICEC_ERROR_CODE_SOCKET_FAILED:
> - return RDP_ERROR_CODE_INTERNAL_ERROR;
> -
> - case SPICEC_ERROR_CODE_RECV_FAILED:
> - return RDP_ERROR_RECV_WINSOCK_FAILED;
> -
> - case SPICEC_ERROR_CODE_SEND_FAILED:
> - return RDP_ERROR_SEND_WINSOCK_FAILED;
> -
> - case SPICEC_ERROR_CODE_NOT_ENOUGH_MEMORY:
> - return RDP_ERROR_CODE_OUT_OF_MEMORY;
> -
> - case SPICEC_ERROR_CODE_AGENT_TIMEOUT:
> - return RDP_ERROR_CODE_TIMEOUT;
> -
> - case SPICEC_ERROR_CODE_AGENT_ERROR:
> - return RDP_ERROR_CODE_INTERNAL_ERROR;
> + // close the socket
> + close(m_client_socket);
> + m_client_socket = -1;
>
> - default:
> - return RDP_ERROR_CODE_INTERNAL_ERROR;
> - }
> + // delete the temporary file, which is used for the socket
> + unlink(m_name.c_str());
> + m_name.clear();
> }
> -
> diff --git a/SpiceXPI/src/plugin/controller-unix.h b/SpiceXPI/src/plugin/controller-unix.h
> new file mode 100644
> index 0000000..e72663b
> --- /dev/null
> +++ b/SpiceXPI/src/plugin/controller-unix.h
> @@ -0,0 +1,96 @@
> +/* ***** 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.
> + *
> + * Copyright 2009-2011, Red Hat Inc.
> + * Copyright 2013, Red Hat Inc.
> + * Based on mozilla.org's scriptable plugin example
> + *
> + * The Original Code is mozilla.org code.
> + *
> + * The Initial Developer of the Original Code is
> + * Netscape Communications Corporation.
> + * Portions created by the Initial Developer are Copyright (C) 1998
> + * the Initial Developer. All Rights Reserved.
> + *
> + * Contributor(s):
> + * Uri Lublin
> + * Martin Stransky
> + * Peter Hatina
> + * Christophe Fergeau
> + *
> + * 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 SPICE_CONTROLLER_UNIX_H
> +#define SPICE_CONTROLLER_UNIX_H
> +
> +/*
> + Basic assumption:
> + ------------------
> + Cross platform compatible.
> + Easy to transform into remote process communication
> + Secured
> +
> + chosen:
> + Unix - Unix Domain Sockets (easy to change into regular sockets for remote communication)
> + Windows - Named pipe (which allows remote access and is duplex
> + (rather than anonymous pipe which is local only and one way)
> +*/
> +
> +#include <glib.h>
> +#include <glib-object.h> /* for GStrv */
> +#include <gio/gio.h>
> +#include <string>
> +extern "C" {
> +# include <stdint.h>
> +# include <limits.h>
> +}
> +
> +#include <spice/controller_prot.h>
> +#include "controller.h"
> +
> +class nsPluginInstance;
> +
> +class SpiceControllerUnix: public SpiceController
> +{
> +public:
> + SpiceControllerUnix(nsPluginInstance *aPlugin);
> + virtual ~SpiceControllerUnix();
> +
> + virtual void StopClient();
> + virtual uint32_t Write(const void *lpBuffer, uint32_t nBytesToWrite);
> + int Connect(int nRetries) { return SpiceController::Connect(nRetries); };
> +
> +private:
> + virtual int Connect();
> + virtual void Disconnect();
> + virtual void SetupControllerPipe(GStrv &env);
> + virtual bool CheckPipe();
> + virtual void GetClientPaths(GStrv *client_argv, GStrv *fallback_argv);
> +
> + int m_client_socket;
> + std::string m_tmp_dir;
> +};
> +
> +#endif // SPICE_CONTROLLER_UNIX_H
> diff --git a/SpiceXPI/src/plugin/controller.cpp b/SpiceXPI/src/plugin/controller.cpp
> new file mode 100644
> index 0000000..6011f5d
> --- /dev/null
> +++ b/SpiceXPI/src/plugin/controller.cpp
> @@ -0,0 +1,252 @@
> +/* ***** 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.
> + *
> + * Copyright 2009-2011, Red Hat Inc.
> + * Copyright 2013, Red Hat Inc.
> + * Based on mozilla.org's scriptable plugin example
> + *
> + * The Original Code is mozilla.org code.
> + *
> + * The Initial Developer of the Original Code is
> + * Netscape Communications Corporation.
> + * Portions created by the Initial Developer are Copyright (C) 1998
> + * the Initial Developer. All Rights Reserved.
> + *
> + * Contributor(s):
> + * Uri Lublin
> + * Martin Stransky
> + * Peter Hatina
> + * Christophe Fergeau
> + *
> + * 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 "config.h"
> +
> +#include <cstdio>
> +#include <cstdlib>
> +#include <cstring>
> +#include <cerrno>
> +#include <glib.h>
> +
> +#include "rederrorcodes.h"
> +#include "controller.h"
> +#include "plugin.h"
> +
> +SpiceController::SpiceController(nsPluginInstance *aPlugin):
> + m_pid_controller(0),
> + m_pipe(NULL),
> + m_plugin(aPlugin),
> + m_child_watch_mainloop(NULL)
> +{
> +}
> +
> +SpiceController::~SpiceController()
> +{
> + g_debug(G_STRFUNC);
> + Disconnect();
> +}
> +
> +void SpiceController::SetFilename(const std::string &name)
> +{
> + m_name = name;
> +}
> +
> +void SpiceController::SetProxy(const std::string &proxy)
> +{
> + m_proxy = proxy;
> +}
> +
> +#define FACILITY_SPICEX 50
> +#define FACILITY_CREATE_RED_PROCESS 51
> +#define FACILITY_STRING_OPERATION 52
> +#define FACILITY_CREATE_RED_EVENT 53
> +#define FACILITY_CREATE_RED_PIPE 54
> +#define FACILITY_PIPE_OPERATION 55
> +
> +int SpiceController::Connect(const int nRetries)
> +{
> + int rc = -1;
> + int sleep_time = 0;
> +
> + // try to connect for specified count
> + for (int i = 0; rc != 0 && i < nRetries; ++i)
> + {
> + rc = Connect();
> + g_usleep(sleep_time * G_USEC_PER_SEC);
> + ++sleep_time;
> + }
> +
> + return rc;
> +}
> +
> +void SpiceController::Disconnect()
> +{
> +}
> +
> +void SpiceController::ChildExited(GPid pid, gint status, gpointer user_data)
> +{
> + SpiceController *fake_this = (SpiceController *)user_data;
> +
> + g_message("Client with pid %p exited", pid);
> +
> + g_main_loop_quit(fake_this->m_child_watch_mainloop);
> + /* FIXME: we are not in the main thread!! */
> + fake_this->m_plugin->OnSpiceClientExit(status);
> +}
> +
> +void SpiceController::WaitForPid(GPid pid)
> +{
> + GMainContext *context;
> + GSource *source;
> +
> + context = g_main_context_new();
> +
> + m_child_watch_mainloop = g_main_loop_new(context, FALSE);
> + source = g_child_watch_source_new(pid);
> + g_source_set_callback(source, (GSourceFunc)ChildExited, this, NULL);
> + g_source_attach(source, context);
> +
> + g_main_loop_run(m_child_watch_mainloop);
> +
> + g_main_loop_unref(m_child_watch_mainloop);
> + g_main_context_unref(context);
> +
> + g_spawn_close_pid(pid);
> + if (pid == m_pid_controller)
> + m_pid_controller = 0;
> +}
> +
> +gpointer SpiceController::ClientThread(gpointer data)
> +{
> + SpiceController *fake_this = (SpiceController *)data;
> + gchar **env = g_get_environ();
> + GPid pid;
> + gboolean spawned = FALSE;
> + GError *error = NULL;
> + GStrv client_argv;
> + GStrv fallback_argv;
> + fake_this->GetClientPaths(&client_argv, &fallback_argv);
> +
> + {
> + char *argv_str = g_strjoinv(" ", client_argv);
> + g_warning("main client cmdline: %s", argv_str);
> + g_free(argv_str);
> + argv_str = g_strjoinv(" ", fallback_argv);
> + g_warning("fallback client cmdline: %s", argv_str);
> + g_free(argv_str);
> + }
> +
> + fake_this->SetupControllerPipe(env);
> +
> + if (!fake_this->m_proxy.empty())
> + env = g_environ_setenv(env, "SPICE_PROXY", fake_this->m_proxy.c_str(), TRUE);
> +
> + if (client_argv != NULL) {
> + spawned = g_spawn_async(NULL,
> + client_argv, env,
> + G_SPAWN_DO_NOT_REAP_CHILD,
> + NULL, NULL, /* child_func, child_arg */
> + &pid, &error);
> + if (error != NULL) {
> + g_warning("failed to start %s: %s", client_argv[0], error->message);
> + g_warn_if_fail(spawned == FALSE);
> + g_clear_error(&error);
> + }
> + }
> + if (!spawned && (fallback_argv != NULL)) {
> + // TODO: temporary fallback for backward compatibility
> + g_message("failed to run preferred client, running fallback client instead");
> + spawned = g_spawn_async(NULL, fallback_argv, env,
> + G_SPAWN_DO_NOT_REAP_CHILD,
> + NULL, NULL, /* child_func, child_arg */
> + &pid, &error);
> + if (error != NULL) {
> + g_warning("failed to start %s: %s", fallback_argv[0], error->message);
> + g_warn_if_fail(spawned == FALSE);
> + g_clear_error(&error);
> + }
> + }
> + g_strfreev(env);
> + g_strfreev(client_argv);
> + g_strfreev(fallback_argv);
> +
> + if (!spawned) {
> + g_critical("ERROR failed to run spicec fallback");
> + return NULL;
> + }
> +
> +#ifdef XP_UNIX
> + fake_this->m_pid_controller = pid;
> +#endif
> + fake_this->WaitForPid(pid);
> +
> + return NULL;
> +}
> +
> +bool SpiceController::StartClient()
> +{
> + GThread *thread;
> +
> + thread = g_thread_create(ClientThread, this, FALSE, NULL);
> +
> + return (thread != NULL);
> +}
> +
> +int SpiceController::TranslateRC(int nRC)
> +{
> + switch (nRC)
> + {
> + case SPICEC_ERROR_CODE_SUCCESS:
> + return 0;
> +
> + case SPICEC_ERROR_CODE_GETHOSTBYNAME_FAILED:
> + return RDP_ERROR_CODE_HOST_NOT_FOUND;
> +
> + case SPICEC_ERROR_CODE_CONNECT_FAILED:
> + return RDP_ERROR_CODE_WINSOCK_CONNECT_FAILED;
> +
> + case SPICEC_ERROR_CODE_ERROR:
> + case SPICEC_ERROR_CODE_SOCKET_FAILED:
> + return RDP_ERROR_CODE_INTERNAL_ERROR;
> +
> + case SPICEC_ERROR_CODE_RECV_FAILED:
> + return RDP_ERROR_RECV_WINSOCK_FAILED;
> +
> + case SPICEC_ERROR_CODE_SEND_FAILED:
> + return RDP_ERROR_SEND_WINSOCK_FAILED;
> +
> + case SPICEC_ERROR_CODE_NOT_ENOUGH_MEMORY:
> + return RDP_ERROR_CODE_OUT_OF_MEMORY;
> +
> + case SPICEC_ERROR_CODE_AGENT_TIMEOUT:
> + return RDP_ERROR_CODE_TIMEOUT;
> +
> + case SPICEC_ERROR_CODE_AGENT_ERROR:
> + return RDP_ERROR_CODE_INTERNAL_ERROR;
> +
> + default:
> + return RDP_ERROR_CODE_INTERNAL_ERROR;
> + }
> +}
> diff --git a/SpiceXPI/src/plugin/controller.h b/SpiceXPI/src/plugin/controller.h
> index de4516c..4473dd4 100644
> --- a/SpiceXPI/src/plugin/controller.h
> +++ b/SpiceXPI/src/plugin/controller.h
> @@ -60,6 +60,7 @@
>
> #include <glib.h>
> #include <glib-object.h> /* for GStrv */
> +#include <gio/gio.h>
> #include <string>
> extern "C" {
> # include <stdint.h>
> @@ -74,32 +75,34 @@ class SpiceController
> {
> public:
> SpiceController(nsPluginInstance *aPlugin);
> - ~SpiceController();
> + virtual ~SpiceController();
>
> bool StartClient();
> - void StopClient();
> + virtual void StopClient() = 0;
> void SetFilename(const std::string &name);
> void SetProxy(const std::string &proxy);
> int Connect(int nRetries);
> - void Disconnect();
> - uint32_t Write(const void *lpBuffer, uint32_t nBytesToWrite);
> + virtual void Disconnect();
> + virtual uint32_t Write(const void *lpBuffer, uint32_t nBytesToWrite) = 0;
>
> static int TranslateRC(int nRC);
>
> +protected:
> + std::string m_name;
> + std::string m_proxy;
> + GPid m_pid_controller;
> + GOutputStream *m_pipe;
> +
> private:
> - int Connect();
> + virtual int Connect() = 0;
> void WaitForPid(GPid pid);
> - void SetupControllerPipe(GStrv &env);
> - void GetClientPaths(GStrv *client_argv, GStrv *fallback_argv);
> + virtual void SetupControllerPipe(GStrv &env) = 0;
> + virtual bool CheckPipe() = 0;
> + virtual void GetClientPaths(GStrv *client_argv, GStrv *fallback_argv) = 0;
> static void ChildExited(GPid pid, gint status, gpointer user_data);
> static gpointer ClientThread(gpointer data);
>
> nsPluginInstance *m_plugin;
> - int m_client_socket;
> - std::string m_name;
> - std::string m_tmp_dir;
> - pid_t m_pid_controller;
> - std::string m_proxy;
>
> GMainLoop *m_child_watch_mainloop;
> };
> diff --git a/SpiceXPI/src/plugin/plugin.cpp b/SpiceXPI/src/plugin/plugin.cpp
> index e8c916e..5ecc793 100644
> --- a/SpiceXPI/src/plugin/plugin.cpp
> +++ b/SpiceXPI/src/plugin/plugin.cpp
> @@ -67,7 +67,7 @@ extern "C" {
> #include <fstream>
> #include <set>
>
> -#include "controller.h"
> +#include "controller-unix.h"
> #include "plugin.h"
> #include "nsScriptablePeer.h"
>
> @@ -173,7 +173,6 @@ void NS_DestroyPluginInstance(nsPluginInstanceBase *aPlugin)
> nsPluginInstance::nsPluginInstance(NPP aInstance):
> nsPluginInstanceBase(),
> m_connected_status(-2),
> - m_external_controller(this),
> m_instance(aInstance),
> m_initialized(true),
> m_window(NULL),
> @@ -186,6 +185,8 @@ nsPluginInstance::nsPluginInstance(NPP aInstance):
> m_scriptable_peer(NULL)
> {
> g_type_init();
> +
> + m_external_controller = new SpiceControllerUnix(this);
> }
>
> nsPluginInstance::~nsPluginInstance()
> @@ -196,6 +197,7 @@ nsPluginInstance::~nsPluginInstance()
> // and zero its m_plugin member
> if (m_scriptable_peer)
> NPN_ReleaseObject(m_scriptable_peer);
> + delete(m_external_controller);
> }
>
> NPBool nsPluginInstance::init(NPWindow *aWindow)
> @@ -221,7 +223,7 @@ NPBool nsPluginInstance::init(NPWindow *aWindow)
> m_color_depth.clear();
> m_disable_effects.clear();
> m_proxy.clear();
> - m_external_controller.SetProxy(std::string());
> + m_external_controller->SetProxy(std::string());
>
> m_fullscreen = false;
> m_smartcard = false;
> @@ -526,12 +528,12 @@ char *nsPluginInstance::GetProxy() const
> void nsPluginInstance::SetProxy(const char *aProxy)
> {
> m_proxy = aProxy;
> - m_external_controller.SetProxy(m_proxy);
> + m_external_controller->SetProxy(m_proxy);
> }
>
> void nsPluginInstance::WriteToPipe(const void *data, uint32_t size)
> {
> - m_external_controller.Write(data, size);
> + m_external_controller->Write(data, size);
> }
>
> void nsPluginInstance::SendInit()
> @@ -628,12 +630,12 @@ void nsPluginInstance::Connect()
> return;
> }
>
> - if (!m_external_controller.StartClient()) {
> + if (!m_external_controller->StartClient()) {
> g_critical("failed to start SPICE client");
> return;
> }
>
> - if (m_external_controller.Connect(10) != 0)
> + if (m_external_controller->Connect(10) != 0)
> {
> g_critical("could not connect to spice client controller");
> return;
> @@ -681,7 +683,7 @@ void nsPluginInstance::Show()
>
> void nsPluginInstance::Disconnect()
> {
> - m_external_controller.StopClient();
> + m_external_controller->StopClient();
> }
>
> void nsPluginInstance::ConnectedStatus(int32_t *retval)
> @@ -755,11 +757,11 @@ void nsPluginInstance::CallOnDisconnected(int code)
>
> void nsPluginInstance::OnSpiceClientExit(int exit_code)
> {
> - m_connected_status = m_external_controller.TranslateRC(exit_code);
> + m_connected_status = m_external_controller->TranslateRC(exit_code);
> if (!getenv("SPICE_XPI_DEBUG"))
> {
> CallOnDisconnected(exit_code);
> - m_external_controller.Disconnect();
> + m_external_controller->Disconnect();
> }
>
> RemoveTrustStoreFile();
> diff --git a/SpiceXPI/src/plugin/plugin.h b/SpiceXPI/src/plugin/plugin.h
> index 5e7f079..7884dc7 100644
> --- a/SpiceXPI/src/plugin/plugin.h
> +++ b/SpiceXPI/src/plugin/plugin.h
> @@ -190,7 +190,7 @@ private:
> bool RemoveTrustStoreFile();
>
> int32_t m_connected_status;
> - SpiceController m_external_controller;
> + SpiceController *m_external_controller;
>
> NPP m_instance;
> NPBool m_initialized;
> --
> 1.8.1.4
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
--
Marc-André Lureau
More information about the Spice-devel
mailing list