6d73dffa7d
Resolves: #1435010
293 lines
9.4 KiB
Diff
293 lines
9.4 KiB
Diff
From a40384b729b74cf935effceaa1ce9fa6b906138c Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 24 Mar 2017 23:59:30 -0400
|
|
Subject: [PATCH 2/2] session: update session search dirs when ignore-wayland
|
|
changes
|
|
|
|
Right now the first time the session search dirs are requested, they
|
|
are computed and cached. That leaves them stale if the ignore-wayland
|
|
flag changes, which breaks fallback mode in some cases.
|
|
|
|
This commit fix the problem by always computing the session search dirs
|
|
in full, with no caching.
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=780518
|
|
---
|
|
daemon/gdm-session.c | 34 +++++++++++++++++++++-------------
|
|
1 file changed, 21 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
|
index e69291f..08d61de 100644
|
|
--- a/daemon/gdm-session.c
|
|
+++ b/daemon/gdm-session.c
|
|
@@ -310,131 +310,138 @@ on_establish_credentials_cb (GdmDBusWorker *proxy,
|
|
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
return;
|
|
|
|
self = g_object_ref (conversation->session);
|
|
service_name = g_strdup (conversation->service_name);
|
|
|
|
if (worked) {
|
|
if (self->priv->user_verifier_interface != NULL) {
|
|
gdm_dbus_user_verifier_emit_verification_complete (self->priv->user_verifier_interface,
|
|
service_name);
|
|
g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name);
|
|
}
|
|
|
|
switch (self->priv->verification_mode) {
|
|
case GDM_SESSION_VERIFICATION_MODE_LOGIN:
|
|
case GDM_SESSION_VERIFICATION_MODE_CHOOSER:
|
|
gdm_session_open_session (self, service_name);
|
|
break;
|
|
case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE:
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
report_and_stop_conversation (self, service_name, error);
|
|
}
|
|
|
|
g_free (service_name);
|
|
g_object_unref (self);
|
|
}
|
|
|
|
-static const char **
|
|
+static char **
|
|
get_system_session_dirs (GdmSession *self)
|
|
{
|
|
- static GArray *search_array = NULL;
|
|
+ GArray *search_array = NULL;
|
|
+ char **search_dirs;
|
|
|
|
static const char *x_search_dirs[] = {
|
|
"/etc/X11/sessions/",
|
|
DMCONFDIR "/Sessions/",
|
|
DATADIR "/gdm/BuiltInSessions/",
|
|
DATADIR "/xsessions/",
|
|
NULL
|
|
};
|
|
|
|
static const char *wayland_search_dir = DATADIR "/wayland-sessions/";
|
|
|
|
- if (search_array == NULL) {
|
|
- search_array = g_array_new (TRUE, TRUE, sizeof (char *));
|
|
+ search_array = g_array_new (TRUE, TRUE, sizeof (char *));
|
|
|
|
- g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
|
|
+ g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
|
|
|
|
#ifdef ENABLE_WAYLAND_SUPPORT
|
|
- if (!self->priv->ignore_wayland) {
|
|
+ if (!self->priv->ignore_wayland) {
|
|
#ifdef ENABLE_USER_DISPLAY_SERVER
|
|
- g_array_prepend_val (search_array, wayland_search_dir);
|
|
+ g_array_prepend_val (search_array, wayland_search_dir);
|
|
#else
|
|
- g_array_append_val (search_array, wayland_search_dir);
|
|
-#endif
|
|
- }
|
|
+ g_array_append_val (search_array, wayland_search_dir);
|
|
#endif
|
|
}
|
|
+#endif
|
|
|
|
- return (const char **) search_array->data;
|
|
+ search_dirs = g_strdupv ((char **) search_array->data);
|
|
+
|
|
+ g_array_free (search_array, TRUE);
|
|
+
|
|
+ return search_dirs;
|
|
}
|
|
|
|
static gboolean
|
|
is_prog_in_path (const char *prog)
|
|
{
|
|
char *f;
|
|
gboolean ret;
|
|
|
|
f = g_find_program_in_path (prog);
|
|
ret = (f != NULL);
|
|
g_free (f);
|
|
return ret;
|
|
}
|
|
|
|
static GKeyFile *
|
|
load_key_file_for_file (GdmSession *self,
|
|
const char *file,
|
|
char **full_path)
|
|
{
|
|
GKeyFile *key_file;
|
|
GError *error;
|
|
gboolean res;
|
|
+ char **search_dirs;
|
|
|
|
key_file = g_key_file_new ();
|
|
|
|
+ search_dirs = get_system_session_dirs (self),
|
|
error = NULL;
|
|
res = g_key_file_load_from_dirs (key_file,
|
|
file,
|
|
- get_system_session_dirs (self),
|
|
+ (const char **) search_dirs,
|
|
full_path,
|
|
G_KEY_FILE_NONE,
|
|
&error);
|
|
if (! res) {
|
|
g_debug ("GdmSession: File '%s' not found: %s", file, error->message);
|
|
g_error_free (error);
|
|
g_key_file_free (key_file);
|
|
key_file = NULL;
|
|
}
|
|
|
|
+ g_strfreev (search_dirs);
|
|
+
|
|
return key_file;
|
|
}
|
|
|
|
static gboolean
|
|
get_session_command_for_file (GdmSession *self,
|
|
const char *file,
|
|
char **command)
|
|
{
|
|
GKeyFile *key_file;
|
|
GError *error;
|
|
char *exec;
|
|
gboolean ret;
|
|
gboolean res;
|
|
|
|
exec = NULL;
|
|
ret = FALSE;
|
|
if (command != NULL) {
|
|
*command = NULL;
|
|
}
|
|
|
|
g_debug ("GdmSession: getting session command for file '%s'", file);
|
|
key_file = load_key_file_for_file (self, file, NULL);
|
|
if (key_file == NULL) {
|
|
goto out;
|
|
}
|
|
|
|
error = NULL;
|
|
res = g_key_file_get_boolean (key_file,
|
|
G_KEY_FILE_DESKTOP_GROUP,
|
|
G_KEY_FILE_DESKTOP_KEY_HIDDEN,
|
|
@@ -494,113 +501,114 @@ get_session_command_for_name (GdmSession *self,
|
|
|
|
filename = g_strdup_printf ("%s.desktop", name);
|
|
res = get_session_command_for_file (self, filename, command);
|
|
g_free (filename);
|
|
|
|
return res;
|
|
}
|
|
|
|
static const char *
|
|
get_default_language_name (GdmSession *self)
|
|
{
|
|
const char *default_language;
|
|
|
|
if (self->priv->saved_language != NULL) {
|
|
return self->priv->saved_language;
|
|
}
|
|
|
|
default_language = g_hash_table_lookup (self->priv->environment,
|
|
"LANG");
|
|
|
|
if (default_language != NULL) {
|
|
return default_language;
|
|
}
|
|
|
|
return setlocale (LC_MESSAGES, NULL);
|
|
}
|
|
|
|
static const char *
|
|
get_fallback_session_name (GdmSession *self)
|
|
{
|
|
- const char **search_dirs;
|
|
+ char **search_dirs;
|
|
int i;
|
|
char *name;
|
|
GSequence *sessions;
|
|
GSequenceIter *session;
|
|
|
|
if (self->priv->fallback_session_name != NULL) {
|
|
/* verify that the cached version still exists */
|
|
if (get_session_command_for_name (self, self->priv->fallback_session_name, NULL)) {
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
name = g_strdup ("gnome");
|
|
if (get_session_command_for_name (self, name, NULL)) {
|
|
g_free (self->priv->fallback_session_name);
|
|
self->priv->fallback_session_name = name;
|
|
goto out;
|
|
}
|
|
g_free (name);
|
|
|
|
sessions = g_sequence_new (g_free);
|
|
|
|
search_dirs = get_system_session_dirs (self);
|
|
for (i = 0; search_dirs[i] != NULL; i++) {
|
|
GDir *dir;
|
|
const char *base_name;
|
|
|
|
dir = g_dir_open (search_dirs[i], 0, NULL);
|
|
|
|
if (dir == NULL) {
|
|
continue;
|
|
}
|
|
|
|
do {
|
|
base_name = g_dir_read_name (dir);
|
|
|
|
if (base_name == NULL) {
|
|
break;
|
|
}
|
|
|
|
if (!g_str_has_suffix (base_name, ".desktop")) {
|
|
continue;
|
|
}
|
|
|
|
if (get_session_command_for_file (self, base_name, NULL)) {
|
|
|
|
g_sequence_insert_sorted (sessions, g_strdup (base_name), (GCompareDataFunc) g_strcmp0, NULL);
|
|
}
|
|
} while (base_name != NULL);
|
|
|
|
g_dir_close (dir);
|
|
}
|
|
+ g_strfreev (search_dirs);
|
|
|
|
name = NULL;
|
|
session = g_sequence_get_begin_iter (sessions);
|
|
|
|
if (g_sequence_iter_is_end (session))
|
|
g_error ("GdmSession: no session desktop files installed, aborting...");
|
|
|
|
do {
|
|
if (g_sequence_get (session)) {
|
|
char *base_name;
|
|
|
|
g_free (name);
|
|
base_name = g_sequence_get (session);
|
|
name = g_strndup (base_name,
|
|
strlen (base_name) -
|
|
strlen (".desktop"));
|
|
|
|
break;
|
|
}
|
|
session = g_sequence_iter_next (session);
|
|
} while (!g_sequence_iter_is_end (session));
|
|
|
|
g_free (self->priv->fallback_session_name);
|
|
self->priv->fallback_session_name = name;
|
|
|
|
g_sequence_free (sessions);
|
|
|
|
out:
|
|
return self->priv->fallback_session_name;
|
|
}
|
|
--
|
|
2.10.2
|
|
|