]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Make XServerXVNC extend XServerLocal
authorRobert Ancell <robert.ancell@canonical.com>
Fri, 17 Jun 2016 02:20:42 +0000 (14:20 +1200)
committerRobert Ancell <robert.ancell@canonical.com>
Fri, 17 Jun 2016 02:20:42 +0000 (14:20 +1200)
src/seat-xvnc.c
src/x-server-local.c
src/x-server-local.h
src/x-server-xvnc.c
src/x-server-xvnc.h

index 89a7d201af0e729168cdb920f1b0823c27635e24..6026859e8582a5f3372c4cc59b7b63b73b5f908e 100644 (file)
@@ -37,17 +37,24 @@ static DisplayServer *
 seat_xvnc_create_display_server (Seat *seat, Session *session)
 {
     XServerXVNC *x_server;
+    gchar *number;
+    XAuthority *cookie;
     const gchar *command = NULL;
 
     if (strcmp (session_get_session_type (session), "x") != 0)
         return NULL;
 
     x_server = x_server_xvnc_new ();
+    number = g_strdup_printf ("%d", x_server_get_display_number (X_SERVER (x_server)));
+    cookie = x_authority_new_local_cookie (number);
+    x_server_set_authority (X_SERVER (x_server), cookie);
+    g_free (number);
+    g_object_unref (cookie);
     x_server_xvnc_set_socket (x_server, g_socket_get_fd (SEAT_XVNC (seat)->priv->connection));
 
     command = config_get_string (config_get_instance (), "VNCServer", "command");
     if (command)
-        x_server_xvnc_set_command (x_server, command);
+        x_server_local_set_command (X_SERVER_LOCAL (x_server), command);
 
     if (config_has_key (config_get_instance (), "VNCServer", "width") &&
         config_has_key (config_get_instance (), "VNCServer", "height"))
@@ -81,7 +88,7 @@ seat_xvnc_run_script (Seat *seat, DisplayServer *display_server, Process *script
 
     address = G_INET_SOCKET_ADDRESS (g_socket_get_remote_address (SEAT_XVNC (seat)->priv->connection, NULL));
     hostname = g_inet_address_to_string (g_inet_socket_address_get_address (address));
-    path = x_server_xvnc_get_authority_file_path (x_server);
+    path = x_server_local_get_authority_file_path (X_SERVER_LOCAL (x_server));
 
     process_set_env (script, "REMOTE_HOST", hostname);
     process_set_env (script, "DISPLAY", x_server_get_address (X_SERVER (x_server)));
index 20d067b5ad2927fe297f55c3e4d46f2ba8fd230e..78006700b53e2d751668376e3b9b98c126e47ba9 100644 (file)
@@ -382,7 +382,7 @@ get_absolute_command (const gchar *command)
 }
 
 static void
-run_cb (Process *process, gpointer user_data)
+x_server_local_run (Process *process, gpointer user_data)
 {
     int fd;
 
@@ -395,6 +395,18 @@ run_cb (Process *process, gpointer user_data)
     signal (SIGUSR1, SIG_IGN);
 }
 
+static ProcessRunFunc
+x_server_local_get_run_function (XServerLocal *server)
+{
+    return x_server_local_run;
+}
+
+static gboolean
+x_server_local_get_log_stdout (XServerLocal *server)
+{
+    return TRUE;
+}
+
 static void
 got_signal_cb (Process *process, int signum, XServerLocal *server)
 {
@@ -471,6 +483,7 @@ static gboolean
 x_server_local_start (DisplayServer *display_server)
 {
     XServerLocal *server = X_SERVER_LOCAL (display_server);
+    ProcessRunFunc run_cb;
     gboolean result, backup_logs;
     gchar *filename, *dir, *log_file, *absolute_command;
     GString *command;
@@ -481,6 +494,7 @@ x_server_local_start (DisplayServer *display_server)
 
     g_return_val_if_fail (server->priv->command != NULL, FALSE);
 
+    run_cb = X_SERVER_LOCAL_GET_CLASS (server)->get_run_function (server);
     server->priv->x_server_process = process_new (run_cb, server);
     process_set_clear_environment (server->priv->x_server_process, TRUE);
     g_signal_connect (server->priv->x_server_process, PROCESS_SIGNAL_GOT_SIGNAL, G_CALLBACK (got_signal_cb), server);
@@ -491,7 +505,7 @@ x_server_local_start (DisplayServer *display_server)
     dir = config_get_string (config_get_instance (), "LightDM", "log-directory");
     log_file = g_build_filename (dir, filename, NULL);
     backup_logs = config_get_boolean (config_get_instance (), "LightDM", "backup-logs");
-    process_set_log_file (server->priv->x_server_process, log_file, TRUE, backup_logs ? LOG_MODE_BACKUP_AND_TRUNCATE : LOG_MODE_APPEND);
+    process_set_log_file (server->priv->x_server_process, log_file, X_SERVER_LOCAL_GET_CLASS (server)->get_log_stdout (server), backup_logs ? LOG_MODE_BACKUP_AND_TRUNCATE : LOG_MODE_APPEND);
     l_debug (display_server, "Logging to %s", log_file);
     g_free (log_file);
     g_free (filename);
@@ -552,6 +566,10 @@ x_server_local_start (DisplayServer *display_server)
     if (server->priv->background)
         g_string_append_printf (command, " -background %s", server->priv->background);
 
+    /* Allow sub-classes to add arguments */
+    if (X_SERVER_LOCAL_GET_CLASS (server)->add_args)
+        X_SERVER_LOCAL_GET_CLASS (server)->add_args (server, command);
+
     process_set_command (server->priv->x_server_process, command->str);
     g_string_free (command, TRUE);
 
@@ -639,6 +657,8 @@ x_server_local_class_init (XServerLocalClass *klass)
     XServerClass *x_server_class = X_SERVER_CLASS (klass);
     DisplayServerClass *display_server_class = DISPLAY_SERVER_CLASS (klass);
 
+    klass->get_run_function = x_server_local_get_run_function;
+    klass->get_log_stdout = x_server_local_get_log_stdout;
     x_server_class->get_display_number = x_server_local_get_display_number;
     display_server_class->get_vt = x_server_local_get_vt;
     display_server_class->start = x_server_local_start;
index e20a86cd2e116edcf2c7039a5c9e119df694540a..7c37f01d77854197dda718b9cc794c7513c77b97 100644 (file)
 #define X_SERVER_LOCAL_H_
 
 #include "x-server.h"
+#include "process.h"
 
 G_BEGIN_DECLS
 
 #define X_SERVER_LOCAL_TYPE    (x_server_local_get_type())
 #define X_SERVER_LOCAL(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), X_SERVER_LOCAL_TYPE, XServerLocal))
+#define X_SERVER_LOCAL_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST ((klass), X_SERVER_LOCAL_TYPE, XServerLocalClass))
+#define X_SERVER_LOCAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), X_SERVER_LOCAL_TYPE, XServerLocalClass))
 #define IS_X_SERVER_LOCAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), X_SERVER_LOCAL_TYPE))
 
 typedef struct XServerLocalPrivate XServerLocalPrivate;
@@ -31,6 +34,9 @@ typedef struct
 typedef struct
 {
     XServerClass parent_class;
+    ProcessRunFunc (*get_run_function)(XServerLocal *server);
+    gboolean (*get_log_stdout)(XServerLocal *server);  
+    void (*add_args)(XServerLocal *server, GString *command);
 } XServerLocalClass;
 
 const gchar *x_server_local_get_version (void);
index eb5f6f45a5d8dd05b4937b6e4e60bdef33ffa60f..1abbff3cace349360d7caca887a769c387e05454 100644 (file)
 
 #include "x-server-xvnc.h"
 #include "configuration.h"
-#include "x-server-local.h"
 #include "process.h"
 
 struct XServerXVNCPrivate
 {
-    /* X server process */
-    Process *x_server_process;
-
-    /* Command to run the X server */
-    gchar *command;
-
-    /* Display number to use */
-    guint display_number;
-
-    /* Authority file */
-    gchar *authority_file;
-
     /* File descriptor to use for standard input */
     gint socket_fd;
 
     /* Geometry and colour depth */
     gint width, height, depth;
-
-    /* TRUE when received ready signal */
-    gboolean got_signal;
 };
 
-G_DEFINE_TYPE (XServerXVNC, x_server_xvnc, X_SERVER_TYPE);
+G_DEFINE_TYPE (XServerXVNC, x_server_xvnc, X_SERVER_LOCAL_TYPE);
 
 XServerXVNC *
 x_server_xvnc_new (void)
@@ -56,18 +40,11 @@ x_server_xvnc_new (void)
     name = g_strdup_printf ("xvnc-%d", x_server_get_display_number (X_SERVER (self)));
     display_server_set_name (DISPLAY_SERVER (self), name);
     g_free (name);
+  
+    x_server_local_set_command (X_SERVER_LOCAL (self), "Xvnc");
 
     return self;
 }
-
-void
-x_server_xvnc_set_command (XServerXVNC *server, const gchar *command)
-{
-    g_return_if_fail (server != NULL);
-    g_free (server->priv->command);
-    server->priv->command = g_strdup (command);
-}
-
 void
 x_server_xvnc_set_socket (XServerXVNC *server, int fd)
 {
@@ -97,43 +74,8 @@ x_server_xvnc_set_depth (XServerXVNC *server, gint depth)
     server->priv->depth = depth;
 }
 
-const gchar *
-x_server_xvnc_get_authority_file_path (XServerXVNC *server)
-{
-    g_return_val_if_fail (server != NULL, 0);
-    return server->priv->authority_file;
-}
-
-static guint
-x_server_xvnc_get_display_number (XServer *server)
-{
-    return X_SERVER_XVNC (server)->priv->display_number;
-}
-
-static gchar *
-get_absolute_command (const gchar *command)
-{
-    gchar **tokens;
-    gchar *absolute_binary, *absolute_command = NULL;
-
-    tokens = g_strsplit (command, " ", 2);
-
-    absolute_binary = g_find_program_in_path (tokens[0]);
-    if (absolute_binary)
-    {
-        if (tokens[1])
-            absolute_command = g_strjoin (" ", absolute_binary, tokens[1], NULL);
-        else
-            absolute_command = g_strdup (absolute_binary);
-    }
-
-    g_strfreev (tokens);
-
-    return absolute_command;
-}
-
 static void
-run_cb (Process *process, gpointer user_data)
+x_server_xvnc_run (Process *process, gpointer user_data)
 {
     XServerXVNC *server = user_data;
 
@@ -146,35 +88,16 @@ run_cb (Process *process, gpointer user_data)
     signal (SIGUSR1, SIG_IGN);
 }
 
-static void
-got_signal_cb (Process *process, int signum, XServerXVNC *server)
+static ProcessRunFunc
+x_server_xvnc_get_run_function (XServerLocal *server)
 {
-    if (signum == SIGUSR1 && !server->priv->got_signal)
-    {
-        server->priv->got_signal = TRUE;
-        l_debug (server, "Got signal from Xvnc server :%d", x_server_get_display_number (X_SERVER (server)));
-
-        // FIXME: Check return value
-        DISPLAY_SERVER_CLASS (x_server_xvnc_parent_class)->start (DISPLAY_SERVER (server));
-    }
+    return x_server_xvnc_run;
 }
 
-static void
-stopped_cb (Process *process, XServerXVNC *server)
+static gboolean
+x_server_xvnc_get_log_stdout (XServerLocal *server)
 {
-    l_debug (server, "Xvnc server stopped");
-
-    g_clear_object (&server->priv->x_server_process);
-
-    x_server_local_release_display_number (x_server_get_display_number (X_SERVER (server)));
-
-    l_debug (server, "Removing X server authority %s", server->priv->authority_file);
-
-    g_unlink (server->priv->authority_file);
-    g_free (server->priv->authority_file);
-    server->priv->authority_file = NULL;
-
-    DISPLAY_SERVER_CLASS (x_server_xvnc_parent_class)->stop (DISPLAY_SERVER (server));
+    return FALSE;
 }
 
 static gboolean
@@ -183,141 +106,39 @@ x_server_xvnc_get_can_share (DisplayServer *server)
     return TRUE;
 }
 
-static gboolean
-x_server_xvnc_start (DisplayServer *display_server)
+static void
+x_server_xvnc_add_args (XServerLocal *x_server, GString *command)
 {
-    XServerXVNC *server = X_SERVER_XVNC (display_server);
-    XAuthority *authority;
-    gboolean result, backup_logs;
-    gchar *filename, *run_dir, *dir, *log_file, *absolute_command;
-    GString *command;
-    gchar *number;
-    GError *error = NULL;
-
-    g_return_val_if_fail (server->priv->x_server_process == NULL, FALSE);
-
-    server->priv->got_signal = FALSE;
-
-    server->priv->x_server_process = process_new (run_cb, server);
-    process_set_clear_environment (server->priv->x_server_process, TRUE);
-    g_signal_connect (server->priv->x_server_process, PROCESS_SIGNAL_GOT_SIGNAL, G_CALLBACK (got_signal_cb), server);
-    g_signal_connect (server->priv->x_server_process, PROCESS_SIGNAL_STOPPED, G_CALLBACK (stopped_cb), server);
-
-    /* Setup logging */
-    filename = g_strdup_printf ("%s.log", display_server_get_name (display_server));
-    dir = config_get_string (config_get_instance (), "LightDM", "log-directory");
-    log_file = g_build_filename (dir, filename, NULL);
-    backup_logs = config_get_boolean (config_get_instance (), "LightDM", "backup-logs");  
-    process_set_log_file (server->priv->x_server_process, log_file, FALSE, backup_logs ? LOG_MODE_BACKUP_AND_TRUNCATE : LOG_MODE_APPEND);
-    l_debug (display_server, "Logging to %s", log_file);
-    g_free (log_file);
-    g_free (filename);
-    g_free (dir);
-
-    absolute_command = get_absolute_command (server->priv->command);
-    if (!absolute_command)
-    {
-        l_debug (display_server, "Can't launch X server %s, not found in path", server->priv->command);
-        stopped_cb (server->priv->x_server_process, X_SERVER_XVNC (server));
-        return FALSE;
-    }
+    XServerXVNC *server = X_SERVER_XVNC (x_server);
 
-    number = g_strdup_printf ("%d", x_server_get_display_number (X_SERVER (server)));
-    authority = x_authority_new_local_cookie (number);
+    g_string_append (command, " -inetd");
 
-    x_server_set_authority (X_SERVER (server), authority);
-
-    run_dir = config_get_string (config_get_instance (), "LightDM", "run-directory");
-    dir = g_build_filename (run_dir, "root", NULL);
-    g_free (run_dir);
-    if (g_mkdir_with_parents (dir, S_IRWXU) < 0)
-        l_warning (display_server, "Failed to make authority directory %s: %s", dir, strerror (errno));
-
-    server->priv->authority_file = g_build_filename (dir, x_server_get_address (X_SERVER (server)), NULL);
-    g_free (dir);
-
-    l_debug (display_server, "Writing X server authority to %s", server->priv->authority_file);
-
-    x_authority_write (authority, XAUTH_WRITE_MODE_REPLACE, server->priv->authority_file, &error);
-    if (error)
-        l_warning (display_server, "Failed to write authority: %s", error->message);
-    g_clear_error (&error);
-
-    command = g_string_new (absolute_command);
-    g_free (absolute_command);
-
-    g_string_append_printf (command, " :%d", x_server_get_display_number (X_SERVER (server)));
-    g_string_append_printf (command, " -auth %s", server->priv->authority_file);
-    g_string_append (command, " -inetd -nolisten tcp");
     if (server->priv->width > 0 && server->priv->height > 0)
         g_string_append_printf (command, " -geometry %dx%d", server->priv->width, server->priv->height);
+
     if (server->priv->depth > 0)
         g_string_append_printf (command, " -depth %d", server->priv->depth);
-
-    process_set_command (server->priv->x_server_process, command->str);
-    g_string_free (command, TRUE);
-
-    l_debug (display_server, "Launching Xvnc server");
-
-    /* Variable required for regression tests */
-    if (g_getenv ("LIGHTDM_TEST_ROOT"))
-    {
-        process_set_env (server->priv->x_server_process, "LIGHTDM_TEST_ROOT", g_getenv ("LIGHTDM_TEST_ROOT"));
-        process_set_env (server->priv->x_server_process, "LD_LIBRARY_PATH", g_getenv ("LD_LIBRARY_PATH"));
-    }
-
-    result = process_start (server->priv->x_server_process, FALSE);
-
-    if (result)
-        l_debug (display_server, "Waiting for ready signal from Xvnc server :%d", x_server_get_display_number (X_SERVER (server)));
-
-    if (!result)
-        stopped_cb (server->priv->x_server_process, X_SERVER_XVNC (server));
-
-    return result;
-}
-
-static void
-x_server_xvnc_stop (DisplayServer *server)
-{
-    process_stop (X_SERVER_XVNC (server)->priv->x_server_process);
 }
 
 static void
 x_server_xvnc_init (XServerXVNC *server)
 {
     server->priv = G_TYPE_INSTANCE_GET_PRIVATE (server, X_SERVER_XVNC_TYPE, XServerXVNCPrivate);
-    server->priv->command = g_strdup ("Xvnc");
-    server->priv->display_number = x_server_local_get_unused_display_number ();
     server->priv->width = 1024;
     server->priv->height = 768;
     server->priv->depth = 8;
 }
 
-static void
-x_server_xvnc_finalize (GObject *object)
-{
-    XServerXVNC *self = X_SERVER_XVNC (object);
-
-    g_clear_object (&self->priv->x_server_process);
-    g_free (self->priv->command);
-    g_free (self->priv->authority_file);
-
-    G_OBJECT_CLASS (x_server_xvnc_parent_class)->finalize (object);
-}
-
 static void
 x_server_xvnc_class_init (XServerXVNCClass *klass)
 {
-    GObjectClass *object_class = G_OBJECT_CLASS (klass);
-    XServerClass *x_server_class = X_SERVER_CLASS (klass);
+    XServerLocalClass *x_server_local_class = X_SERVER_LOCAL_CLASS (klass);
     DisplayServerClass *display_server_class = DISPLAY_SERVER_CLASS (klass);
 
-    x_server_class->get_display_number = x_server_xvnc_get_display_number;
+    x_server_local_class->get_run_function = x_server_xvnc_get_run_function;
+    x_server_local_class->get_log_stdout = x_server_xvnc_get_log_stdout;
+    x_server_local_class->add_args = x_server_xvnc_add_args;
     display_server_class->get_can_share = x_server_xvnc_get_can_share;
-    display_server_class->start = x_server_xvnc_start;
-    display_server_class->stop = x_server_xvnc_stop;
-    object_class->finalize = x_server_xvnc_finalize;
 
     g_type_class_add_private (klass, sizeof (XServerXVNCPrivate));
 }
index 4a7bc54ce591958ec1f976562302827936f8149b..e56ea7cb326fb880d3933db9adae4ed8a40f7d21 100644 (file)
@@ -12,7 +12,7 @@
 #ifndef X_SERVER_XVNC_H_
 #define X_SERVER_XVNC_H_
 
-#include "x-server.h"
+#include "x-server-local.h"
 
 G_BEGIN_DECLS
 
@@ -24,13 +24,13 @@ typedef struct XServerXVNCPrivate XServerXVNCPrivate;
 
 typedef struct
 {
-    XServer              parent_instance;
+    XServerLocal        parent_instance;
     XServerXVNCPrivate *priv;
 } XServerXVNC;
 
 typedef struct
 {
-    XServerClass parent_class;
+    XServerLocalClass parent_class;
 
     void (*ready)(XServerXVNC *server);
 } XServerXVNCClass;
@@ -41,8 +41,6 @@ gboolean x_server_xvnc_check_available (void);
 
 XServerXVNC *x_server_xvnc_new (void);
 
-void x_server_xvnc_set_command (XServerXVNC *server, const gchar *command);
-
 void x_server_xvnc_set_socket (XServerXVNC *server, int fd);
 
 int x_server_xvnc_get_socket (XServerXVNC *server);
@@ -51,8 +49,6 @@ void x_server_xvnc_set_geometry (XServerXVNC *server, gint width, gint height);
 
 void x_server_xvnc_set_depth (XServerXVNC *server, gint depth);
 
-const gchar *x_server_xvnc_get_authority_file_path (XServerXVNC *server);
-
 G_END_DECLS
 
 #endif /* X_SERVER_XVNC_H_ */