commit c7791f293660c22fd699020ff1ec1ac83ad94afa Author: Halton Huo Date: Fri Nov 27 21:30:58 2009 +0800 gdm-08-fbconsole.diff (rework) diff --git a/acconfig.h b/acconfig.h index 7a625d2..db32ec0 100644 --- a/acconfig.h +++ b/acconfig.h @@ -14,6 +14,8 @@ #undef HAVE_CHPASS #undef HAVE_CLEARENV #undef HAVE_CRYPT +#undef FBCONSOLE +#undef HAVE_FBCONSOLE #undef HAVE_GETTEXT #undef HAVE_LC_MESSAGES #undef HAVE_LIBSM diff --git a/configure.ac b/configure.ac index 76b88a0..e6d0e6a 100644 --- a/configure.ac +++ b/configure.ac @@ -1025,6 +1025,16 @@ fi AC_SUBST(XEVIE_OPTION) AC_DEFINE_UNQUOTED(XEVIE_OPTION,"$XEVIE_OPTION",[Define xevie option]) +# Check for Solaris VT and fbconsole support +# +AC_CHECK_HEADERS(sys/vt.h) + +AC_PATH_PROG([FBCONSOLE], [fbconsole], no, [$PATH:/usr/X11/bin:/usr/bin]) +if test x$FBCONSOLE != xno ; then + AC_DEFINE(HAVE_FBCONSOLE) + AC_DEFINE_UNQUOTED([FBCONSOLE], "${FBCONSOLE}", [fbconsole program]) +fi + dnl --------------------------------------------------------------------------- dnl - Check for audit framework dnl --------------------------------------------------------------------------- diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c index 6408d04..c4e3f93 100644 --- a/daemon/gdm-server.c +++ b/daemon/gdm-server.c @@ -39,6 +39,12 @@ #include #include +#ifdef HAVE_FBCONSOLE +#ifdef HAVE_SYS_VT_H +#include +#endif +#endif + #include #include /* for Display */ @@ -69,6 +75,7 @@ struct GdmServerPrivate { char *command; GPid pid; + GPid fbconsolepid; int priority; char *user_name; @@ -120,6 +127,128 @@ static void gdm_server_finalize (GObject *object); G_DEFINE_TYPE (GdmServer, gdm_server, G_TYPE_OBJECT) +#ifdef HAVE_FBCONSOLE +static void +gdm_exec_fbconsole (GdmServer *server) +{ + gboolean run_fbconsole; + char *argv[6]; + + run_fbconsole = FALSE; + + if (server->priv->fbconsolepid == 0) { + + g_debug ("Checking if fbconsole should be started"); + + if (strcmp (server->priv->display_device, "/dev/console") == 0) { + int fd; +#ifdef HAVE_SYS_VT_H + int vtstat; +#endif + + g_debug ("Running on console"); + + /* If no VT, then run fbconsole */ + run_fbconsole = TRUE; + + /* Set run_fbconsole as TRUE since Xsun + does not support VT at all */ + char *x_server; + char *out; + char *command; + char **arr; + char **arr1; + int status; + int i; + gboolean res; + GError *error; + + error = NULL; + out = NULL; + command = g_strdup ("svcprop svc:/application/x11/x11-server"); + + res = g_spawn_command_line_sync (command, + &out, + NULL, + &status, + &error); + g_free (command); + + if (! res) { + g_warning ("Could not get options/server of FMRI x11-server: %s", error->message); + g_error_free (error); + g_free (out); + } + + x_server = NULL; + arr = g_strsplit (out,"\n", -1); + i = 0; + while (arr [i++] != NULL) { + if (g_str_has_prefix (arr[i], "options/server")) { + arr1 = g_strsplit (arr[i], " ", -1); + x_server = g_strdup (arr1[2]); + g_strfreev (arr1); + break; + } + } + g_strfreev (arr); + + if (g_str_has_suffix (x_server, "Xsun")) { + run_fbconsole = TRUE; + } else { + +#ifdef HAVE_SYS_VT_H + fd = open ("/dev/vt/0", O_WRONLY); + if (fd > 0) { + if (ioctl (fd, VT_ENABLED, &vtstat) == 0) { + if (vtstat == 1) { + g_debug ("VT is enabled, so not forking fbconsole"); + run_fbconsole = FALSE; + } + } + } + +#endif + } + + g_free (x_server); + + if (run_fbconsole == TRUE) { + g_debug ("VT is not enabled, so fork fbconsole"); + } + + } else { + g_debug ("Using %s and not on console, so not forking fbconsole", + server->priv->display_device ? server->priv->display_device : "(null)"); + } + } + + if (run_fbconsole == FALSE) { + return; + } + + argv[0] = FBCONSOLE; + argv[1] = "-n"; + argv[2] = "-d"; + argv[3] = server->priv->display_name; + argv[4] = NULL; + + g_debug ("Forking fbconsole"); + + server->priv->fbconsolepid = fork (); + if (server->priv->fbconsolepid == 0) { + execv (argv[0], argv); + + g_debug ("Can not start fallback console: %s", + strerror (errno)); + _exit (0); + } + if (server->priv->fbconsolepid == -1) { + g_debug ("Can not start fallback console"); + } +} +#endif + static char * _gdm_server_query_ck_for_display_device (GdmServer *server) { @@ -165,6 +294,10 @@ gdm_server_get_display_device (GdmServer *server) g_object_notify (G_OBJECT (server), "display-device"); } +#ifdef HAVE_FBCONSOLE + gdm_exec_fbconsole (server); +#endif + return g_strdup (server->priv->display_device); } @@ -733,6 +866,15 @@ gdm_server_stop (GdmServer *server) { int res; +#ifdef HAVE_FBCONSOLE + /* Kill fbconsole if it is running */ + if (server->priv->fbconsolepid > 0) { + g_debug ("Killing fbconsole"); + kill (server->priv->fbconsolepid, SIGTERM); + } + server->priv->fbconsolepid = 0; +#endif + if (server->priv->pid <= 1) { return TRUE; } @@ -933,6 +1075,7 @@ gdm_server_init (GdmServer *server) server->priv->pid = -1; server->priv->command = NULL; server->priv->log_dir = g_strdup (LOGDIR); + server->priv->fbconsolepid = 0; add_ready_handler (server); }