summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Lebl <jirka@5z.com>2001-07-05 10:27:30 +0000
committerGeorge Lebl <jirka@src.gnome.org>2001-07-05 10:27:30 +0000
commit77acdba97f5933ef5bdbce0751dd7492e4df87c5 (patch)
tree48f61259e218a0e035f1a0c4ad06314192ffaee2
parenta277ba17bf69aa34f7f077b4ed3d0f30852db0f3 (diff)
downloadgdm-77acdba97f5933ef5bdbce0751dd7492e4df87c5.tar.gz
raise version to 2.2.3.1
Thu Jul 05 03:29:01 2001 George Lebl <jirka@5z.com> * configure.in: raise version to 2.2.3.1 * gdm.spec.in: do a "soft restart" in %post * gui/gdmchooser.c, gui/gdmlogin.c: warning fixes * daemon/misc.h, daemon/slave.c, daemon/xdmcp.c, daemon/choose.c, daemon/display.c, daemon/gdm.c,saemon/server.c: fix printf style warnings * daemon/choose.[ch], display/gdm.[ch], daemon/slave.c: change the fifo protocol to be text based so that we can also control from scripts like the .spec file. Also store all the different pids in the daemon so that we can whack all the different processes the slave starts if it crashes. Also add a soft restart opcode.
-rw-r--r--ChangeLog18
-rw-r--r--TODO3
-rw-r--r--configure.in2
-rw-r--r--daemon/choose.c34
-rw-r--r--daemon/choose.h12
-rw-r--r--daemon/display.c4
-rw-r--r--daemon/gdm.c216
-rw-r--r--daemon/gdm.h41
-rw-r--r--daemon/misc.h8
-rw-r--r--daemon/server.c18
-rw-r--r--daemon/slave.c107
-rw-r--r--daemon/xdmcp.c34
-rw-r--r--gdm.spec.in7
-rw-r--r--gui/gdmchooser.c2
-rw-r--r--gui/gdmlogin.c2
15 files changed, 317 insertions, 191 deletions
diff --git a/ChangeLog b/ChangeLog
index dcd47539..d7978644 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Thu Jul 05 03:29:01 2001 George Lebl <jirka@5z.com>
+
+ * configure.in: raise version to 2.2.3.1
+
+ * gdm.spec.in: do a "soft restart" in %post
+
+ * gui/gdmchooser.c, gui/gdmlogin.c: warning fixes
+
+ * daemon/misc.h, daemon/slave.c, daemon/xdmcp.c, daemon/choose.c,
+ daemon/display.c, daemon/gdm.c,saemon/server.c: fix printf style
+ warnings
+
+ * daemon/choose.[ch], display/gdm.[ch], daemon/slave.c: change the
+ fifo protocol to be text based so that we can also control from
+ scripts like the .spec file. Also store all the different pids
+ in the daemon so that we can whack all the different processes
+ the slave starts if it crashes. Also add a soft restart opcode.
+
Wed Jul 04 20:58:31 2001 George Lebl <jirka@5z.com>
* gdm-safe-restart.in, Makefile.am, configure.in, daemon/choose.[ch],
diff --git a/TODO b/TODO
index 69e66e30..bf02b312 100644
--- a/TODO
+++ b/TODO
@@ -17,7 +17,4 @@ xsri like logo functionality
the photosetup proggie should be put into some sort of crapplet and there
should be other settings in the crapplet as well.
-Version /var/run/gdm.version, and check this on gdm-safe-restart, and
-do safe restart in spec file
-
Make sure that greeter whacks all on SIGPIPE (X connection fail)
diff --git a/configure.in b/configure.in
index 86761259..4f2dd2da 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,7 @@ dnl
AM_PROG_XML_I18N_TOOLS
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(gdm,2.2.3)
+AM_INIT_AUTOMAKE(gdm,2.2.3.1)
AM_MAINTAINER_MODE
AM_ACLOCAL_INCLUDE(macros)
diff --git a/daemon/choose.c b/daemon/choose.c
index d4d6782e..7b73521e 100644
--- a/daemon/choose.c
+++ b/daemon/choose.c
@@ -39,6 +39,7 @@
#include <fcntl.h>
#include "gdm.h"
+#include "misc.h"
#include "choose.h"
static const gchar RCSid[]="$Id$";
@@ -50,8 +51,6 @@ static GSList *indirect = NULL;
extern gint GdmMaxIndirect; /* Maximum pending indirects, i.e. simultaneous choosing sessions */
extern gint GdmMaxIndirectWait; /* Maximum age before a pending session is removed from the list */
-extern void gdm_debug (gchar *, ...);
-
static guint indirect_id = 1;
static gboolean
@@ -80,23 +79,38 @@ remove_oldest_pending (void)
}
gboolean
-gdm_choose_data (void *uncast_data, size_t len)
+gdm_choose_data (const char *data)
{
- GdmChooseData data;
+ int id;
+ struct in_addr addr;
GSList *li;
+ char *msg = g_strdup (data);
+ char *p;
- if (len != sizeof (data)) {
+ p = strtok (msg, " ");
+ if (p == NULL || strcmp (GDM_SOP_CHOSEN, p) != 0) {
+ g_free (msg);
return FALSE;
}
- memcpy (&data, uncast_data, len);
+ p = strtok (NULL, " ");
+ if (p == NULL || sscanf (p, "%d", &id) != 1) {
+ g_free (msg);
+ return FALSE;
+ }
+
+ p = strtok (NULL, " ");
+ if (p == NULL || inet_aton (p, &addr) == 0) {
+ g_free (msg);
+ return FALSE;
+ }
gdm_debug ("gdm_choose_data: got indirect id: %d address: %s",
- data.id, inet_ntoa (data.addr));
+ id, inet_ntoa (addr));
for (li = indirect; li != NULL; li = li->next) {
GdmIndirectDisplay *idisp = li->data;
- if (idisp->id == data.id) {
+ if (idisp->id == id) {
/* whack the oldest if more then allowed */
while (ipending >= GdmMaxIndirect &&
remove_oldest_pending ())
@@ -105,7 +119,7 @@ gdm_choose_data (void *uncast_data, size_t len)
idisp->acctime = time (NULL);
g_free (idisp->chosen_host);
idisp->chosen_host = g_new (struct in_addr, 1);
- memcpy (idisp->chosen_host, &(data.addr),
+ memcpy (idisp->chosen_host, &addr,
sizeof (struct in_addr));
/* Now this display is pending */
@@ -217,7 +231,7 @@ gdm_choose_indirect_dispose (GdmIndirectDisplay *id)
ipending--;
id->acctime = 0;
- gdm_debug ("gdm_choose_indirect_dispose: Disposing %d",
+ gdm_debug ("gdm_choose_indirect_dispose: Disposing %s",
inet_ntoa (id->dsp_sa->sin_addr));
g_free (id->dsp_sa);
diff --git a/daemon/choose.h b/daemon/choose.h
index 19ba9b0f..86fa8dc2 100644
--- a/daemon/choose.h
+++ b/daemon/choose.h
@@ -21,9 +21,6 @@
#include "gdm.h"
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
GdmIndirectDisplay * gdm_choose_indirect_alloc (struct sockaddr_in *clnt_sa);
GdmIndirectDisplay * gdm_choose_indirect_lookup (struct sockaddr_in *clnt_sa);
void gdm_choose_indirect_dispose (GdmIndirectDisplay *id);
@@ -31,14 +28,7 @@ void gdm_choose_indirect_dispose (GdmIndirectDisplay *id);
/* dispose of indirect display of id, if no host is set */
void gdm_choose_indirect_dispose_empty_id (guint id);
-typedef struct _GdmChooseData GdmChooseData;
-struct _GdmChooseData {
- int id;
- struct in_addr addr;
-};
-
-gboolean gdm_choose_data (void *uncast_data,
- size_t len);
+gboolean gdm_choose_data (const char *data);
#endif /* CHOOSE_H */
diff --git a/daemon/display.c b/daemon/display.c
index d631dbbb..e9a5be5a 100644
--- a/daemon/display.c
+++ b/daemon/display.c
@@ -101,8 +101,8 @@ gdm_display_check_loop (GdmDisplay *disp)
*/
if (since_last < 8)
{
- gdm_debug ("Will sleep %d seconds before next X server restart attempt",
- 8 - since_last);
+ gdm_debug ("Will sleep %ld seconds before next X server restart attempt",
+ (long)(8 - since_last));
now = time (NULL) + 8 - since_last;
disp->sleep_before_run = 8 - since_last;
}
diff --git a/daemon/gdm.c b/daemon/gdm.c
index fcdeba81..fc298e77 100644
--- a/daemon/gdm.c
+++ b/daemon/gdm.c
@@ -372,7 +372,7 @@ gdm_config_parse (void)
*stemp = '\0';
if (access (gtemp, X_OK))
- gdm_error ("gdm_config_parse: Greeter not found or can't be executed by the gdm user", gtemp);
+ gdm_error (_("%s: Greeter not found or can't be executed by the gdm user"), "gdm_config_parse");
}
g_free (gtemp);
@@ -386,7 +386,7 @@ gdm_config_parse (void)
*stemp = '\0';
if (access (gtemp, X_OK))
- gdm_error ("gdm_config_parse: Chooser not found or it can't be executed by the gdm user", gtemp);
+ gdm_error (_("%s: Chooser not found or it can't be executed by the gdm user"), "gdm_config_parse");
}
g_free (gtemp);
@@ -705,7 +705,8 @@ gdm_cleanup_children (void)
crashed = TRUE;
}
- gdm_debug ("gdm_cleanup_children: child %d returned %d", pid, status);
+ gdm_debug ("gdm_cleanup_children: child %d returned %d%s", pid, status,
+ crashed ? " (child crashed)" : "");
if (pid < 1)
return;
@@ -717,19 +718,37 @@ gdm_cleanup_children (void)
return;
if (crashed) {
+ gdm_debug ("gdm_cleanup_children: Slave crashed, killing it's "
+ "children");
+
+ if (d->sesspid > 0) {
+ if (kill (d->sesspid, SIGTERM) == 0)
+ waitpid (d->sesspid, NULL, 0);
+ d->sesspid = 0;
+ }
+ if (d->greetpid > 0) {
+ if (kill (d->greetpid, SIGTERM) == 0)
+ waitpid (d->greetpid, NULL, 0);
+ d->greetpid = 0;
+ }
+ if (d->chooserpid > 0) {
+ if (kill (d->chooserpid, SIGTERM) == 0)
+ waitpid (d->chooserpid, NULL, 0);
+ d->chooserpid = 0;
+ }
if (d->servpid > 0) {
if (kill (d->servpid, SIGTERM) == 0)
waitpid (d->servpid, NULL, 0);
-
- /* just for paranoia's sake, yes sleeping in the
- * daemon is bad but this is an exceptional
- * situation and not normal occurance. */
- sleep (3);
-
d->servpid = 0;
}
}
+ /* null all these, they are not valid most definately */
+ d->servpid = 0;
+ d->sesspid = 0;
+ d->greetpid = 0;
+ d->chooserpid = 0;
+
/* definately not logged in now */
d->logged_in = FALSE;
@@ -1268,81 +1287,144 @@ gdm_quit (void)
g_main_quit (main_loop);
}
+static void
+handle_message (const char *msg)
+{
+ gdm_debug ("Handeling message: '%s'", msg);
+
+ if (strncmp (msg, GDM_SOP_CHOSEN " ",
+ strlen (GDM_SOP_CHOSEN " ")) == 0) {
+ gdm_choose_data (msg);
+ } else if (strncmp (msg, GDM_SOP_XPID " ",
+ strlen (GDM_SOP_XPID " ")) == 0) {
+ GdmDisplay *d;
+ long slave_pid, pid;
+
+ if (sscanf (msg, GDM_SOP_XPID " %ld %ld", &slave_pid, &pid)
+ != 2)
+ return;
+
+ /* Find out who this slave belongs to */
+ d = gdm_display_lookup (slave_pid);
+
+ if (d != NULL) {
+ d->servpid = pid;
+ gdm_debug ("Got XPID == %ld", (long)pid);
+ /* send ack */
+ kill (slave_pid, SIGUSR2);
+ }
+ } else if (strncmp (msg, GDM_SOP_SESSPID " ",
+ strlen (GDM_SOP_SESSPID " ")) == 0) {
+ GdmDisplay *d;
+ long slave_pid, pid;
+
+ if (sscanf (msg, GDM_SOP_SESSPID " %ld %ld", &slave_pid, &pid)
+ != 2)
+ return;
+
+ /* Find out who this slave belongs to */
+ d = gdm_display_lookup (slave_pid);
+
+ if (d != NULL) {
+ d->sesspid = pid;
+ gdm_debug ("Got SESSPID == %ld", (long)pid);
+ /* send ack */
+ kill (slave_pid, SIGUSR2);
+ }
+ } else if (strncmp (msg, GDM_SOP_GREETPID " ",
+ strlen (GDM_SOP_GREETPID " ")) == 0) {
+ GdmDisplay *d;
+ long slave_pid, pid;
+
+ if (sscanf (msg, GDM_SOP_GREETPID " %ld %ld", &slave_pid, &pid)
+ != 2)
+ return;
+
+ /* Find out who this slave belongs to */
+ d = gdm_display_lookup (slave_pid);
+
+ if (d != NULL) {
+ d->greetpid = pid;
+ gdm_debug ("Got GREETPID == %ld", (long)pid);
+ /* send ack */
+ kill (slave_pid, SIGUSR2);
+ }
+ } else if (strncmp (msg, GDM_SOP_CHOOSERPID " ",
+ strlen (GDM_SOP_CHOOSERPID " ")) == 0) {
+ GdmDisplay *d;
+ long slave_pid, pid;
+
+ if (sscanf (msg, GDM_SOP_CHOOSERPID " %ld %ld",
+ &slave_pid, &pid) != 2)
+ return;
+
+ /* Find out who this slave belongs to */
+ d = gdm_display_lookup (slave_pid);
+
+ if (d != NULL) {
+ d->chooserpid = pid;
+ gdm_debug ("Got CHOOSERPID == %ld", (long)pid);
+ /* send ack */
+ kill (slave_pid, SIGUSR2);
+ }
+ } else if (strncmp (msg, GDM_SOP_LOGGED_IN " ",
+ strlen (GDM_SOP_LOGGED_IN " ")) == 0) {
+ GdmDisplay *d;
+ long slave_pid;
+ int logged_in;
+ if (sscanf (msg, GDM_SOP_LOGGED_IN " %ld %d", &slave_pid,
+ &logged_in) != 2)
+ return;
+
+ /* Find out who this slave belongs to */
+ d = gdm_display_lookup (slave_pid);
+
+ if (d != NULL) {
+ d->logged_in = logged_in ? TRUE : FALSE;
+ gdm_debug ("Got logged in == %s",
+ d->logged_in ? "TRUE" : "FALSE");
+
+ /* if the user just logged out,
+ * let's see if it's safe to restart */
+ if (gdm_restart_mode &&
+ ! d->logged_in)
+ gdm_safe_restart ();
+
+ /* send ack */
+ kill (slave_pid, SIGUSR2);
+ }
+ } else if (strcmp (msg, GDM_SOP_SOFT_RESTART) == 0) {
+ gdm_restart_mode = TRUE;
+ gdm_safe_restart ();
+ }
+}
+
static gboolean
gdm_slave_socket_handler (GIOChannel *source,
GIOCondition cond,
gpointer data)
{
- GdmSlaveHeader header;
gchar buf[PIPE_SIZE];
+ char *p;
gint len;
if (cond != G_IO_IN)
return TRUE;
- if (g_io_channel_read (source, (char *)&header, sizeof (header), &len)
+ if (g_io_channel_read (source, buf, sizeof (buf) - 1, &len)
!= G_IO_ERROR_NONE)
return TRUE;
- if (len < sizeof (header))
+ if (len <= 0)
return TRUE;
- gdm_debug ("gdm_slave_socket_handler: opcode %d len %d",
- (int) header.opcode,
- (int) header.len);
+ /* null terminate as the string is NOT */
+ buf[len] = '\0';
- if (header.len > 0) {
- if (g_io_channel_read (source, buf, header.len, &len)
- != G_IO_ERROR_NONE)
- return TRUE;
-
- if (len != header.len)
- return TRUE;
- } else {
- len = 0;
- }
-
- gdm_debug ("gdm_slave_socket_handler: Read %d bytes", len);
-
- if (header.opcode <= GDM_SOP_INVALID ||
- header.opcode >= GDM_SOP_LAST) {
- gdm_error (_("%s: Invalid opcode"),
- "gdm_slave_socket_handler");
- return TRUE;
- }
-
- if (header.opcode == GDM_SOP_CHOOSER) {
- gdm_choose_data (buf, header.len);
- } else if (header.opcode == GDM_SOP_XPID) {
- GdmXPidData data;
- if (header.len == sizeof (data)) {
- GdmDisplay *d;
- memcpy (&data, buf, sizeof (data));
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (data.slave_pid);
-
- if (d != NULL) {
- d->servpid = data.xpid;
- }
- }
- } else if (header.opcode == GDM_SOP_LOGGED_IN) {
- GdmLoggedInData data;
- if (header.len == sizeof (data)) {
- GdmDisplay *d;
- memcpy (&data, buf, sizeof (data));
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (data.slave_pid);
-
- if (d != NULL) {
- d->logged_in = data.logged_in;
-
- /* if the user just logged out,
- * let's see if it's safe to restart */
- if (gdm_restart_mode &&
- ! data.logged_in)
- gdm_safe_restart ();
- }
- }
+ p = strtok (buf, "\n");
+ while (p != NULL) {
+ handle_message (p);
+ p = strtok (NULL, "\n");
}
return TRUE;
diff --git a/daemon/gdm.h b/daemon/gdm.h
index f15ebc39..db630290 100644
--- a/daemon/gdm.h
+++ b/daemon/gdm.h
@@ -286,39 +286,16 @@ void gdm_quit (void);
/* primitive protocol for controlling the daemon from the chooser
* or gdmconfig or whatnot */
-enum {
- GDM_SOP_INVALID = 0,
- GDM_SOP_CHOOSER, /* Chosen host information */
- GDM_SOP_XPID, /* Pid of X server so that in case of
- slave crash, daemon can kill it */
- GDM_SOP_LOGGED_IN, /* status of user, if logged in or not,
- useful for safe restarts */
-
- GDM_SOP_LAST
-};
-
-typedef struct _GdmXPidData GdmXPidData;
-struct _GdmXPidData {
- pid_t slave_pid;
- pid_t xpid;
-};
-
-typedef struct _GdmLoggedInData GdmLoggedInData;
-struct _GdmLoggedInData {
- pid_t slave_pid;
- gboolean logged_in;
-};
-
-/* Protocol is not for use outside of gdm so endianess be damned,
- * it's not really a "wire" protocol, just for the programs of the
- * gdm suite. Which are all compiled on the same machine etc... etc...
- * blah blah blah*/
-typedef struct _GdmSlaveHeader GdmSlaveHeader;
-struct _GdmSlaveHeader {
- int opcode;
- size_t len; /* length of data (not including header) */
-};
+/* The ones that pass a <slave pid> must be from a valid slave, and
+ * the slave will be sent a SIGUSR2 */
+#define GDM_SOP_CHOSEN "CHOSEN" /* <indirect id> <ip addr> */
+#define GDM_SOP_XPID "XPID" /* <slave pid> <xpid> */
+#define GDM_SOP_SESSPID "SESSPID" /* <slave pid> <sesspid> */
+#define GDM_SOP_GREETPID "GREETPID" /* <slave pid> <greetpid> */
+#define GDM_SOP_CHOOSERPID "CHOOSERPID" /* <slave pid> <chooserpid> */
+#define GDM_SOP_LOGGED_IN "LOGGED_IN" /* <slave pid> <logged_in as int> */
+#define GDM_SOP_SOFT_RESTART "SOFT_RESTART" /* no arguments */
void gdm_fifo_close (void);
diff --git a/daemon/misc.h b/daemon/misc.h
index f36ff8db..cf267beb 100644
--- a/daemon/misc.h
+++ b/daemon/misc.h
@@ -22,10 +22,10 @@
#include "config.h"
#include "gdm.h"
-void gdm_fail (const gchar *format, ...);
-void gdm_info (const gchar *format, ...);
-void gdm_error (const gchar *format, ...);
-void gdm_debug (const gchar *format, ...);
+void gdm_fail (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
+void gdm_info (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
+void gdm_error (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
+void gdm_debug (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
#ifdef HAVE_SETENV
#define gdm_setenv(var,value) setenv(var,value,-1)
diff --git a/daemon/server.c b/daemon/server.c
index 15afa16f..361f74b3 100644
--- a/daemon/server.c
+++ b/daemon/server.c
@@ -96,18 +96,20 @@ gdm_server_reinit (GdmDisplay *disp)
void
gdm_server_stop (GdmDisplay *disp)
{
- if (disp == NULL ||
- disp->servpid <= 0)
+ if (disp == NULL)
return;
- gdm_debug ("gdm_server_stop: Server for %s going down!", disp->name);
-
/* Kill our connection if one existed */
if (disp->dsp != NULL) {
- XCloseDisplay (disp->dsp);
- disp->dsp = NULL;
+ XCloseDisplay (disp->dsp);
+ disp->dsp = NULL;
}
-
+
+ if (disp->servpid <= 0)
+ return;
+
+ gdm_debug ("gdm_server_stop: Server for %s going down!", disp->name);
+
disp->servstat = SERVER_DEAD;
if (disp->servpid != 0) {
@@ -296,7 +298,7 @@ gdm_server_start (GdmDisplay *disp)
switch (d->servstat) {
case SERVER_TIMEOUT:
- gdm_debug ("gdm_server_start: Temporary server failure (%d)", d->name);
+ gdm_debug ("gdm_server_start: Temporary server failure (%s)", d->name);
break;
case SERVER_ABORT:
diff --git a/daemon/slave.c b/daemon/slave.c
index f798f46e..7eee9fc7 100644
--- a/daemon/slave.c
+++ b/daemon/slave.c
@@ -127,17 +127,19 @@ static void gdm_slave_session_cleanup (void);
static void gdm_slave_alrm_handler (int sig);
static void gdm_slave_term_handler (int sig);
static void gdm_slave_child_handler (int sig);
-static void gdm_slave_exit (gint status, const gchar *format, ...);
-static void gdm_child_exit (gint status, const gchar *format, ...);
+static void gdm_slave_usr2_handler (int sig);
+static void gdm_slave_exit (gint status, const gchar *format, ...) G_GNUC_PRINTF (2, 3);
+static void gdm_child_exit (gint status, const gchar *format, ...) G_GNUC_PRINTF (2, 3);
static gint gdm_slave_exec_script (GdmDisplay *d, const gchar *dir,
const char *login, struct passwd *pwent);
static gchar * gdm_parse_enriched_login (const gchar *s, GdmDisplay *display);
static void gdm_send_logged_in (gboolean logged_in);
-static void gdm_send_xpid (pid_t xpid);
+static void gdm_send_pid (const char *opcode, pid_t pid);
/* Yay thread unsafety */
static gboolean x_error_occured = FALSE;
+static gboolean gdm_got_usr2 = FALSE;
/* ignore handlers */
static int
@@ -159,7 +161,7 @@ gdm_slave_start (GdmDisplay *display)
{
time_t first_time;
int death_count;
- struct sigaction alrm, term, child;
+ struct sigaction alrm, term, child, usr2;
if (!display)
return;
@@ -197,11 +199,21 @@ gdm_slave_start (GdmDisplay *display)
if (sigaction (SIGCHLD, &child, NULL) < 0)
gdm_slave_exit (DISPLAY_ABORT, _("gdm_slave_init: Error setting up CHLD signal handler"));
+ /* Handle a USR2 which is ack from master that it received a message */
+ usr2.sa_handler = gdm_slave_usr2_handler;
+ usr2.sa_flags = SA_RESTART;
+ sigemptyset (&usr2.sa_mask);
+ sigaddset (&usr2.sa_mask, SIGUSR2);
+
+ if (sigaction (SIGUSR2, &usr2, NULL) < 0)
+ gdm_slave_exit (DISPLAY_ABORT, _("%s: Error setting up USR2 signal handler"), "gdm_slave_init");
+
/* The signals we wish to listen to */
sigfillset (&mask);
sigdelset (&mask, SIGINT);
sigdelset (&mask, SIGTERM);
sigdelset (&mask, SIGCHLD);
+ sigdelset (&mask, SIGUSR2);
if (display->type != TYPE_LOCAL &&
GdmPingInterval > 0) {
sigdelset (&mask, SIGALRM);
@@ -241,7 +253,7 @@ gdm_slave_start (GdmDisplay *display)
/* Whack the server if we want to restart it next time
* we run gdm_slave_run */
gdm_server_stop (display);
- gdm_send_xpid (0);
+ gdm_send_pid (GDM_SOP_XPID, 0);
} else {
/* OK about to start again so redo our cookies and reinit
* the server */
@@ -353,7 +365,7 @@ gdm_slave_run (GdmDisplay *display)
if (d->type == TYPE_LOCAL &&
d->servpid <= 0) {
gdm_server_start (d);
- gdm_send_xpid (d->servpid);
+ gdm_send_pid (GDM_SOP_XPID, d->servpid);
}
gdm_setenv ("XAUTHORITY", d->authfile);
@@ -473,6 +485,8 @@ gdm_slave_whack_greeter (void)
waitpid (d->greetpid, 0, 0);
d->greetpid = 0;
+ gdm_send_pid (GDM_SOP_GREETPID, 0);
+
if (greeter != NULL)
fclose (greeter);
greeter = NULL;
@@ -1127,50 +1141,54 @@ gdm_slave_greeter (void)
gdm_debug ("gdm_slave_greeter: Greeter on pid %d", d->greetpid);
+ gdm_send_pid (GDM_SOP_GREETPID, d->greetpid);
+
run_pictures (); /* Append pictures to greeter if browsing is on */
break;
}
}
static void
-gdm_send_xpid (pid_t xpid)
+gdm_send_pid (const char *opcode, pid_t pid)
{
- GdmSlaveHeader header;
- GdmXPidData data;
+ char *msg;
int fd;
char *fifopath;
- gdm_debug ("Sending X pid == %ld for slave %ld",
- (long)xpid,
+ gdm_debug ("Sending %s == %ld for slave %ld",
+ opcode,
+ (long)pid,
(long)getpid ());
+ gdm_got_usr2 = FALSE;
+
fifopath = g_strconcat (GdmServAuthDir, "/.gdmfifo", NULL);
fd = open (fifopath, O_WRONLY);
/* eek */
if (fd < 0) {
- gdm_error (_("%s: Can't open fifo!"), "gdm_send_logged_in");
+ gdm_error (_("%s: Can't open fifo!"), "gdm_send_pid");
return;
}
- header.opcode = GDM_SOP_XPID;
- header.len = sizeof (data);
+ msg = g_strdup_printf ("\n%s %ld %ld\n", opcode,
+ (long)getpid (), (long)pid);
- data.slave_pid = getpid ();
- data.xpid = xpid;
+ write (fd, msg, strlen (msg));
- write (fd, &header, sizeof (header));
- write (fd, &data, sizeof (data));
+ g_free (msg);
close (fd);
+
+ if ( ! gdm_got_usr2)
+ sleep (10);
}
static void
gdm_send_logged_in (gboolean logged_in)
{
- GdmSlaveHeader header;
- GdmLoggedInData data;
+ char *msg;
int fd;
char *fifopath;
@@ -1178,6 +1196,8 @@ gdm_send_logged_in (gboolean logged_in)
logged_in ? "TRUE" : "FALSE",
(long)getpid ());
+ gdm_got_usr2 = FALSE;
+
fifopath = g_strconcat (GdmServAuthDir, "/.gdmfifo", NULL);
fd = open (fifopath, O_WRONLY);
@@ -1187,23 +1207,23 @@ gdm_send_logged_in (gboolean logged_in)
return;
}
- header.opcode = GDM_SOP_LOGGED_IN;
- header.len = sizeof (data);
+ msg = g_strdup_printf ("\n%s %ld %d\n", GDM_SOP_LOGGED_IN,
+ (long)getpid (), (int)logged_in);
- data.slave_pid = getpid ();
- data.logged_in = logged_in;
+ write (fd, msg, strlen (msg));
- write (fd, &header, sizeof (header));
- write (fd, &data, sizeof (data));
+ g_free (msg);
close (fd);
+
+ if ( ! gdm_got_usr2)
+ sleep (10);
}
static void
send_chosen_host (GdmDisplay *disp, const char *hostname)
{
- GdmSlaveHeader header;
- GdmChooseData data;
+ char *msg;
int fd;
char *fifopath;
struct hostent *host;
@@ -1228,15 +1248,13 @@ send_chosen_host (GdmDisplay *disp, const char *hostname)
return;
}
- header.opcode = GDM_SOP_CHOOSER;
- header.len = sizeof (GdmChooseData);
+ msg = g_strdup_printf ("\n%s %d %s\n", GDM_SOP_CHOSEN,
+ disp->indirect_id,
+ inet_ntoa (*((struct in_addr *)host->h_addr_list[0])));
- data.id = disp->indirect_id;
- memcpy (&(data.addr), (struct in_addr *)host->h_addr_list[0],
- sizeof (struct in_addr));
+ write (fd, msg, strlen (msg));
- write (fd, &header, sizeof (header));
- write (fd, &data, sizeof (data));
+ g_free (msg);
close (fd);
}
@@ -1263,7 +1281,7 @@ gdm_slave_chooser (void)
/* Fork. Parent is gdmslave, child is greeter process. */
last_killed_pid = 0; /* race condition wrapper,
* it could be that we recieve sigchld before
- * we can set greetpid. eek! */
+ * we can set chooserpid. eek! */
switch (d->chooserpid = fork()) {
case 0:
@@ -1337,6 +1355,8 @@ gdm_slave_chooser (void)
}
gdm_debug ("gdm_slave_chooser: Chooser on pid %d", d->chooserpid);
+ gdm_send_pid (GDM_SOP_CHOOSERPID, d->chooserpid);
+
close (p[1]);
fcntl(p[0], F_SETFD, fcntl(p[0], F_GETFD, 0) | FD_CLOEXEC);
@@ -1344,6 +1364,8 @@ gdm_slave_chooser (void)
/* wait for the chooser to die */
waitpid (d->chooserpid, 0, 0);
+ gdm_send_pid (GDM_SOP_CHOOSERPID, 0);
+
bytes = read (p[0], buf, sizeof(buf)-1);
if (bytes > 0) {
if (buf[bytes-1] == '\n')
@@ -2028,6 +2050,7 @@ gdm_slave_session_start (void)
g_free (gnome_session);
sesspid = d->sesspid;
+ gdm_send_pid (GDM_SOP_SESSPID, sesspid);
/* Wait for the user's session to exit, but by this time the
* session might have ended, so check for 0 */
@@ -2054,6 +2077,8 @@ gdm_slave_session_stop (pid_t sesspid)
seteuid (0);
setegid (0);
+ gdm_send_pid (GDM_SOP_SESSPID, 0);
+
gdm_debug ("gdm_slave_session_stop: %s on %s", local_login, d->name);
if (sesspid > 0)
@@ -2109,7 +2134,7 @@ gdm_slave_term_handler (int sig)
{
sigset_t tmask, omask;
- gdm_debug ("gdm_slave_term_handler: %s got TERM signal", d->name);
+ gdm_debug ("gdm_slave_term_handler: %s got TERM/INT signal", d->name);
/* just for paranoia's sake */
seteuid (0);
@@ -2224,6 +2249,14 @@ gdm_slave_child_handler (int sig)
}
}
+static void
+gdm_slave_usr2_handler (int sig)
+{
+ gdm_debug ("gdm_slave_usr2_handler: %s got USR2 signal", d->name);
+
+ gdm_got_usr2 = TRUE;
+}
+
/* Minor X faults */
static gint
gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt)
diff --git a/daemon/xdmcp.c b/daemon/xdmcp.c
index 01f7013c..b408bcd8 100644
--- a/daemon/xdmcp.c
+++ b/daemon/xdmcp.c
@@ -481,7 +481,8 @@ gdm_xdmcp_handle_query (struct sockaddr_in *clnt_sa, gint len, gint type)
/* Crude checksumming */
for (i = 0 ; i < clnt_authlist.length ; i++) {
- gdm_debug ("gdm_xdmcp_handle_query: authlist: %s", clnt_authlist.data);
+ gdm_debug ("gdm_xdmcp_handle_query: authlist: %s",
+ (char *)clnt_authlist.data);
explen += 2+clnt_authlist.data[i].length;
}
@@ -650,7 +651,8 @@ gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, gint len)
explen += 2+clnt_port.length;
for (i = 0 ; i < clnt_authlist.length ; i++) {
- gdm_debug ("gdm_xdmcp_handle_forward_query: authlist: %s", clnt_authlist.data);
+ gdm_debug ("gdm_xdmcp_handle_forward_query: authlist: %s",
+ (char *)clnt_authlist.data);
explen += 2+clnt_authlist.data[i].length;
}
@@ -943,8 +945,8 @@ gdm_xdmcp_send_accept (const char *hostname,
XdmcpFlush (xdmcpfd, &buf, clnt_sa, (int)sizeof (struct sockaddr_in));
- gdm_debug ("gdm_xdmcp_send_accept: Sending ACCEPT to %s with SessionID=%d",
- inet_ntoa (clnt_sa->sin_addr), d->sessionid);
+ gdm_debug ("gdm_xdmcp_send_accept: Sending ACCEPT to %s with SessionID=%ld",
+ inet_ntoa (clnt_sa->sin_addr), (long)d->sessionid);
}
@@ -1014,8 +1016,8 @@ gdm_xdmcp_handle_manage (struct sockaddr_in *clnt_sa, gint len)
return;
}
- gdm_debug ("gdm_xdmcp_handle_manage: Got Display=%d, SessionID=%d from %s",
- clnt_dspnum, clnt_sessid, inet_ntoa (clnt_sa->sin_addr));
+ gdm_debug ("gdm_xdmcp_handle_manage: Got Display=%d, SessionID=%ld from %s",
+ (int)clnt_dspnum, (long)clnt_sessid, inet_ntoa (clnt_sa->sin_addr));
/* Display Class */
if (! XdmcpReadARRAY8 (&buf, &clnt_dspclass)) {
@@ -1076,10 +1078,12 @@ gdm_xdmcp_handle_manage (struct sockaddr_in *clnt_sa, gint len)
}
}
else if (d && d->dispstat == XDMCP_MANAGED) {
- gdm_debug ("gdm_xdmcp_handle_manage: Session id %d already managed", clnt_sessid);
+ gdm_debug ("gdm_xdmcp_handle_manage: Session id %ld already managed",
+ (long)clnt_sessid);
}
else {
- gdm_debug ("gdm_xdmcp_handle_manage: Failed to look up session id %d", clnt_sessid);
+ gdm_debug ("gdm_xdmcp_handle_manage: Failed to look up session id %ld",
+ (long)clnt_sessid);
gdm_xdmcp_send_refuse (clnt_sa, clnt_sessid);
}
@@ -1092,7 +1096,7 @@ gdm_xdmcp_send_refuse (struct sockaddr_in *clnt_sa, CARD32 sessid)
{
XdmcpHeader header;
- gdm_debug ("gdm_xdmcp_send_refuse: Sending REFUSE to %d", sessid);
+ gdm_debug ("gdm_xdmcp_send_refuse: Sending REFUSE to %ld", (long)sessid);
header.version = XDM_PROTOCOL_VERSION;
header.opcode= (CARD16) REFUSE;
@@ -1110,7 +1114,7 @@ gdm_xdmcp_send_failed (struct sockaddr_in *clnt_sa, CARD32 sessid)
XdmcpHeader header;
ARRAY8 status;
- gdm_debug ("gdm_xdmcp_send_failed: Sending FAILED to %d", sessid);
+ gdm_debug ("gdm_xdmcp_send_failed: Sending FAILED to %ld", (long)sessid);
status.data = "Failed to start session";
status.length = strlen (status.data);
@@ -1163,7 +1167,7 @@ gdm_xdmcp_send_alive (struct sockaddr_in *clnt_sa, CARD32 sessid)
{
XdmcpHeader header;
- gdm_debug ("Sending ALIVE to %d", sessid);
+ gdm_debug ("Sending ALIVE to %ld", (long)sessid);
header.version = XDM_PROTOCOL_VERSION;
header.opcode = (CARD16) ALIVE;
@@ -1246,8 +1250,8 @@ gdm_xdmcp_display_alloc (const char *hostname, gint displaynum)
pending++;
- gdm_debug ("gdm_xdmcp_display_alloc: display=%s, session id=%d, pending=%d ",
- d->name, d->sessionid, pending);
+ gdm_debug ("gdm_xdmcp_display_alloc: display=%s, session id=%ld, pending=%d ",
+ d->name, (long)d->sessionid, pending);
return (d);
}
@@ -1320,8 +1324,8 @@ gdm_xdmcp_displays_check (void)
d->type == TYPE_XDMCP &&
d->dispstat == XDMCP_PENDING &&
time (NULL) > d->acctime + GdmMaxManageWait) {
- gdm_debug ("gdm_xdmcp_displays_check: Disposing session id %d",
- d->sessionid);
+ gdm_debug ("gdm_xdmcp_displays_check: Disposing session id %ld",
+ (long)d->sessionid);
gdm_display_dispose (d);
/* restart as the list is now fucked */
diff --git a/gdm.spec.in b/gdm.spec.in
index 7fad201a..2eeb805c 100644
--- a/gdm.spec.in
+++ b/gdm.spec.in
@@ -77,6 +77,13 @@ ln -sf ../../xdm/TakeConsole $RPM_BUILD_ROOT%{sysconfdir}/X11/gdm/PostSession/De
# and couldn't create account with the current adduser.
exit 0
+%post
+# Attempt to restart GDM softly by use of the fifo. Wont work on older
+# then 2.2.3.1 versions but should work nicely on later upgrades.
+if test -w %{localstatedir}/gdm/.gdmfifo ; then (echo;echo SOFT_RESTART) >> %{localstatedir}/gdm/.gdmfifo ; fi
+# ignore error in the above
+exit 0
+
%files
%defattr(-, root, root)
diff --git a/gui/gdmchooser.c b/gui/gdmchooser.c
index dbdfaa0f..62c3c003 100644
--- a/gui/gdmchooser.c
+++ b/gui/gdmchooser.c
@@ -73,7 +73,7 @@ static gboolean gdm_chooser_decode_packet (GIOChannel *source,
GIOCondition condition,
gpointer data);
-static void gdm_chooser_abort (const gchar *format, ...);
+static void gdm_chooser_abort (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
static void gdm_chooser_browser_update (void);
static void gdm_chooser_xdmcp_init (char **hosts);
static void gdm_chooser_host_dispose (GdmChooserHost *host);
diff --git a/gui/gdmlogin.c b/gui/gdmlogin.c
index 28c4aeb7..f8a1f687 100644
--- a/gui/gdmlogin.c
+++ b/gui/gdmlogin.c
@@ -167,6 +167,8 @@ static char *selected_browser_user = NULL;
* in some way or another */
static gboolean session_dir_whacked_out = FALSE;
+static void gdm_login_abort (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
+
/*
* Timed Login: Timer
*/