[gdm/wip/wayland] hackity hack, sketchity sketch
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdm/wip/wayland] hackity hack, sketchity sketch
- Date: Fri, 13 Sep 2013 21:09:00 +0000 (UTC)
commit 15c32e6467093ab4cc582aa609015f10b4a4aac4
Author: Ray Strode <rstrode redhat com>
Date: Fri Sep 13 17:06:02 2013 -0400
hackity hack, sketchity sketch
This commit is a rough start at trying to get wayland sessions working
from the login screen.
It's not fully functional, but I can log in (just not log out).
daemon/gdm-session-worker-job.c | 2 +
daemon/gdm-session-worker.c | 237 +++++++++++++++++++++++++++++----------
daemon/gdm-session.c | 48 ++++++++
daemon/gdm-session.h | 1 +
daemon/gdm-simple-slave.c | 10 ++
daemon/gdm-slave.c | 1 +
6 files changed, 242 insertions(+), 57 deletions(-)
---
diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
index 557c452..7193d5d 100644
--- a/daemon/gdm-session-worker-job.c
+++ b/daemon/gdm-session-worker-job.c
@@ -86,9 +86,11 @@ static void
session_worker_job_child_setup (GdmSessionWorkerJob *session_worker_job)
{
/* Terminate the process when the parent dies */
+#if 0
#ifdef HAVE_SYS_PRCTL_H
prctl (PR_SET_PDEATHSIG, SIGTERM);
#endif
+#endif
}
static void
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 7307872..e6a725c 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -54,6 +54,10 @@
#include <systemd/sd-journal.h>
#endif
+#include <linux/vt.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
#endif /* HAVE_SELINUX */
@@ -152,6 +156,7 @@ struct GdmSessionWorkerPrivate
gboolean password_is_required;
int cred_flags;
+ int vt;
char **arguments;
guint32 cancelled : 1;
@@ -1024,11 +1029,7 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
GError **error)
{
struct pam_conv pam_conversation;
-#ifdef PAM_XAUTHDATA
- struct pam_xauth_data *pam_xauth;
-#endif
int error_code;
- char *pam_tty;
g_assert (worker->priv->pam_handle == NULL);
@@ -1089,25 +1090,6 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
}
}
- /* set TTY */
- pam_tty = _get_tty_for_pam (x11_display_name, display_device);
- if (pam_tty != NULL && pam_tty[0] != '\0') {
- error_code = pam_set_item (worker->priv->pam_handle, PAM_TTY, pam_tty);
- }
-
- if (error_code != PAM_SUCCESS) {
- g_debug ("error informing authentication system of user's console %s: %s",
- pam_tty,
- pam_strerror (worker->priv->pam_handle, error_code));
- g_free (pam_tty);
- g_set_error (error,
- GDM_SESSION_WORKER_ERROR,
- GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
- "%s", "");
- goto out;
- }
- g_free (pam_tty);
-
#ifdef WITH_SYSTEMD
/* set seat ID */
if (seat_id != NULL && seat_id[0] != '\0' && LOGIND_RUNNING()) {
@@ -1119,40 +1101,6 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
gdm_session_worker_set_environment_variable (worker, "XDG_SESSION_CLASS", "greeter");
}
-#ifdef PAM_XDISPLAY
- /* set XDISPLAY */
- error_code = pam_set_item (worker->priv->pam_handle, PAM_XDISPLAY, x11_display_name);
-
- if (error_code != PAM_SUCCESS) {
- g_debug ("error informing authentication system of display string %s: %s",
- x11_display_name,
- pam_strerror (worker->priv->pam_handle, error_code));
- g_set_error (error,
- GDM_SESSION_WORKER_ERROR,
- GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
- "%s", "");
- goto out;
- }
-#endif
-#ifdef PAM_XAUTHDATA
- /* set XAUTHDATA */
- pam_xauth = _get_xauth_for_pam (x11_authority_file);
- error_code = pam_set_item (worker->priv->pam_handle, PAM_XAUTHDATA, pam_xauth);
- if (error_code != PAM_SUCCESS) {
- g_debug ("error informing authentication system of display string %s: %s",
- x11_display_name,
- pam_strerror (worker->priv->pam_handle, error_code));
- g_free (pam_xauth);
-
- g_set_error (error,
- GDM_SESSION_WORKER_ERROR,
- GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
- "%s", "");
- goto out;
- }
- g_free (pam_xauth);
-#endif
-
g_debug ("GdmSessionWorker: state SETUP_COMPLETE");
worker->priv->state = GDM_SESSION_WORKER_STATE_SETUP_COMPLETE;
@@ -1783,6 +1731,18 @@ out:
return fd;
}
+static void
+jump_to_vt (GdmSessionWorker *worker,
+ int vt_number)
+{
+ int fd;
+
+ fd = open("/dev/tty0", O_RDWR | O_NOCTTY);
+ ioctl(fd, VT_ACTIVATE, vt_number);
+ ioctl(fd, VT_WAITACTIVE, vt_number);
+ close(fd);
+}
+
static gboolean
gdm_session_worker_start_session (GdmSessionWorker *worker,
GError **error)
@@ -1802,6 +1762,10 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
error_code = PAM_SUCCESS;
+ if (worker->priv->vt > 0) {
+ jump_to_vt (worker, worker->priv->vt);
+ }
+
session_pid = fork ();
if (session_pid < 0) {
@@ -1958,6 +1922,159 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
return TRUE;
}
+static const char **
+get_system_session_dirs (void)
+{
+ static const char *search_dirs[] = {
+ "/etc/X11/sessions/",
+ DMCONFDIR "/Sessions/",
+ DATADIR "/xsessions/",
+ DATADIR "/gdm/BuiltInSessions/",
+ NULL
+ };
+
+ return search_dirs;
+}
+
+static gboolean
+gdm_session_worker_needs_vt (GdmSessionWorker *worker)
+{
+ GError *error;
+ GKeyFile *key_file;
+ gboolean res;
+ gboolean needs_vt = FALSE;
+ char *session_name, *filename;
+
+ session_name = gdm_session_settings_get_session_name (worker->priv->user_settings);
+ filename = g_strdup_printf ("%s.desktop", session_name);
+ g_free (session_name);
+
+ key_file = g_key_file_new ();
+ error = NULL;
+ res = g_key_file_load_from_dirs (key_file,
+ filename,
+ get_system_session_dirs (),
+ NULL,
+ G_KEY_FILE_NONE,
+ &error);
+ if (! res) {
+ g_debug ("GdmSession: File '%s' not found: %s", filename, error->message);
+ goto out;
+ }
+
+ error = NULL;
+ res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-NeedsVT", NULL);
+ if (!res) {
+ goto out;
+ } else {
+ needs_vt = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-NeedsVT",
&error);
+ if (error) {
+ needs_vt = FALSE;
+ g_error_free (error);
+ goto out;
+ }
+ if (needs_vt) {
+ g_debug ("GdmSession: Session %s needs VT", filename);
+ }
+ }
+
+out:
+ g_free (filename);
+ return needs_vt;
+}
+
+static gboolean
+set_up_for_new_vt (GdmSessionWorker *worker,
+ GError **error)
+{
+ int fd;
+ char vt_string[256] = "", tty_string[256] = "";
+ int vt_number = 0;
+
+ fd = open("/dev/tty0", O_RDWR | O_NOCTTY);
+ ioctl(fd, VT_OPENQRY, &vt_number);
+ worker->priv->vt = vt_number;
+ close(fd);
+
+ g_snprintf(vt_string, 256, "%d", vt_number);
+ g_snprintf(tty_string, 256, "tty%d", vt_number);
+
+ gdm_session_worker_set_environment_variable (worker,
+ "XDG_VTNR",
+ vt_string);
+
+ pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string);
+
+ return TRUE;
+}
+
+static gboolean
+set_up_for_current_vt (GdmSessionWorker *worker,
+ GError **error)
+{
+#ifdef PAM_XAUTHDATA
+ struct pam_xauth_data *pam_xauth;
+#endif
+ int error_code;
+ char *pam_tty;
+
+ /* set TTY */
+ pam_tty = _get_tty_for_pam (worker->priv->x11_display_name, worker->priv->display_device);
+ if (pam_tty != NULL && pam_tty[0] != '\0') {
+ error_code = pam_set_item (worker->priv->pam_handle, PAM_TTY, pam_tty);
+ }
+
+ if (error_code != PAM_SUCCESS) {
+ g_debug ("error informing authentication system of user's console %s: %s",
+ pam_tty,
+ pam_strerror (worker->priv->pam_handle, error_code));
+ g_free (pam_tty);
+ g_set_error (error,
+ GDM_SESSION_WORKER_ERROR,
+ GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
+ "%s", "");
+ goto out;
+ }
+ g_free (pam_tty);
+
+#ifdef PAM_XDISPLAY
+ /* set XDISPLAY */
+ error_code = pam_set_item (worker->priv->pam_handle, PAM_XDISPLAY, worker->priv->x11_display_name);
+
+ if (error_code != PAM_SUCCESS) {
+ g_debug ("error informing authentication system of display string %s: %s",
+ worker->priv->x11_display_name,
+ pam_strerror (worker->priv->pam_handle, error_code));
+ g_set_error (error,
+ GDM_SESSION_WORKER_ERROR,
+ GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
+ "%s", "");
+ goto out;
+ }
+#endif
+#ifdef PAM_XAUTHDATA
+ /* set XAUTHDATA */
+ pam_xauth = _get_xauth_for_pam (worker->priv->x11_authority_file);
+ error_code = pam_set_item (worker->priv->pam_handle, PAM_XAUTHDATA, pam_xauth);
+ if (error_code != PAM_SUCCESS) {
+ g_debug ("error informing authentication system of display string %s: %s",
+ worker->priv->x11_display_name,
+ pam_strerror (worker->priv->pam_handle, error_code));
+ g_free (pam_xauth);
+
+ g_set_error (error,
+ GDM_SESSION_WORKER_ERROR,
+ GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
+ "%s", "");
+ goto out;
+ }
+ g_free (pam_xauth);
+#endif
+ return TRUE;
+out:
+ return FALSE;
+}
+
static gboolean
gdm_session_worker_open_session (GdmSessionWorker *worker,
GError **error)
@@ -1969,6 +2086,12 @@ gdm_session_worker_open_session (GdmSessionWorker *worker,
g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED);
g_assert (geteuid () == 0);
+ if (gdm_session_worker_needs_vt (worker)) {
+ set_up_for_new_vt (worker, NULL);
+ } else {
+ set_up_for_current_vt (worker, NULL);
+ }
+
flags = 0;
if (worker->priv->is_program_session) {
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index d74bed6..c9b9440 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -2719,6 +2719,54 @@ out:
return bypasses_xsession;
}
+gboolean
+gdm_session_needs_vt (GdmSession *self)
+{
+ GError *error;
+ GKeyFile *key_file;
+ gboolean res;
+ gboolean needs_vt = FALSE;
+ char *filename;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
+
+ filename = g_strdup_printf ("%s.desktop", get_session_name (self));
+
+ key_file = g_key_file_new ();
+ error = NULL;
+ res = g_key_file_load_from_dirs (key_file,
+ filename,
+ get_system_session_dirs (),
+ NULL,
+ G_KEY_FILE_NONE,
+ &error);
+ if (! res) {
+ g_debug ("GdmSession: File '%s' not found: %s", filename, error->message);
+ goto out;
+ }
+
+ error = NULL;
+ res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-NeedsVT", NULL);
+ if (!res) {
+ goto out;
+ } else {
+ needs_vt = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-NeedsVT",
&error);
+ if (error) {
+ needs_vt = FALSE;
+ g_error_free (error);
+ goto out;
+ }
+ if (needs_vt) {
+ g_debug ("GdmSession: Session %s runs on its own VT", filename);
+ }
+ }
+
+out:
+ g_free (filename);
+ return needs_vt;
+}
+
void
gdm_session_select_program (GdmSession *self,
const char *text)
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index 2511eca..3af06c1 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -110,6 +110,7 @@ char *gdm_session_get_display_device (GdmSession *sessi
char *gdm_session_get_display_seat_id (GdmSession *session);
char *gdm_session_get_session_id (GdmSession *session);
gboolean gdm_session_bypasses_xsession (GdmSession *session);
+gboolean gdm_session_needs_vt (GdmSession *self);
void gdm_session_start_conversation (GdmSession *session,
const char *service_name);
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 217c33b..e74d38b 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -129,6 +129,7 @@ static void create_new_session (GdmSimpleSlave *slave);
static void start_session (GdmSimpleSlave *slave);
static void queue_start_session (GdmSimpleSlave *slave,
const char *service_name);
+static void setup_session (GdmSimpleSlave *slave);
static gboolean
chown_file (GFile *file,
@@ -519,10 +520,16 @@ static gboolean
start_session_timeout (GdmSimpleSlave *slave)
{
gboolean migrated;
+ gboolean needs_vt;
gboolean fail_if_already_switched = TRUE;
g_debug ("GdmSimpleSlave: accredited");
+ needs_vt = gdm_session_needs_vt (slave->priv->session);
+ if (needs_vt) {
+ fail_if_already_switched = FALSE;
+ }
+
/* If there's already a session running, jump to it.
* If the only session running is the one we just opened,
* start a session on it.
@@ -537,6 +544,7 @@ start_session_timeout (GdmSimpleSlave *slave)
when Xorg exits it switches to the VT it was
started from. That interferes with fast
user switching. */
+ // WAYLAND FIXME: we need to disown the session and create a new one
gdm_session_reset (slave->priv->session);
slave->priv->start_session_id = 0;
@@ -969,6 +977,7 @@ create_new_session (GdmSimpleSlave *slave)
"session-started",
G_CALLBACK (on_session_started),
slave);
+#if 0
g_signal_connect (slave->priv->session,
"session-exited",
G_CALLBACK (on_session_exited),
@@ -977,6 +986,7 @@ create_new_session (GdmSimpleSlave *slave)
"session-died",
G_CALLBACK (on_session_died),
slave);
+#endif
start_autologin_conversation_if_necessary (slave);
diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
index 128a800..3636b68 100644
--- a/daemon/gdm-slave.c
+++ b/daemon/gdm-slave.c
@@ -1264,6 +1264,7 @@ gdm_slave_get_primary_session_id_for_user_from_systemd (GdmSlave *slave,
continue;
}
+ /* WAYLAND FIXME: WE CAN"T FILTER OUT X11 session here unless we can make wayland show up
as an X11 session */
is_x11 = g_strcmp0 (type, "x11") == 0;
free (type);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]