summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2013-02-08 14:48:15 +0100
committerChristophe Fergeau <cfergeau@redhat.com>2013-03-14 11:10:08 +0100
commit271833906304670e557d45b929c458c1e890b036 (patch)
treeb8b72deb8ae7e26db0300b012de18eee8b97c61a
parent473c1d5b2aeb350ef51d8e0b87bd56a76ea122e9 (diff)
Move StartClient() to the controller class
This is platform specific, and is related to starting the receiver of controller messages, so let's move it with the rest of the platform-specific code.
-rw-r--r--SpiceXPI/src/plugin/controller-unix.cpp106
-rw-r--r--SpiceXPI/src/plugin/controller.h13
-rw-r--r--SpiceXPI/src/plugin/plugin.cpp110
-rw-r--r--SpiceXPI/src/plugin/plugin.h7
4 files changed, 130 insertions, 106 deletions
diff --git a/SpiceXPI/src/plugin/controller-unix.cpp b/SpiceXPI/src/plugin/controller-unix.cpp
index 0d8f0f8..489136e 100644
--- a/SpiceXPI/src/plugin/controller-unix.cpp
+++ b/SpiceXPI/src/plugin/controller-unix.cpp
@@ -53,20 +53,29 @@ extern "C" {
# include <fcntl.h>
# include <sys/socket.h>
# include <sys/un.h>
+# include <sys/wait.h>
}
#include "rederrorcodes.h"
#include "controller.h"
+#include "plugin.h"
-SpiceController::SpiceController():
+SpiceController::SpiceController(nsPluginInstance *aPlugin):
+ m_plugin(aPlugin),
m_client_socket(-1)
{
+ // create temporary directory in /tmp
+ char tmp_dir[] = "/tmp/spicec-XXXXXX";
+ m_tmp_dir = mkdtemp(tmp_dir);
}
SpiceController::~SpiceController()
{
g_debug(G_STRFUNC);
Disconnect();
+
+ // delete the temporary directory used for a client socket
+ rmdir(m_tmp_dir.c_str());
}
void SpiceController::SetFilename(const std::string &name)
@@ -74,6 +83,11 @@ void SpiceController::SetFilename(const std::string &name)
m_name = name;
}
+void SpiceController::SetProxy(const std::string &proxy)
+{
+ m_proxy = proxy;
+}
+
int SpiceController::Connect()
{
// check, if we have a filename for socket to create
@@ -148,6 +162,96 @@ uint32_t SpiceController::Write(const void *lpBuffer, uint32_t nBytesToWrite)
return len;
}
+bool SpiceController::StartClient()
+{
+ std::string socket_file(m_tmp_dir);
+ socket_file += "/spice-xpi";
+
+ /* use a pipe for the children to wait until it gets tracked */
+ int pipe_fds[2] = { -1, -1 };
+ if (pipe(pipe_fds) < 0) {
+ perror("spice-xpi system error");
+ return false;
+ }
+
+ m_pid_controller = fork();
+ if (m_pid_controller == 0)
+ {
+ setpgrp();
+
+ close(pipe_fds[1]);
+ pipe_fds[1] = -1;
+
+ char c;
+ if (read(pipe_fds[0], &c, 1) != 0)
+ g_critical("Error while reading on pipe: %s", g_strerror(errno));
+
+ close(pipe_fds[0]);
+ pipe_fds[0] = -1;
+
+ gchar **env = g_get_environ();
+ env = g_environ_setenv(env, "SPICE_XPI_SOCKET", socket_file.c_str(), TRUE);
+ if (!m_proxy.empty())
+ env = g_environ_setenv(env, "SPICE_PROXY", m_proxy.c_str(), TRUE);
+
+ execle("/usr/libexec/spice-xpi-client",
+ "/usr/libexec/spice-xpi-client", NULL,
+ env);
+ g_message("failed to run spice-xpi-client, running spicec instead");
+
+ // TODO: temporary fallback for backward compatibility
+ execle("/usr/bin/spicec",
+ "/usr/bin/spicec", "--controller", NULL,
+ env);
+
+ g_critical("ERROR failed to run spicec fallback");
+ g_strfreev(env);
+ exit(EXIT_FAILURE);
+ }
+ else
+ {
+ g_debug("child pid: %"G_GUINT64_FORMAT, (guint64)m_pid_controller);
+
+ close(pipe_fds[0]);
+ pipe_fds[0] = -1;
+
+ pthread_t controller_thread_id;
+ pthread_create(&controller_thread_id, NULL, ControllerWaitHelper,
+ reinterpret_cast<void*>(this));
+
+ close(pipe_fds[1]);
+ pipe_fds[1] = -1;
+
+ this->SetFilename(socket_file);
+
+ return true;
+ }
+
+ g_return_val_if_reached(false);
+}
+
+void SpiceController::StopClient()
+{
+ if (m_pid_controller > 0)
+ kill(-m_pid_controller, SIGTERM);
+}
+
+void *SpiceController::ControllerWaitHelper(void *opaque)
+{
+ SpiceController *fake_this = reinterpret_cast<SpiceController *>(opaque);
+ if (!fake_this)
+ return NULL;
+
+ int exit_code;
+ waitpid(fake_this->m_pid_controller, &exit_code, 0);
+ g_debug("child finished, pid: %"G_GUINT64_FORMAT, (guint64)exit_code);
+
+ fake_this->m_plugin->OnSpiceClientExit(exit_code);
+ fake_this->m_pid_controller = -1;
+
+ return NULL;
+}
+
int SpiceController::TranslateRC(int nRC)
{
switch (nRC)
diff --git a/SpiceXPI/src/plugin/controller.h b/SpiceXPI/src/plugin/controller.h
index 001d2b3..d7d3875 100644
--- a/SpiceXPI/src/plugin/controller.h
+++ b/SpiceXPI/src/plugin/controller.h
@@ -65,13 +65,18 @@ extern "C" {
#include <spice/controller_prot.h>
+class nsPluginInstance;
+
class SpiceController
{
public:
- SpiceController();
+ SpiceController(nsPluginInstance *aPlugin);
~SpiceController();
+ bool StartClient();
+ void StopClient();
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);
@@ -80,8 +85,14 @@ public:
private:
int Connect();
+ static void *ControllerWaitHelper(void *opaque);
+
+ 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;
};
#endif // SPICE_CONTROLLER_H
diff --git a/SpiceXPI/src/plugin/plugin.cpp b/SpiceXPI/src/plugin/plugin.cpp
index ba5747e..6531523 100644
--- a/SpiceXPI/src/plugin/plugin.cpp
+++ b/SpiceXPI/src/plugin/plugin.cpp
@@ -47,10 +47,6 @@
#include "config.h"
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
@@ -175,8 +171,8 @@ void NS_DestroyPluginInstance(nsPluginInstanceBase *aPlugin)
nsPluginInstance::nsPluginInstance(NPP aInstance):
nsPluginInstanceBase(),
- m_pid_controller(-1),
m_connected_status(-2),
+ m_external_controller(this),
m_instance(aInstance),
m_initialized(true),
m_window(NULL),
@@ -188,10 +184,6 @@ nsPluginInstance::nsPluginInstance(NPP aInstance):
m_usb_auto_share(true),
m_scriptable_peer(NULL)
{
- // create temporary directory in /tmp
- char tmp_dir[] = "/tmp/spicec-XXXXXX";
- m_tmp_dir = mkdtemp(tmp_dir);
-
#if !GLIB_CHECK_VERSION(2, 35, 0)
g_type_init();
#endif
@@ -205,9 +197,6 @@ nsPluginInstance::~nsPluginInstance()
// and zero its m_plugin member
if (m_scriptable_peer)
NPN_ReleaseObject(m_scriptable_peer);
-
- // delete the temporary directory used for a client socket
- rmdir(m_tmp_dir.c_str());
}
NPBool nsPluginInstance::init(NPWindow *aWindow)
@@ -233,6 +222,7 @@ NPBool nsPluginInstance::init(NPWindow *aWindow)
m_color_depth.clear();
m_disable_effects.clear();
m_proxy.clear();
+ m_external_controller.SetProxy(std::string());
m_fullscreen = false;
m_smartcard = false;
@@ -537,6 +527,7 @@ char *nsPluginInstance::GetProxy() const
void nsPluginInstance::SetProxy(const char *aProxy)
{
m_proxy = aProxy;
+ m_external_controller.SetProxy(m_proxy);
}
void nsPluginInstance::WriteToPipe(const void *data, uint32_t size)
@@ -586,74 +577,6 @@ void nsPluginInstance::SendStr(uint32_t id, std::string str)
free(msg);
}
-bool nsPluginInstance::StartClient()
-{
- std::string socket_file(m_tmp_dir);
- socket_file += "/spice-xpi";
-
- /* use a pipe for the children to wait until it gets tracked */
- int pipe_fds[2] = { -1, -1 };
- if (pipe(pipe_fds) < 0) {
- perror("spice-xpi system error");
- return false;
- }
-
- m_pid_controller = fork();
- if (m_pid_controller == 0)
- {
- setpgrp();
-
- close(pipe_fds[1]);
- pipe_fds[1] = -1;
-
- char c;
- if (read(pipe_fds[0], &c, 1) != 0)
- g_critical("Error while reading on pipe: %s", g_strerror(errno));
-
- close(pipe_fds[0]);
- pipe_fds[0] = -1;
-
- gchar **env = g_get_environ();
- env = g_environ_setenv(env, "SPICE_XPI_SOCKET", socket_file.c_str(), TRUE);
- if (!m_proxy.empty())
- env = g_environ_setenv(env, "SPICE_PROXY", m_proxy.c_str(), TRUE);
-
- execle("/usr/libexec/spice-xpi-client",
- "/usr/libexec/spice-xpi-client", NULL,
- env);
- g_message("failed to run spice-xpi-client, running spicec instead");
-
- // TODO: temporary fallback for backward compatibility
- execle("/usr/bin/spicec",
- "/usr/bin/spicec", "--controller", NULL,
- env);
-
- g_critical("ERROR failed to run spicec fallback");
- g_strfreev(env);
- exit(EXIT_FAILURE);
- }
- else
- {
- g_debug("child pid: %"G_GUINT64_FORMAT, (guint64)m_pid_controller);
-
- close(pipe_fds[0]);
- pipe_fds[0] = -1;
-
- pthread_t controller_thread_id;
- pthread_create(&controller_thread_id, NULL, ControllerWaitHelper,
- reinterpret_cast<void*>(this));
-
- close(pipe_fds[1]);
- pipe_fds[1] = -1;
-
- m_external_controller.SetFilename(socket_file);
-
- return true;
- }
-
- g_return_val_if_reached(false);
-}
-
bool nsPluginInstance::CreateTrustStoreFile(const std::string &trust_store)
{
GFile *tmp_file;
@@ -706,7 +629,7 @@ void nsPluginInstance::Connect()
return;
}
- if (!this->StartClient()) {
+ if (!m_external_controller.StartClient()) {
g_critical("failed to start SPICE client");
return;
}
@@ -759,8 +682,7 @@ void nsPluginInstance::Show()
void nsPluginInstance::Disconnect()
{
- if (m_pid_controller > 0)
- kill(-m_pid_controller, SIGTERM);
+ m_external_controller.StopClient();
}
void nsPluginInstance::ConnectedStatus(int32_t *retval)
@@ -832,26 +754,16 @@ void nsPluginInstance::CallOnDisconnected(int code)
NPN_ReleaseVariantValue(&var_on_disconnected);
}
-void *nsPluginInstance::ControllerWaitHelper(void *opaque)
+void nsPluginInstance::OnSpiceClientExit(int exit_code)
{
- nsPluginInstance *fake_this = reinterpret_cast<nsPluginInstance *>(opaque);
- if (!fake_this)
- return NULL;
-
- int exit_code;
- waitpid(fake_this->m_pid_controller, &exit_code, 0);
- g_debug("child finished, pid: %"G_GUINT64_FORMAT, (guint64)exit_code);
-
- fake_this->m_connected_status = fake_this->m_external_controller.TranslateRC(exit_code);
+ m_connected_status = m_external_controller.TranslateRC(exit_code);
if (!getenv("SPICE_XPI_DEBUG"))
{
- fake_this->CallOnDisconnected(exit_code);
- fake_this->m_external_controller.Disconnect();
+ CallOnDisconnected(exit_code);
+ m_external_controller.Disconnect();
}
-
- fake_this->RemoveTrustStoreFile();
- fake_this->m_pid_controller = -1;
- return NULL;
+
+ RemoveTrustStoreFile();
}
// ==============================
diff --git a/SpiceXPI/src/plugin/plugin.h b/SpiceXPI/src/plugin/plugin.h
index ea50ca5..5e7f079 100644
--- a/SpiceXPI/src/plugin/plugin.h
+++ b/SpiceXPI/src/plugin/plugin.h
@@ -174,8 +174,9 @@ public:
NPObject *GetScriptablePeer();
+ void OnSpiceClientExit(int exit_code);
+
private:
- static void *ControllerWaitHelper(void *opaque);
void WriteToPipe(const void *data, uint32_t size);
void SendInit();
void SendMsg(uint32_t id);
@@ -185,12 +186,9 @@ private:
void CallOnDisconnected(int code);
private:
- bool StartClient();
- bool CreateTrustStore();
bool CreateTrustStoreFile(const std::string &trust_store);
bool RemoveTrustStoreFile();
- pid_t m_pid_controller;
int32_t m_connected_status;
SpiceController m_external_controller;
@@ -224,7 +222,6 @@ private:
std::string m_proxy;
NPObject *m_scriptable_peer;
- std::string m_tmp_dir;
std::string m_trust_store_file;
};