summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--TODO1
-rw-r--r--daemon/display.c14
-rw-r--r--daemon/misc.c7
-rw-r--r--daemon/server.c198
-rw-r--r--daemon/server.h10
-rw-r--r--daemon/slave.c399
-rw-r--r--docs/C/.cvsignore5
-rw-r--r--gui/gdmlogin.c56
9 files changed, 375 insertions, 322 deletions
diff --git a/ChangeLog b/ChangeLog
index c8d11bc6..5592d5fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Jan 22 02:59:22 2001 George Lebl <jirka@5z.com>
+
+ * daemon/misc.c, daemon/server.[ch], daemon/slave.c,
+ daemon/display.c: Race fixes, remove old code, cleanups,
+ leak fixes, use the same X server process and use HUP to
+ reset it
+
Wed Jan 10 19:25:54 2001 George Lebl <jirka@5z.com>
* configure.in, *: raise version and put in some notes in relevant
diff --git a/TODO b/TODO
index 9e5655de..824907bb 100644
--- a/TODO
+++ b/TODO
@@ -9,3 +9,4 @@ Keyboard layout menu.
utmp/wtmp handling.
+easter egg
diff --git a/daemon/display.c b/daemon/display.c
index f03c7bf7..a8598ef5 100644
--- a/daemon/display.c
+++ b/daemon/display.c
@@ -77,11 +77,15 @@ gdm_display_manage (GdmDisplay *d)
if (GdmXdmcp)
gdm_xdmcp_close ();
- if (d->type == TYPE_LOCAL)
+ if (d->type == TYPE_LOCAL) {
gdm_slave_start (d);
-
- if (d->type == TYPE_XDMCP && d->dispstat == XDMCP_MANAGED)
+ /* if we ever return, bad things are happening */
+ _exit (DISPLAY_ABORT);
+ } else if (d->type == TYPE_XDMCP && d->dispstat == XDMCP_MANAGED) {
gdm_slave_start (d);
+ /* we expect to return after the session finishes */
+ _exit (DISPLAY_REMANAGE);
+ }
break;
@@ -114,9 +118,9 @@ gdm_display_unmanage (GdmDisplay *d)
gdm_debug ("gdm_display_unmanage: Stopping %s", d->name);
- /* Kill slave and all its children */
+ /* Kill slave */
if (d->slavepid) {
- kill (-(d->slavepid), SIGTERM);
+ kill (d->slavepid, SIGTERM);
waitpid (d->slavepid, 0, 0);
d->slavepid = 0;
}
diff --git a/daemon/misc.c b/daemon/misc.c
index 7707df7b..4304d581 100644
--- a/daemon/misc.c
+++ b/daemon/misc.c
@@ -130,7 +130,7 @@ gdm_debug (const gchar *format, ...)
va_list args;
gchar *s;
- if (/*0 &&*/ ! GdmDebug)
+ if (/*0 && */! GdmDebug)
return;
va_start (args, format);
@@ -138,9 +138,8 @@ gdm_debug (const gchar *format, ...)
va_end (args);
/* UGLY DEBUGGING HACK! */
- /*
- { FILE *fp = fopen ("/tmp/foo.gdm", "a"); fprintf (fp, "%s\n", s); fflush (fp); fclose (fp); };
- */
+
+ /*{ FILE *fp = fopen ("/tmp/foo.gdm", "a"); fprintf (fp, "%s\n", s); fflush (fp); fclose (fp); };*/
syslog (LOG_ERR, s); /* FIXME: LOG_DEBUG */
diff --git a/daemon/server.c b/daemon/server.c
index 4903cb2b..125d428e 100644
--- a/daemon/server.c
+++ b/daemon/server.c
@@ -133,6 +133,38 @@ gdm_server_check_loop (GdmDisplay *disp)
}
/**
+ * gdm_server_reinit:
+ * @disp: Pointer to a GdmDisplay structure
+ *
+ * Reinit the display, basically sends a HUP signal
+ * but only if the display exists
+ */
+
+void
+gdm_server_reinit (GdmDisplay *disp)
+{
+ gboolean had_connection = FALSE;
+
+ if (disp == NULL ||
+ disp->servpid <= 0)
+ return;
+
+ /* Kill our connection */
+ if (disp->dsp != NULL) {
+ XCloseDisplay (disp->dsp);
+ disp->dsp = NULL;
+ had_connection = TRUE;
+ }
+
+ gdm_debug ("gdm_server_reinit: Server for %s is about to be reinitialized!", disp->name);
+
+ kill (disp->servpid, SIGHUP);
+
+ if (had_connection)
+ d->dsp = XOpenDisplay (d->name);
+}
+
+/**
* gdm_server_stop:
* @disp: Pointer to a GdmDisplay structure
*
@@ -140,13 +172,29 @@ gdm_server_check_loop (GdmDisplay *disp)
*/
void
-gdm_server_kill (GdmDisplay *disp)
+gdm_server_stop (GdmDisplay *disp)
{
if (disp == NULL ||
disp->servpid <= 0)
return;
- gdm_server_stop (disp);
+ gdm_debug ("gdm_server_stop: Server for %s going down!", disp->name);
+
+ /* Kill our connection */
+ if (disp->dsp != NULL) {
+ XCloseDisplay (disp->dsp);
+ disp->dsp = NULL;
+ }
+
+ disp->servstat = SERVER_DEAD;
+
+ if (disp->servpid != 0) {
+ if (kill (disp->servpid, SIGTERM) == 0)
+ waitpid (disp->servpid, 0, 0);
+ disp->servpid = 0;
+ }
+
+ unlink (disp->authfile);
}
/**
@@ -171,7 +219,7 @@ gdm_server_start (GdmDisplay *disp)
d->servtries = 0;
/* if an X server exists, wipe it */
- gdm_server_kill (d);
+ gdm_server_stop (d);
gdm_debug ("gdm_server_start: %s", d->name);
@@ -224,6 +272,13 @@ gdm_server_start (GdmDisplay *disp)
sigaddset (&mask, SIGALRM);
sigprocmask (SIG_UNBLOCK, &mask, &oldmask);
+ /* We add a timeout in case the X server fails to start. This
+ * might happen because X servers take a while to die, close their
+ * sockets etc. If the old X server isn't completely dead, the new
+ * one will fail and we'll hang here forever */
+
+ alarm (10);
+
/* fork X server process */
gdm_server_spawn (d);
@@ -231,7 +286,8 @@ gdm_server_start (GdmDisplay *disp)
/* Wait for X server to send ready signal */
while (d->servtries < 5) {
- gdm_run ();
+ if (d->servstat == SERVER_STARTED)
+ gdm_run ();
switch (d->servstat) {
@@ -242,6 +298,13 @@ gdm_server_start (GdmDisplay *disp)
gdm_debug ("gdm_server_start: Temporary server failure (%d)", d->name);
sleep (1 + d->servtries*2);
+
+ /* We add a timeout in case the X server fails to start. This
+ * might happen because X servers take a while to die, close their
+ * sockets etc. If the old X server isn't completely dead, the new
+ * one will fail and we'll hang here forever */
+
+ alarm (10);
gdm_server_spawn (d);
@@ -257,10 +320,18 @@ gdm_server_start (GdmDisplay *disp)
goto spawn_done;
case SERVER_ABORT:
+ /* Unset alarm */
alarm (0);
gdm_debug ("gdm_server_start: Server %s died during startup!", d->name);
sleep (1 + d->servtries*2);
+ /* We add a timeout in case the X server fails to start. This
+ * might happen because X servers take a while to die, close their
+ * sockets etc. If the old X server isn't completely dead, the new
+ * one will fail and we'll hang here forever */
+
+ alarm (10);
+
gdm_server_spawn (d);
break;
@@ -296,7 +367,8 @@ spawn_done:
static void
gdm_server_spawn (GdmDisplay *d)
{
- struct sigaction usr1;
+ struct sigaction usr1, dfl_signal;
+ sigset_t mask;
gchar *srvcmd = NULL;
gchar **argv = NULL;
int logfd;
@@ -316,13 +388,6 @@ gdm_server_spawn (GdmDisplay *d)
}
else
gdm_error (_("gdm_server_spawn: Could not open logfile for display %s!"), d->name);
-
- /* We add a timeout in case the X server fails to start. This
- * might happen because X servers take a while to die, close their
- * sockets etc. If the old X server isn't completely dead, the new
- * one will fail and we'll hang here forever */
-
- alarm (10);
/* Fork into two processes. Parent remains the gdm process. Child
* becomes the X server. */
@@ -338,11 +403,34 @@ gdm_server_spawn (GdmDisplay *d)
usr1.sa_handler = SIG_IGN;
usr1.sa_flags = SA_RESTART;
sigemptyset (&usr1.sa_mask);
-
+
if (sigaction (SIGUSR1, &usr1, NULL) < 0) {
gdm_error (_("gdm_server_spawn: Error setting USR1 to SIG_IGN"));
exit (SERVER_ABORT);
}
+
+ /* And HUP and TERM should be at default */
+ dfl_signal.sa_handler = SIG_IGN;
+ dfl_signal.sa_flags = SA_RESTART;
+ sigemptyset (&dfl_signal.sa_mask);
+
+ if (sigaction (SIGHUP, &dfl_signal, NULL) < 0) {
+ gdm_error (_("gdm_server_spawn: Error setting HUP to SIG_DFL"));
+ exit (SERVER_ABORT);
+ }
+ if (sigaction (SIGTERM, &dfl_signal, NULL) < 0) {
+ gdm_error (_("gdm_server_spawn: Error setting TERM to SIG_DFL"));
+ exit (SERVER_ABORT);
+ }
+
+ /* unblock HUP/TERM/USR1 so that we can control the
+ * X server */
+ sigprocmask (SIG_SETMASK, &sysmask, NULL);
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGUSR1);
+ sigaddset (&mask, SIGHUP);
+ sigaddset (&mask, SIGTERM);
+ sigprocmask (SIG_UNBLOCK, &mask, NULL);
srvcmd = g_strconcat (d->command, " -auth ", GdmServAuthDir, \
"/", d->name, ".Xauth ",
@@ -364,6 +452,7 @@ gdm_server_spawn (GdmDisplay *d)
gdm_error (_("gdm_server_spawn: Can't fork Xserver process!"));
d->servpid = 0;
d->servstat = SERVER_DEAD;
+
break;
default:
@@ -373,30 +462,6 @@ gdm_server_spawn (GdmDisplay *d)
/**
- * gdm_server_stop:
- * @disp: Pointer to a GdmDisplay structure
- *
- * Stops a local X server
- */
-
-void
-gdm_server_stop (GdmDisplay *d)
-{
- gdm_debug ("gdm_server_stop: Server for %s going down!", d->name);
-
- d->servstat = SERVER_DEAD;
-
- if (d->servpid != 0) {
- if (kill (d->servpid, SIGTERM) == 0)
- waitpid (d->servpid, 0, 0);
- d->servpid = 0;
- }
-
- unlink (d->authfile);
-}
-
-
-/**
* gdm_server_usr1_handler:
* @sig: Signal value
*
@@ -456,16 +521,14 @@ gdm_server_child_handler (gint signal)
*/
GdmDisplay *
-gdm_server_alloc (gint id, gchar *command)
+gdm_server_alloc (gint id, const gchar *command)
{
- gchar *dname = g_new0 (gchar, 1024);
gchar *hostname = g_new0 (gchar, 1024);
GdmDisplay *d = g_new0 (GdmDisplay, 1);
if (gethostname (hostname, 1023) == -1)
return NULL;
- sprintf (dname, ":%d", id);
d->authfile = NULL;
d->auths = NULL;
d->userauth = NULL;
@@ -473,7 +536,7 @@ gdm_server_alloc (gint id, gchar *command)
d->cookie = NULL;
d->dispstat = DISPLAY_DEAD;
d->greetpid = 0;
- d->name = g_strdup (dname);
+ d->name = g_strdup_printf (":%d", id);
d->hostname = g_strdup (hostname);
d->dispnum = id;
d->servpid = 0;
@@ -490,11 +553,62 @@ gdm_server_alloc (gint id, gchar *command)
d->retry_count = 0;
d->disabled = FALSE;
- g_free (dname);
g_free (hostname);
return d;
}
+/* ignore handlers */
+static gint
+ignore_xerror_handler (Display *disp, XErrorEvent *evt)
+{
+ return 0;
+}
+
+static gint
+ignore_xioerror_handler (Display *disp)
+{
+ return 0;
+}
+
+void
+gdm_server_whack_clients (GdmDisplay *disp)
+{
+ int i, screen_count;
+ gint (* old_xerror_handler) (Display *, XErrorEvent *);
+ gint (* old_xioerror_handler) (Display *);
+
+ if (disp == NULL ||
+ disp->dsp == NULL)
+ return;
+
+ old_xerror_handler = XSetErrorHandler (ignore_xerror_handler);
+ old_xioerror_handler = XSetIOErrorHandler (ignore_xioerror_handler);
+
+ screen_count = ScreenCount (disp->dsp);
+
+ for (i = 0; i < screen_count; i++) {
+ Window root_ret, parent_ret;
+ Window *childs = NULL;
+ unsigned int childs_count = 0;
+ Window root = RootWindow (disp->dsp, i);
+
+ while (XQueryTree (disp->dsp, root, &root_ret, &parent_ret,
+ &childs, &childs_count) &&
+ childs_count > 0) {
+ int ii;
+
+ for (ii = 0; ii < childs_count; ii++) {
+ XKillClient (disp->dsp, childs[ii]);
+ }
+
+ XFree (childs);
+ }
+ }
+
+ XSetErrorHandler (old_xerror_handler);
+ XSetIOErrorHandler (old_xioerror_handler);
+}
+
/* EOF */
diff --git a/daemon/server.h b/daemon/server.h
index c92af416..9c7063e4 100644
--- a/daemon/server.h
+++ b/daemon/server.h
@@ -21,10 +21,12 @@
#include "gdm.h"
-gboolean gdm_server_start (GdmDisplay *d);
-void gdm_server_kill (GdmDisplay *disp);
-void gdm_server_stop (GdmDisplay *d);
-GdmDisplay *gdm_server_alloc (gint id, gchar *command);
+gboolean gdm_server_start (GdmDisplay *d);
+void gdm_server_stop (GdmDisplay *d);
+void gdm_server_reinit (GdmDisplay *d);
+GdmDisplay * gdm_server_alloc (gint id,
+ const gchar *command);
+void gdm_server_whack_clients (GdmDisplay *disp);
#endif /* GDM_SERVER_H */
diff --git a/daemon/slave.c b/daemon/slave.c
index 9310f1c9..6fd38e18 100644
--- a/daemon/slave.c
+++ b/daemon/slave.c
@@ -50,7 +50,6 @@ static const gchar RCSid[]="$Id$";
static GdmDisplay *d;
static gchar *login = NULL;
static sigset_t mask, omask;
-static gboolean pingack;
static gboolean greet = FALSE;
static FILE *greeter;
@@ -80,65 +79,101 @@ extern gchar *argdelim;
/* Local prototypes */
static gint gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt);
static gint gdm_slave_xioerror_handler (Display *disp);
+static void gdm_slave_run (GdmDisplay *display);
+static void gdm_slave_wait_for_login (void);
static void gdm_slave_greeter (void);
static void gdm_slave_session_start (void);
-static void gdm_slave_session_stop (void);
+static void gdm_slave_session_stop (pid_t sesspid);
static void gdm_slave_session_cleanup (void);
static void gdm_slave_term_handler (int sig);
static void gdm_slave_child_handler (int sig);
-static void gdm_slave_windows_kill (void);
-/* static void gdm_slave_xsync_handler (int sig); */
-static gboolean gdm_slave_xsync_ping (void);
static void gdm_slave_exit (gint status, const gchar *format, ...);
static gint gdm_slave_exec_script (GdmDisplay*, gchar *dir);
static gchar* gdm_get_user_shell(void);
-
void
gdm_slave_start (GdmDisplay *display)
{
- struct sigaction term, child;
- gint openretries = 0;
-
- if (!display)
- return;
+ time_t first_time;
+ int death_count;
+ struct sigaction term, child;
+
+ if (!display)
+ return;
+
+ gdm_debug ("gdm_slave_start: Starting slave process for %s", display->name);
+ /* Handle a INT/TERM signals from gdm master */
+ term.sa_handler = gdm_slave_term_handler;
+ term.sa_flags = SA_RESTART;
+ sigemptyset (&term.sa_mask);
+ sigaddset (&term.sa_mask, SIGTERM);
+ sigaddset (&term.sa_mask, SIGINT);
+
+ if ((sigaction (SIGTERM, &term, NULL) < 0) ||
+ (sigaction (SIGINT, &term, NULL) < 0))
+ gdm_slave_exit (DISPLAY_ABORT, _("gdm_slave_init: Error setting up TERM/INT signal handler"));
+
+ /* Child handler. Keeps an eye on greeter/session */
+ child.sa_handler = gdm_slave_child_handler;
+ child.sa_flags = SA_RESTART|SA_NOCLDSTOP;
+ sigemptyset (&child.sa_mask);
+ sigaddset (&child.sa_mask, SIGCHLD);
+
+ if (sigaction (SIGCHLD, &child, NULL) < 0)
+ gdm_slave_exit (DISPLAY_ABORT, _("gdm_slave_init: Error setting up CHLD signal handler"));
+
+ /* The signals we wish to listen to */
+ sigfillset (&mask);
+ sigdelset (&mask, SIGINT);
+ sigdelset (&mask, SIGTERM);
+ sigdelset (&mask, SIGCHLD);
+ sigprocmask (SIG_SETMASK, &mask, NULL);
+
+ first_time = time (NULL);
+ death_count = 0;
+
+ for (;;) {
+ time_t the_time;
+
+ gdm_debug ("gdm_slave_start: Loop Thingie");
+ gdm_slave_run (display);
+
+ if (d->type != TYPE_LOCAL)
+ break;
+
+ the_time = time (NULL);
+
+ death_count ++;
+
+ if ((the_time - first_time) <= 0 ||
+ (the_time - first_time) > 60) {
+ first_time = the_time;
+ death_count = 0;
+ } else if (death_count > 6) {
+ /* exitting the loop will cause an
+ * abort actually */
+ break;
+ }
+ }
+}
- gdm_debug ("gdm_slave_start: Starting slave process for %s", display->name);
+
+static void
+gdm_slave_run (GdmDisplay *display)
+{
+ gint openretries = 0;
d = display;
- if (d->type == TYPE_LOCAL)
- gdm_server_start (d);
+ /* if this is local display start a server if one doesn't
+ * exist */
+ if (d->type == TYPE_LOCAL &&
+ d->servpid <= 0)
+ gdm_server_start (d);
gdm_setenv ("XAUTHORITY", d->authfile);
gdm_setenv ("DISPLAY", d->name);
- /* Handle a INT/TERM signals from gdm master */
- term.sa_handler = gdm_slave_term_handler;
- term.sa_flags = SA_RESTART;
- sigemptyset (&term.sa_mask);
- sigaddset (&term.sa_mask, SIGTERM);
- sigaddset (&term.sa_mask, SIGINT);
-
- if ((sigaction (SIGTERM, &term, NULL) < 0) || (sigaction (SIGINT, &term, NULL) < 0))
- gdm_slave_exit (DISPLAY_ABORT, _("gdm_slave_init: Error setting up TERM/INT signal handler"));
-
- /* Child handler. Keeps an eye on greeter/session */
- child.sa_handler = gdm_slave_child_handler;
- child.sa_flags = SA_RESTART|SA_NOCLDSTOP;
- sigemptyset (&child.sa_mask);
- sigaddset (&child.sa_mask, SIGCHLD);
-
- if (sigaction (SIGCHLD, &child, NULL) < 0)
- gdm_slave_exit (DISPLAY_ABORT, _("gdm_slave_init: Error setting up CHLD signal handler"));
-
- /* The signals we wish to listen to */
- sigfillset (&mask);
- sigdelset (&mask, SIGINT);
- sigdelset (&mask, SIGTERM);
- sigdelset (&mask, SIGCHLD);
- sigprocmask (SIG_SETMASK, &mask, NULL);
-
/* X error handlers to avoid the default one (i.e. exit (1)) */
XSetErrorHandler (gdm_slave_xerror_handler);
XSetIOErrorHandler (gdm_slave_xioerror_handler);
@@ -164,6 +199,9 @@ gdm_slave_start (GdmDisplay *display)
GdmAutomaticLogin != NULL &&
GdmAutomaticLogin[0] != '\0' &&
strcmp (GdmAutomaticLogin, "root") != 0) {
+ gdm_first_login = FALSE;
+
+ g_free (login);
login = g_strdup (GdmAutomaticLogin);
greet = FALSE;
@@ -181,14 +219,37 @@ gdm_slave_start (GdmDisplay *display)
gdm_debug ("gdm_slave_start: Automatic login done");
} else {
+ if (gdm_first_login)
+ gdm_first_login = FALSE;
gdm_slave_greeter (); /* Start the greeter */
+ gdm_slave_wait_for_login (); /* wait for a password */
+ gdm_slave_session_start ();
}
} else {
- gdm_server_kill (d);
+ gdm_server_stop (d);
exit (DISPLAY_ABORT);
}
}
+static void
+gdm_slave_wait_for_login (void)
+{
+ g_free (login);
+ login = NULL;
+
+ /* Chat with greeter */
+ while (login == NULL) {
+ gdm_debug ("gdm_slave_wait_for_login: In loop");
+ login = gdm_verify_user (d->name);
+
+ if (login == NULL) {
+ gdm_debug ("gdm_slave_wait_for_login: No login/Bad login");
+ g_free (gdm_slave_greeter_ctl (GDM_RESET, ""));
+ sleep (GdmRetryDelay);
+ }
+ }
+}
+
static void
gdm_slave_greeter (void)
@@ -264,21 +325,8 @@ gdm_slave_greeter (void)
gdm_debug ("gdm_slave_greeter: Greeter on pid %d", d->greetpid);
break;
}
-
- /* Chat with greeter */
- while (login == NULL) {
- login = gdm_verify_user (d->name);
-
- if (login == NULL) {
- gdm_slave_greeter_ctl (GDM_RESET, "");
- sleep (GdmRetryDelay);
- }
- }
-
- gdm_slave_session_start();
}
-
static void
gdm_slave_session_start (void)
{
@@ -289,6 +337,7 @@ gdm_slave_session_start (void)
gboolean savesess = FALSE, savelang = FALSE, usrcfgok = FALSE, authok = FALSE;
gint i;
char *shell;
+ pid_t sesspid;
pwent = getpwnam (login);
@@ -325,8 +374,8 @@ gdm_slave_session_start (void)
g_free (cfgstr);
}
else {
- usrsess = "";
- usrlang = "";
+ usrsess = g_strdup ("");
+ usrlang = g_strdup ("");
}
setegid (GdmGroupId);
@@ -336,6 +385,9 @@ gdm_slave_session_start (void)
session = gdm_slave_greeter_ctl (GDM_SESS, usrsess);
language = gdm_slave_greeter_ctl (GDM_LANG, usrlang);
}
+
+ g_free (usrsess);
+ g_free (usrlang);
if (session == NULL ||
session[0] == '\0') {
@@ -371,10 +423,10 @@ gdm_slave_session_start (void)
sigprocmask (SIG_SETMASK, &omask, NULL);
}
-
+
if (GdmKillInitClients)
- gdm_slave_windows_kill();
-
+ gdm_server_whack_clients (d);
+
/* Prepare user session */
gdm_setenv ("DISPLAY", d->name);
gdm_setenv ("LOGNAME", login);
@@ -416,12 +468,12 @@ gdm_slave_session_start (void)
setegid (GdmGroupId);
seteuid (0);
- if (!authok) {
+ if ( ! authok) {
gdm_debug ("gdm_slave_session_start: Auth not OK");
- gdm_slave_session_stop();
- gdm_slave_session_cleanup();
+ gdm_slave_session_stop (0);
+ gdm_slave_session_cleanup ();
- gdm_server_kill (d);
+ gdm_server_stop (d);
exit (DISPLAY_REMANAGE);
}
@@ -487,35 +539,43 @@ gdm_slave_session_start (void)
gdm_error (_("gdm_slave_session_start: Could not start session `%s'"), sesspath);
g_free (shell);
+ g_free (sesspath);
- gdm_slave_session_stop();
- gdm_slave_session_cleanup();
+ gdm_slave_session_stop (0);
+ gdm_slave_session_cleanup ();
- gdm_server_kill (d);
+ gdm_server_stop (d);
exit (DISPLAY_REMANAGE);
default:
break;
}
-
+
+ g_free (session);
+ g_free (language);
+
+ sesspid = d->sesspid;
+
/* Wait for the user's session to exit */
waitpid (d->sesspid, 0, 0);
+ d->sesspid = 0;
gdm_debug ("gdm_slave_session_start: Session ended OK");
- gdm_slave_session_stop();
- gdm_slave_session_cleanup();
+ gdm_slave_session_stop (sesspid);
+ gdm_slave_session_cleanup ();
}
static void
-gdm_slave_session_stop (void)
+gdm_slave_session_stop (pid_t sesspid)
{
struct passwd *pwent;
gdm_debug ("gdm_slave_session_stop: %s on %s", login, d->name);
- kill (- (d->sesspid), SIGTERM);
+ if (sesspid > 0)
+ kill (- (sesspid), SIGTERM);
gdm_verify_cleanup();
@@ -538,23 +598,18 @@ static void
gdm_slave_session_cleanup (void)
{
gdm_debug ("gdm_slave_session_cleanup: %s on %s", login, d->name);
+
+ /* kill login */
+ g_free (login);
+ login = NULL;
/* Execute post session script */
gdm_debug ("gdm_slave_session_cleanup: Running post session script");
gdm_slave_exec_script (d, GdmPostSession);
-
- if (d->dsp && gdm_slave_xsync_ping()) {
-
- /* Cleanup */
- gdm_debug ("gdm_slave_session_cleanup: Killing windows");
- gdm_slave_windows_kill();
-
- XCloseDisplay (d->dsp);
- d->dsp = NULL;
- }
-
- gdm_server_kill (d);
- exit (DISPLAY_REMANAGE);
+
+ /* Cleanup */
+ gdm_debug ("gdm_slave_session_cleanup: Killing windows");
+ gdm_server_reinit (d);
}
static gchar*
@@ -599,14 +654,11 @@ gdm_slave_term_handler (int sig)
d->greetpid = 0;
}
else if (login)
- gdm_slave_session_stop();
+ gdm_slave_session_stop (d->sesspid);
- gdm_debug ("gdm_slave_term_handler: Whacking client connections");
- gdm_slave_windows_kill();
- XCloseDisplay (d->dsp);
- d->dsp = NULL;
+ gdm_debug ("gdm_slave_term_handler: Whacking server");
- gdm_server_kill (d);
+ gdm_server_stop (d);
exit (DISPLAY_ABORT);
}
@@ -632,7 +684,7 @@ gdm_slave_child_handler (int sig)
if (pid == d->greetpid && greet) {
if (WIFEXITED (status)) {
- gdm_server_kill (d);
+ gdm_server_stop (d);
exit (WEXITSTATUS (status));
} else if (WIFSIGNALED (status) &&
WTERMSIG (status) != SIGQUIT &&
@@ -640,22 +692,16 @@ gdm_slave_child_handler (int sig)
WTERMSIG (status) != SIGTERM &&
WTERMSIG (status) != SIGINT) {
/* if we died of some weird signal, we are broken */
- gdm_server_kill (d);
+ gdm_server_stop (d);
exit (DISPLAY_GREETERSEGV);
} else {
- if (d && d->dsp) {
- XCloseDisplay (d->dsp);
- d->dsp = NULL;
- }
-
- gdm_server_kill (d);
+ gdm_server_stop (d);
exit (DISPLAY_REMANAGE);
}
}
if (pid && pid == d->sesspid) {
- gdm_slave_session_stop();
- gdm_slave_session_cleanup();
+ d->sesspid = 0;
}
if (pid && pid == d->servpid) {
@@ -666,78 +712,11 @@ gdm_slave_child_handler (int sig)
}
}
-static gint
-ignore_xerror (Display *disp, XErrorEvent *event)
-{
- return 0;
-}
-static gint
-ignore_xioerror (Display *disp)
-{
- return 0;
-}
-
-
-/* Only kills clients, not connections. This keeps the server alive */
-static void
-gdm_slave_windows_kill (void)
-{
- Window root, parent, *children;
- gint child, screen, nchildren;
- Display *disp = NULL;
- gint (* xerror) (Display *, XErrorEvent *);
- gint (* xioerror) (Display *);
-
- /* this seems just wrong! */
-#if 0
- disp=XOpenDisplay (d->name);
-
- if (!disp) {
- gdm_debug ("gdm_slave_windows_kill: Could not open display %s", d->name);
- return;
- }
-#endif
-
- disp = d->dsp;
-
- gdm_debug ("gdm_slave_windows_kill: Killing windows on %s", d->name);
-
- gdm_setenv ("XAUTHORITY", d->authfile);
- gdm_setenv ("DISPLAY", d->name);
-
- xerror = XSetErrorHandler (ignore_xerror);
- xioerror = XSetIOErrorHandler (ignore_xioerror);
-
- for (screen = 0 ; screen < ScreenCount (disp) ; screen++) {
-
- nchildren = 0;
-
- while (XQueryTree (disp, RootWindow (disp, screen), &root, &parent,
- &children, &nchildren) && nchildren>0) {
-
- for (child = 0 ; child < nchildren ; child++) {
- gdm_debug ("gdm_slave_windows_kill: Killing child 0x%x", children[child]);
- XKillClient (disp, children[child]);
- }
-
- XFree (children);
- }
-
- }
-
- XSync (disp, FALSE);
-
- XSetErrorHandler (xerror);
- XSetIOErrorHandler (xioerror);
-}
-
-
/* Minor X faults */
static gint
gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt)
{
gdm_debug ("gdm_slave_xerror_handler: X error - display doesn't respond");
- pingack = FALSE;
return (0);
}
@@ -749,78 +728,14 @@ gdm_slave_xioerror_handler (Display *disp)
gdm_debug ("gdm_slave_xioerror_handler: I/O error for display %s", d->name);
if (login)
- gdm_slave_session_stop();
+ gdm_slave_session_stop (d->sesspid);
gdm_error (_("gdm_slave_xioerror_handler: Fatal X error - Restarting %s"), d->name);
- gdm_server_kill (d);
+ gdm_server_stop (d);
exit (DISPLAY_REMANAGE);
}
-
-#if 0
-static void
-gdm_slave_xsync_handler (int sig)
-{
- gdm_debug ("gdm_slave_xsync_handler: Xping failed for display %s", d->name);
- pingack = FALSE;
-}
-#endif
-
-/* I don't understand how the alarm stuff would even work here, I mean
- * yes it would set the pingback var if XSync hangs, but other then that
- * it doesn't stop the hang */
-
-static gboolean
-gdm_slave_xsync_ping (void)
-{
-#if 0
- struct sigaction sigalarm;
- sigset_t mask, omask;
-#endif
- gint (* xerror) (Display *, XErrorEvent *);
- gint (* xioerror) (Display *);
-
- gdm_debug ("gdm_slave_xsync_ping: Pinging %s", d->name);
-
- pingack = TRUE;
-
- xerror = XSetErrorHandler (gdm_slave_xerror_handler);
- xioerror = XSetIOErrorHandler (gdm_slave_xioerror_handler);
-
-#if 0
- sigalarm.sa_handler = gdm_slave_xsync_handler;
- sigalarm.sa_flags = 0;
- sigemptyset (&sigalarm.sa_mask);
-#endif
-
-#if 0
- if (sigaction (SIGALRM, &sigalarm, NULL) < 0)
- gdm_slave_exit (DISPLAY_ABORT, _("gdm_slave_xsync_ping: Error setting up ALARM signal handler"));
-
- sigemptyset (&mask);
- sigaddset (&mask, SIGALRM);
- sigprocmask (SIG_UNBLOCK, &mask, &omask);
-
- alarm (10);
-#endif
-
- XSync (d->dsp, TRUE);
-
-#if 0
- alarm (0);
- sigprocmask (SIG_SETMASK, &omask, NULL);
-#endif
-
- gdm_debug ("gdm_slave_xsync_ping: %s returned %d", d->name, pingack);
-
- XSetErrorHandler (xerror);
- XSetIOErrorHandler (xioerror);
-
- return (pingack);
-}
-
-
gchar *
gdm_slave_greeter_ctl (gchar cmd, gchar *str)
{
@@ -833,16 +748,18 @@ gdm_slave_greeter_ctl (gchar cmd, gchar *str)
g_print ("%c%c\n", STX, cmd);
/* Skip random junk that might have accumulated */
- do { c = getc (greeter); } while (c && c != STX);
+ do {
+ c = getc (greeter);
+ } while (c && c != STX);
fgets (buf, FIELD_SIZE-1, greeter);
if (strlen (buf)) {
buf[strlen (buf)-1] = '\0';
- return (g_strndup (buf, strlen (buf)));
+ return g_strdup (buf);
}
else
- return (NULL);
+ return NULL;
}
@@ -861,19 +778,19 @@ gdm_slave_exit (gint status, const gchar *format, ...)
g_free (s);
/* Kill children where applicable */
- if (d->greetpid)
+ if (d->greetpid != 0)
kill (d->greetpid, SIGTERM);
d->greetpid = 0;
- if (d->chooserpid)
+ if (d->chooserpid != 0)
kill (d->chooserpid, SIGTERM);
d->chooserpid = 0;
- if (d->sesspid)
- kill (d->sesspid, SIGTERM);
+ if (d->sesspid != 0)
+ kill (-(d->sesspid), SIGTERM);
d->sesspid = 0;
- if (d->servpid)
+ if (d->servpid != 0)
kill (d->servpid, SIGTERM);
d->servpid = 0;
diff --git a/docs/C/.cvsignore b/docs/C/.cvsignore
new file mode 100644
index 00000000..4a31d14a
--- /dev/null
+++ b/docs/C/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+Makefile.in
+gdm
+gdm.html
+*.junk
diff --git a/gui/gdmlogin.c b/gui/gdmlogin.c
index 4ef24324..05568633 100644
--- a/gui/gdmlogin.c
+++ b/gui/gdmlogin.c
@@ -77,25 +77,25 @@ static GnomeIconList *browser;
static GdkImlibImage *defface;
/* Eew. Loads of global vars. It's hard to be event controlled while maintaining state */
-GSList *sessions = NULL;
-GSList *languages = NULL;
-GList *users = NULL;
-GSList *exclude = NULL;
-
-gchar *defsess=NULL;
-gchar *cursess=NULL;
-gchar *curlang=NULL;
-gchar *curuser=NULL;
-gchar *lastsess=NULL;
-gchar *lastlang=NULL;
-gchar *session=NULL;
-gchar *language=NULL;
-
-gboolean savesess;
-gboolean savelang;
-gint maxwidth;
-
-pid_t backgroundpid = 0;
+static GSList *sessions = NULL;
+static GSList *languages = NULL;
+static GList *users = NULL;
+static GSList *exclude = NULL;
+
+static gchar *defsess = NULL;
+static gchar *cursess = NULL;
+static gchar *curlang = NULL;
+static gchar *curuser = NULL;
+static gchar *lastsess = NULL;
+static gchar *lastlang = NULL;
+static gchar *session = NULL;
+static gchar *language = NULL;
+
+static gboolean savesess;
+static gboolean savelang;
+static gint maxwidth;
+
+static pid_t backgroundpid = 0;
static void
gdm_greeter_chld (int sig)
@@ -111,6 +111,7 @@ kill_background (void)
{
if (backgroundpid != 0) {
kill (backgroundpid, SIGTERM);
+ backgroundpid = 0;
}
}
@@ -122,7 +123,10 @@ gdm_login_done (int sig)
}
-typedef struct _cursoroffset { gint x,y; } CursorOffset;
+typedef struct _CursorOffset {
+ int x;
+ int y;
+} CursorOffset;
static void
@@ -486,7 +490,7 @@ gdm_login_list_lookup (GSList *l, gchar *data)
static void
gdm_login_session_lookup (gchar* savedsess)
{
- if (!curuser)
+ if (curuser == NULL)
gdm_login_abort("gdm_login_session_lookup: curuser==NULL. Mail <mkp@mkp.net> with " \
"information on your PAM and user database setup");
@@ -546,7 +550,7 @@ gdm_login_session_lookup (gchar* savedsess)
static void
gdm_login_language_lookup (gchar* savedlang)
{
- if (!curuser)
+ if (curuser == NULL)
gdm_login_abort("gdm_login_language_lookup: curuser==NULL. Mail <mkp@mkp.net> with " \
"information on your PAM and user database setup");
@@ -609,7 +613,7 @@ gdm_login_entry_handler (GtkWidget *widget, GdkEventKey *event)
* setups. Needs thinking!
*/
- if (!curuser)
+ if (curuser == NULL)
curuser = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
g_print ("%c%s\n", STX, gtk_entry_get_text (GTK_ENTRY (entry)));
@@ -960,9 +964,9 @@ gdm_login_ctrl_handler (GIOChannel *source, GIOCondition cond, gint fd)
}
}
- if (curuser) {
+ if (curuser != NULL) {
g_free (curuser);
- curuser=NULL;
+ curuser = NULL;
}
gtk_widget_set_sensitive (GTK_WIDGET (entry), TRUE);
@@ -1029,7 +1033,7 @@ gdm_login_browser_select (GtkWidget *widget, gint selected, GdkEvent *event)
if (user && user->login)
gtk_entry_set_text (GTK_ENTRY (entry), user->login);
- if (!curuser)
+ if (curuser == NULL)
curuser = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
gtk_widget_set_sensitive (GTK_WIDGET (entry), FALSE);