diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | daemon/display.c | 14 | ||||
-rw-r--r-- | daemon/misc.c | 7 | ||||
-rw-r--r-- | daemon/server.c | 198 | ||||
-rw-r--r-- | daemon/server.h | 10 | ||||
-rw-r--r-- | daemon/slave.c | 399 | ||||
-rw-r--r-- | docs/C/.cvsignore | 5 | ||||
-rw-r--r-- | gui/gdmlogin.c | 56 |
9 files changed, 375 insertions, 322 deletions
@@ -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 @@ -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); |