diff options
author | George Lebl <jirka@5z.com> | 2002-07-09 17:16:59 +0000 |
---|---|---|
committer | George Lebl <jirka@src.gnome.org> | 2002-07-09 17:16:59 +0000 |
commit | ed9fbb6e14f5059e2b05dfc02a49bcc2ef0aca9f (patch) | |
tree | bb8728c592038f898f1d4bd34a87144986f4c13e | |
parent | 66fd78c9ec917cd9beabb3a2e7c334841b88d429 (diff) | |
download | gdm-ed9fbb6e14f5059e2b05dfc02a49bcc2ef0aca9f.tar.gz |
Fix some errors with server starting, fix alarm/sleep collisions, add a
Tue Jul 09 10:27:51 2002 George Lebl <jirka@5z.com>
* config/gdm.conf.in, daemon/gdm.[ch], daemon/server.c,
daemon/slave.c, daemon/xdmcp.c: Fix some errors with server
starting, fix alarm/sleep collisions, add a handled flag to
servers so that we can setup unhandled X servers (such as
for X terminals)
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | config/gdm.conf.in | 17 | ||||
-rw-r--r-- | daemon/gdm.c | 9 | ||||
-rw-r--r-- | daemon/gdm.h | 7 | ||||
-rw-r--r-- | daemon/server.c | 99 | ||||
-rw-r--r-- | daemon/slave.c | 56 | ||||
-rw-r--r-- | daemon/xdmcp.c | 2 |
7 files changed, 141 insertions, 57 deletions
@@ -1,3 +1,11 @@ +Tue Jul 09 10:27:51 2002 George Lebl <jirka@5z.com> + + * config/gdm.conf.in, daemon/gdm.[ch], daemon/server.c, + daemon/slave.c, daemon/xdmcp.c: Fix some errors with server + starting, fix alarm/sleep collisions, add a handled flag to + servers so that we can setup unhandled X servers (such as + for X terminals) + Tue Jul 09 09:14:55 2002 George Lebl <jirka@5z.com> * daemon/slave.c: do the display init before the user setup for diff --git a/config/gdm.conf.in b/config/gdm.conf.in index 21e87e1a..806761b2 100644 --- a/config/gdm.conf.in +++ b/config/gdm.conf.in @@ -148,8 +148,25 @@ Enable=false # starts as the last thing, and that will make it not neccessary to # do hacks like this. #0=Standard vt7 +# +#Note: If you want to run an X terminal you could add an X server such as this +#0=Terminal -query serverhostname +# or for a chooser (optionally serverhostname could be localhost) +#0=Terminal -indirect serverhostname [server-Standard] name=Standard server command=/usr/X11R6/bin/X flexible=true + +# To use this server type you should add -query host or -indirect host +# to the command line +[server-Terminal] +name=Terminal server +# Add -terminate to make things behave more nicely +command=/usr/X11R6/bin/X -terminate +# Make this not appear in the flexible servers (we need extra params +# anyway, and terminate would be bad for xdmcp) +flexible=false +# Not local, we do not handle the logins for this X server +handled=false diff --git a/daemon/gdm.c b/daemon/gdm.c index fb94d2cb..9fb1669a 100644 --- a/daemon/gdm.c +++ b/daemon/gdm.c @@ -390,6 +390,8 @@ gdm_config_parse (void) (GDM_KEY_SERVER_FLEXIBLE); svr->choosable = gnome_config_get_bool (GDM_KEY_SERVER_CHOOSABLE); + svr->handled = gnome_config_get_bool + (GDM_KEY_SERVER_HANDLED); if (ve_string_empty (svr->command)) { gdm_error (_("%s: Empty server command, " @@ -419,6 +421,7 @@ gdm_config_parse (void) svr->command = g_strdup (GdmStandardXServer); svr->flexible = TRUE; svr->choosable = TRUE; + svr->handled = TRUE; xservers = g_slist_append (xservers, svr); } @@ -2100,6 +2103,7 @@ check_cookie (const char *file, const char *disp, const char *cookie) static void handle_flexi_server (GdmConnection *conn, int type, const char *server, + gboolean handled, const char *xnest_disp, uid_t xnest_uid, const char *xnest_auth_file, const char *xnest_cookie) @@ -2172,6 +2176,7 @@ handle_flexi_server (GdmConnection *conn, int type, const char *server, "ERROR 2 Startup errors\n"); return; } + display->handled = handled; if (type == TYPE_FLEXI_XNEST) { GdmDisplay *parent; @@ -2506,6 +2511,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) return; } handle_flexi_server (conn, TYPE_FLEXI, GdmStandardXServer, + TRUE /* handled */, NULL, 0, NULL, NULL); } else if (strncmp (msg, GDM_SUP_FLEXI_XSERVER " ", strlen (GDM_SUP_FLEXI_XSERVER " ")) == 0) { @@ -2547,7 +2553,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) } g_free (name); - handle_flexi_server (conn, TYPE_FLEXI, command, + handle_flexi_server (conn, TYPE_FLEXI, command, svr->handled, NULL, 0, NULL, NULL); } else if (strncmp (msg, GDM_SUP_FLEXI_XNEST " ", strlen (GDM_SUP_FLEXI_XNEST " ")) == 0) { @@ -2576,6 +2582,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) } handle_flexi_server (conn, TYPE_FLEXI_XNEST, GdmXnest, + TRUE /* handled */, dispname, uid, xauthfile, cookie); g_free (dispname); diff --git a/daemon/gdm.h b/daemon/gdm.h index 1aabe9ae..f47dd67d 100644 --- a/daemon/gdm.h +++ b/daemon/gdm.h @@ -166,7 +166,9 @@ enum { /* runnable as flexi server */ #define GDM_KEY_SERVER_FLEXIBLE "flexible=true" /* choosable from the login screen */ -#define GDM_KEY_SERVER_CHOOSABLE "choosable=true" +#define GDM_KEY_SERVER_CHOOSABLE "choosable=false" +/* Login is handled by gdm, otherwise it's a remote server */ +#define GDM_KEY_SERVER_HANDLED "handled=true" #define GDM_KEY_ALLOWROOT "security/AllowRoot=true" #define GDM_KEY_ALLOWREMOTEROOT "security/AllowRemoteRoot=true" @@ -285,6 +287,8 @@ struct _GdmDisplay { pid_t chooserpid; time_t acctime; + gboolean handled; + #ifdef __linux__ int vt; #endif @@ -331,6 +335,7 @@ struct _GdmXServer { char *command; gboolean flexible; gboolean choosable; /* not implemented yet */ + gboolean handled; }; typedef struct _GdmIndirectDisplay GdmIndirectDisplay; diff --git a/daemon/server.c b/daemon/server.c index 98132106..41d35631 100644 --- a/daemon/server.c +++ b/daemon/server.c @@ -399,7 +399,7 @@ gdm_server_start (GdmDisplay *disp, gboolean treat_as_flexi, * sockets etc. If the old X server isn't completely dead, the new * one will fail and we'll hang here forever */ - /* Only do alarm if esrver will be run as root */ + /* Only do alarm if server will be run as root */ if (d->server_uid == 0) { alarm (SERVER_WAIT_ALARM); } @@ -409,11 +409,22 @@ gdm_server_start (GdmDisplay *disp, gboolean treat_as_flexi, /* fork X server process */ gdm_server_spawn (d); + /* we can now use d->handled since that's set up above */ + /* Wait for X server to send ready signal */ if (d->servstat == SERVER_STARTED) { - if (d->server_uid != 0) { + if (d->server_uid != 0 && ! d->handled) { + alarm (0); + /* FIXME: If not handled, we just don't know, so + * just wait a few seconds and hope things just work, + * fortunately there is no such case yet and probably + * never will, but just for code anality's sake */ + sleep (5); + } else if (d->server_uid != 0) { int i; + alarm (0); + /* if we're running the server as a non-root, we can't * use USR1 of course, so try openning the display * as a test, but the */ @@ -618,6 +629,9 @@ rotate_logs (const char *dname) * @disp: Pointer to a GdmDisplay structure * * forks an actual X server process + * + * Note that we can only use d->handled once we call this function + * since otherwise the server might not yet be looked up yet. */ static void @@ -650,6 +664,47 @@ gdm_server_spawn (GdmDisplay *d) waitpid (pid, NULL, 0); } + + /* Figure out the server command */ + bin = ve_first_word (d->command); + if (bin == NULL) { + gdm_error (_("Invalid server command '%s'"), d->command); + argv = ve_split (GdmStandardXServer); + command = GdmStandardXServer; + } else if (bin[0] != '/') { + GdmXServer *svr = gdm_find_x_server (bin); + if (svr == NULL) { + gdm_error (_("Server name '%s' not found, " + "using standard server"), bin); + argv = ve_split (GdmStandardXServer); + command = GdmStandardXServer; + } else { + char **svr_command = + ve_split (ve_sure_string (svr->command)); + argv = ve_split (d->command); + if (argv[0] == NULL || argv[1] == NULL) { + g_strfreev (argv); + argv = svr_command; + } else { + char **old_argv = argv; + argv = ve_vector_merge (svr_command, + &old_argv[1]); + g_strfreev (svr_command); + g_strfreev (old_argv); + } + /* this is only for information only, + * so doesn't include whole command line */ + command = svr->command; + + /* Setup the handled function */ + d->handled = svr->handled; + } + } else { + command = d->command; + argv = ve_split (d->command); + } + g_free (bin); + /* Fork into two processes. Parent remains the gdm process. Child * becomes the X server. */ @@ -741,42 +796,6 @@ gdm_server_spawn (GdmDisplay *d) gnome_unsetenv ("XAUTHORITY"); } - bin = ve_first_word (d->command); - if (bin == NULL) { - gdm_error (_("Invalid server command '%s'"), d->command); - argv = ve_split (GdmStandardXServer); - command = GdmStandardXServer; - } else if (bin[0] != '/') { - GdmXServer *svr = gdm_find_x_server (bin); - if (svr == NULL) { - gdm_error (_("Server name '%s' not found, " - "using standard server"), bin); - argv = ve_split (GdmStandardXServer); - command = GdmStandardXServer; - } else { - char **svr_command = - ve_split (ve_sure_string (svr->command)); - argv = ve_split (d->command); - if (argv[0] == NULL || argv[1] == NULL) { - g_strfreev (argv); - argv = svr_command; - } else { - char **old_argv = argv; - argv = ve_vector_merge (svr_command, - &old_argv[1]); - g_strfreev (svr_command); - g_strfreev (old_argv); - } - /* this is only for information only, - * so doesn't include whole command line */ - command = svr->command; - } - } else { - command = d->command; - argv = ve_split (d->command); - } - g_free (bin); - for (len = 0; argv != NULL && argv[len] != NULL; len++) ; @@ -857,6 +876,7 @@ gdm_server_spawn (GdmDisplay *d) _exit (SERVER_ABORT); case -1: + g_strfreev (argv); gdm_error (_("gdm_server_spawn: Can't fork Xserver process!")); d->servpid = 0; d->servstat = SERVER_DEAD; @@ -864,6 +884,7 @@ gdm_server_spawn (GdmDisplay *d) break; default: + g_strfreev (argv); gdm_debug ("gdm_server_spawn: Forked server on pid %d", (int)pid); break; } @@ -1011,6 +1032,8 @@ gdm_server_alloc (gint id, const gchar *command) d->screenx = 0; /* xinerama offset */ d->screeny = 0; + d->handled = TRUE; + #ifdef __linux__ d->vt = -1; #endif diff --git a/daemon/slave.c b/daemon/slave.c index 83edf813..17cf9791 100644 --- a/daemon/slave.c +++ b/daemon/slave.c @@ -451,23 +451,27 @@ gdm_slave_run (GdmDisplay *display) check_notifies_now (); } + + /* We can use d->handled from now on on this display, + * since the lookup was done in server start */ gnome_setenv ("XAUTHORITY", d->authfile, TRUE); gnome_setenv ("DISPLAY", d->name, TRUE); - /* Now the display name and hostname is final */ - if ( ! ve_string_empty (GdmAutomaticLogin)) { - g_free (ParsedAutomaticLogin); - ParsedAutomaticLogin = gdm_parse_enriched_login (GdmAutomaticLogin, - display); - } + if (d->handled) { + /* Now the display name and hostname is final */ + if ( ! ve_string_empty (GdmAutomaticLogin)) { + g_free (ParsedAutomaticLogin); + ParsedAutomaticLogin = gdm_parse_enriched_login (GdmAutomaticLogin, + display); + } - if ( ! ve_string_empty (GdmTimedLogin)) { - g_free (ParsedTimedLogin); - ParsedTimedLogin = gdm_parse_enriched_login (GdmTimedLogin, - display); + if ( ! ve_string_empty (GdmTimedLogin)) { + g_free (ParsedTimedLogin); + ParsedTimedLogin = gdm_parse_enriched_login (GdmTimedLogin, + display); + } } - /* X error handlers to avoid the default one (i.e. exit (1)) */ do_xfailed_on_xio_error = TRUE; @@ -486,7 +490,8 @@ gdm_slave_run (GdmDisplay *display) else maxtries = 10; - while (openretries < maxtries && + while (d->handled && + openretries < maxtries && d->dsp == NULL) { d->dsp = XOpenDisplay (d->name); @@ -497,6 +502,11 @@ gdm_slave_run (GdmDisplay *display) } } + /* Just a race avoiding sleep, probably not necessary though, + * but doesn't hurt anything */ + if ( ! d->handled) + sleep (1); + if (SERVER_IS_LOCAL (d)) { gdm_slave_send (GDM_SOP_START_NEXT_LOCAL, FALSE); } @@ -505,7 +515,7 @@ gdm_slave_run (GdmDisplay *display) /* something may have gone wrong, try xfailed, if local (non-flexi), * the toplevel loop of death will handle us */ - if (d->dsp == NULL) { + if (d->handled && d->dsp == NULL) { gdm_server_stop (d); if (d->type == TYPE_LOCAL) _exit (DISPLAY_XFAILED); @@ -514,8 +524,8 @@ gdm_slave_run (GdmDisplay *display) } /* Some sort of a bug foo to make some servers work or whatnot, - * stolem from xdm sourcecode, perhaps not necessary, but can't hurt */ - { + * stolen from xdm sourcecode, perhaps not necessary, but can't hurt */ + if (d->handled) { Display *dsp = XOpenDisplay (d->name); if (dsp != NULL) XCloseDisplay (dsp); @@ -532,14 +542,23 @@ gdm_slave_run (GdmDisplay *display) } /* checkout xinerama */ - gdm_screen_init (d); + if (d->handled) + gdm_screen_init (d); /* check log stuff for the server, this is done here * because it's really a race */ if (SERVER_IS_LOCAL (d)) gdm_server_checklog (d); - if (d->use_chooser) { + if ( ! d->handled) { + /* yay, we now wait for the server to die, + * which will in fact just exit, so + * this code is a little bit too anal */ + while (d->servpid != 0) { + select (0, NULL, NULL, NULL, NULL); + } + return; + } else if (d->use_chooser) { /* this usually doesn't return */ gdm_slave_chooser (); /* Run the chooser */ return; @@ -2893,6 +2912,9 @@ gdm_slave_child_handler (int sig) d->servstat = SERVER_DEAD; d->servpid = 0; gdm_server_wipe_cookies (d); + + if ( ! d->handled) + _exit (DISPLAY_REMANAGE); } else if (pid == extra_process) { /* an extra process died, yay! */ extra_process = -1; diff --git a/daemon/xdmcp.c b/daemon/xdmcp.c index 2215f7df..ede9f0f2 100644 --- a/daemon/xdmcp.c +++ b/daemon/xdmcp.c @@ -1531,6 +1531,8 @@ gdm_xdmcp_display_alloc (struct in_addr *addr, const char *hostname, gint displa d->acctime = time (NULL); d->dispnum = displaynum; + d->handled = TRUE; + #ifdef __linux__ d->vt = -1; #endif |