gdm r5923 - in trunk: . gui/simple-greeter
- From: mccann svn gnome org
- To: svn-commits-list gnome org
- Subject: gdm r5923 - in trunk: . gui/simple-greeter
- Date: Tue, 4 Mar 2008 20:49:08 +0000 (GMT)
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]