gdm r5923 - in trunk: . gui/simple-greeter



Author: mccann
Date: Tue Mar  4 20:49:07 2008
New Revision: 5923
URL: http://svn.gnome.org/viewvc/gdm?rev=5923&view=rev

Log:
2008-03-04  William Jon McCann  <jmccann redhat com>

	* gui/simple-greeter/gdm-remote-login-window.c: (wait_on_child),
	(xserver_died), (stop_xserver), (xserver_child_watch),
	(start_xephyr):
	* gui/simple-greeter/gdm-session-client.c: (wait_on_child),
	(gdm_session_client_dispose):
	* gui/simple-greeter/test-remote-login-window.c: (main):
	Destroy the remote login window when the xserver quits.



Modified:
   trunk/ChangeLog
   trunk/gui/simple-greeter/gdm-remote-login-window.c
   trunk/gui/simple-greeter/gdm-session-client.c
   trunk/gui/simple-greeter/test-remote-login-window.c

Modified: trunk/gui/simple-greeter/gdm-remote-login-window.c
==============================================================================
--- trunk/gui/simple-greeter/gdm-remote-login-window.c	(original)
+++ trunk/gui/simple-greeter/gdm-remote-login-window.c	Tue Mar  4 20:49:07 2008
@@ -23,6 +23,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -33,6 +36,7 @@
 #include <gtk/gtk.h>
 
 #include "gdm-remote-login-window.h"
+#include "gdm-common.h"
 
 #define GDM_REMOTE_LOGIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_REMOTE_LOGIN_WINDOW, GdmRemoteLoginWindowPrivate))
 
@@ -41,6 +45,8 @@
         gboolean connected;
         char    *hostname;
         char    *display;
+        GPid     xserver_pid;
+        guint    xserver_watch_id;
 };
 
 enum {
@@ -60,31 +66,145 @@
 
 G_DEFINE_TYPE (GdmRemoteLoginWindow, gdm_remote_login_window, GTK_TYPE_WINDOW)
 
+static int
+wait_on_child (int pid)
+{
+        int status;
+
+ wait_again:
+        if (waitpid (pid, &status, 0) < 0) {
+                if (errno == EINTR) {
+                        goto wait_again;
+                } else if (errno == ECHILD) {
+                        ; /* do nothing, child already reaped */
+                } else {
+                        g_debug ("GdmRemoteLoginWindow: waitpid () should not fail");
+                }
+        }
+
+        return status;
+}
+
+static void
+xserver_died (GdmRemoteLoginWindow *login_window)
+{
+        int exit_status;
+
+        g_debug ("GdmRemoteLoginWindow: Waiting on process %d", login_window->priv->xserver_pid);
+        exit_status = wait_on_child (login_window->priv->xserver_pid);
+
+        if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) {
+                g_debug ("GdmRemoteLoginWindow: Wait on child process failed");
+        } else {
+                /* exited normally */
+        }
+
+        g_spawn_close_pid (login_window->priv->xserver_pid);
+        login_window->priv->xserver_pid = -1;
+
+        g_debug ("GdmRemoteLoginWindow: xserver died");
+}
+
+static void
+stop_xserver (GdmRemoteLoginWindow *login_window)
+{
+        /* remove watch before killing so we don't restart */
+        if (login_window->priv->xserver_watch_id > 0) {
+                g_source_remove (login_window->priv->xserver_watch_id);
+                login_window->priv->xserver_watch_id = 0;
+        }
+
+        g_debug ("GdmRemoteLoginWindow: Stopping xserver");
+        if (login_window->priv->xserver_pid > 0) {
+                gdm_signal_pid (login_window->priv->xserver_pid, SIGTERM);
+                xserver_died (login_window);
+        }
+}
+
+static void
+xserver_child_watch (GPid                  pid,
+                     int                   status,
+                     GdmRemoteLoginWindow *login_window)
+{
+        g_debug ("GdmRemoteLoginWindow: **** xserver (pid:%d) done (%s:%d)",
+                 (int) pid,
+                 WIFEXITED (status) ? "status"
+                 : WIFSIGNALED (status) ? "signal"
+                 : "unknown",
+                 WIFEXITED (status) ? WEXITSTATUS (status)
+                 : WIFSIGNALED (status) ? WTERMSIG (status)
+                 : -1);
+
+        g_spawn_close_pid (login_window->priv->xserver_pid);
+
+        login_window->priv->xserver_pid = -1;
+        login_window->priv->xserver_watch_id = 0;
+
+        gtk_widget_destroy (GTK_WIDGET (login_window));
+}
+
 static gboolean
 start_xephyr (GdmRemoteLoginWindow *login_window)
 {
-        char    *cmd;
-        gboolean res;
-        GError  *error;
-
-        cmd = g_strdup_printf ("Xephyr -query %s -parent 0x%x -br -once %s",
-                               login_window->priv->hostname,
-                               (unsigned int)GDK_WINDOW_XID (GTK_WIDGET (login_window)->window),
-                               login_window->priv->display);
-        g_debug ("Running: %s", cmd);
+        GError     *local_error;
+        char      **argv;
+        gboolean    res;
+        gboolean    ret;
+        int         flags;
+        char       *command;
+
+        command = g_strdup_printf ("Xephyr -query %s -parent 0x%x -br -once %s",
+                                   login_window->priv->hostname,
+                                   (unsigned int)GDK_WINDOW_XID (GTK_WIDGET (login_window)->window),
+                                   login_window->priv->display);
+        g_debug ("GdmRemoteLoginWindow: Running: %s", command);
+
+        ret = FALSE;
+
+        argv = NULL;
+        local_error = NULL;
+        res = g_shell_parse_argv (command, NULL, &argv, &local_error);
+        if (! res) {
+                g_warning ("GdmRemoteLoginWindow: Unable to parse command: %s", local_error->message);
+                g_error_free (local_error);
+                goto out;
+        }
 
-        error = NULL;
-        res = g_spawn_command_line_async (cmd, &error);
+        flags = G_SPAWN_SEARCH_PATH
+                | G_SPAWN_DO_NOT_REAP_CHILD;
 
-        g_free (cmd);
+        local_error = NULL;
+        res = g_spawn_async (NULL,
+                             argv,
+                             NULL,
+                             flags,
+                             NULL,
+                             NULL,
+                             &login_window->priv->xserver_pid,
+                             &local_error);
+        g_strfreev (argv);
 
         if (! res) {
-                g_warning ("Could not start nested X server: %s", error->message);
-                g_error_free (error);
-                return FALSE;
+                g_warning ("GdmRemoteLoginWindow: Unable to run command %s: %s",
+                           command,
+                           local_error->message);
+                g_error_free (local_error);
+                goto out;
         }
 
-        return TRUE;
+        g_debug ("GdmRemoteLoginWindow: Started: pid=%d command='%s'",
+                 login_window->priv->xserver_pid,
+                 command);
+
+        login_window->priv->xserver_watch_id = g_child_watch_add (login_window->priv->xserver_pid,
+                                                                  (GChildWatchFunc)xserver_child_watch,
+                                                                  login_window);
+        ret = TRUE;
+
+ out:
+        g_free (command);
+
+        return ret;
 }
 
 static gboolean

Modified: trunk/gui/simple-greeter/gdm-session-client.c
==============================================================================
--- trunk/gui/simple-greeter/gdm-session-client.c	(original)
+++ trunk/gui/simple-greeter/gdm-session-client.c	Tue Mar  4 20:49:07 2008
@@ -174,7 +174,7 @@
                 } else if (errno == ECHILD) {
                         ; /* do nothing, child already reaped */
                 } else {
-                        g_debug ("GdmWelcomeSession: waitpid () should not fail");
+                        g_debug ("GdmSessionClient: waitpid () should not fail");
                 }
         }
 
@@ -418,6 +418,8 @@
 static void
 gdm_session_client_dispose (GObject *object)
 {
+        gdm_session_client_stop (GDM_SESSION_CLIENT (object));
+
         G_OBJECT_CLASS (gdm_session_client_parent_class)->dispose (object);
 }
 

Modified: trunk/gui/simple-greeter/test-remote-login-window.c
==============================================================================
--- trunk/gui/simple-greeter/test-remote-login-window.c	(original)
+++ trunk/gui/simple-greeter/test-remote-login-window.c	Tue Mar  4 20:49:07 2008
@@ -79,6 +79,7 @@
         gtk_init (&argc, &argv);
 
         login_window = gdm_remote_login_window_new (TRUE);
+        g_signal_connect (login_window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
         gtk_widget_show (login_window);
 
         gdm_remote_login_window_connect (GDM_REMOTE_LOGIN_WINDOW (login_window), hostname);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]