commit c7791f293660c22fd699020ff1ec1ac83ad94afa
Author: Halton Huo <halton.huo@sun.com>
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 <glib/gstdio.h>
#include <glib-object.h>
+#ifdef HAVE_FBCONSOLE
+#ifdef HAVE_SYS_VT_H
+#include <sys/vt.h>
+#endif
+#endif
+
#include <dbus/dbus-glib.h>
#include <X11/Xlib.h> /* 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);
}