]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - src/greeter.c
Allow in-session greeters to reconnect
[sojka/lightdm.git] / src / greeter.c
index 72eaa2e7dc57668b1c131de3206bb39b14e61f83..e2ae19f9d1bff02e07981f522da98fa729ae8e8d 100644 (file)
@@ -12,8 +12,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <errno.h>
-#include <fcntl.h>
 #include <gcrypt.h>
 
 #include "greeter.h"
@@ -27,6 +25,7 @@ enum {
 
 enum {
     CONNECTED,
+    DISCONNECTED,  
     CREATE_SESSION,
     START_SESSION,
     LAST_SIGNAL
@@ -118,29 +117,22 @@ greeter_new (void)
     return g_object_new (GREETER_TYPE, NULL);
 }
 
-gboolean
-greeter_start (Greeter *greeter, gboolean (*setup_child_cb)(Greeter *greeter, int input_fd, int output_fd, gpointer user_data), gpointer user_data)
+void
+greeter_set_file_descriptors (Greeter *greeter, int to_greeter_fd, int from_greeter_fd)
 {
-    int to_greeter_pipe[2], from_greeter_pipe[2];
-    int to_greeter_output, from_greeter_input;
-    gboolean result;
     GError *error = NULL;
 
-    /* Create a pipe to talk with the greeter */
-    if (pipe (to_greeter_pipe) != 0 || pipe (from_greeter_pipe) != 0)
-    {
-        g_warning ("Failed to create pipes: %s", strerror (errno));
-        return FALSE;
-    }
-    to_greeter_output = to_greeter_pipe[0];
-    greeter->priv->to_greeter_input = to_greeter_pipe[1];
+    g_return_if_fail (greeter != NULL);
+    g_return_if_fail (greeter->priv->to_greeter_input < 0);
+    g_return_if_fail (greeter->priv->from_greeter_output < 0);
+
+    greeter->priv->to_greeter_input = to_greeter_fd;  
     greeter->priv->to_greeter_channel = g_io_channel_unix_new (greeter->priv->to_greeter_input);
     g_io_channel_set_encoding (greeter->priv->to_greeter_channel, NULL, &error);
     if (error)
         g_warning ("Failed to set encoding on to greeter channel to binary: %s\n", error->message);
     g_clear_error (&error);
-    greeter->priv->from_greeter_output = from_greeter_pipe[0];
-    from_greeter_input = from_greeter_pipe[1];
+    greeter->priv->from_greeter_output = from_greeter_fd;
     greeter->priv->from_greeter_channel = g_io_channel_unix_new (greeter->priv->from_greeter_output);
     g_io_channel_set_encoding (greeter->priv->from_greeter_channel, NULL, &error);
     if (error)
@@ -148,18 +140,6 @@ greeter_start (Greeter *greeter, gboolean (*setup_child_cb)(Greeter *greeter, in
     g_clear_error (&error);
     g_io_channel_set_buffered (greeter->priv->from_greeter_channel, FALSE);
     greeter->priv->from_greeter_watch = g_io_add_watch (greeter->priv->from_greeter_channel, G_IO_IN | G_IO_HUP, read_cb, greeter);
-
-    /* Don't allow the daemon end of the pipes to be accessed in child processes */
-    fcntl (greeter->priv->to_greeter_input, F_SETFD, FD_CLOEXEC);
-    fcntl (greeter->priv->from_greeter_output, F_SETFD, FD_CLOEXEC);
-
-    result = setup_child_cb (greeter, from_greeter_input, to_greeter_output, user_data);
-
-    /* Close the session ends of the pipe */
-    close (from_greeter_input);
-    close (to_greeter_output);
-
-    return result;
 }
 
 void
@@ -857,6 +837,7 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
     {
         g_debug ("Greeter closed communication channel");
         greeter->priv->from_greeter_watch = 0;
+        g_signal_emit (greeter, signals[DISCONNECTED], 0);
         return FALSE;
     }
 
@@ -879,7 +860,14 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
     if (error)
         g_warning ("Error reading from greeter: %s", error->message);
     g_clear_error (&error);
-    if (status != G_IO_STATUS_NORMAL)
+    if (status == G_IO_STATUS_EOF)
+    {
+        g_debug ("Greeter closed communication channel");
+        greeter->priv->from_greeter_watch = 0;
+        g_signal_emit (greeter, signals[DISCONNECTED], 0);
+        return FALSE;
+    }
+    else if (status != G_IO_STATUS_NORMAL)
         return TRUE;
 
     greeter->priv->n_read += n_read;
@@ -1105,6 +1093,15 @@ greeter_class_init (GreeterClass *klass)
                       NULL,
                       G_TYPE_NONE, 0);
 
+    signals[DISCONNECTED] =
+        g_signal_new (GREETER_SIGNAL_DISCONNECTED,
+                      G_TYPE_FROM_CLASS (klass),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (GreeterClass, disconnected),
+                      NULL, NULL,
+                      NULL,
+                      G_TYPE_NONE, 0);
+
     signals[CREATE_SESSION] =
         g_signal_new (GREETER_SIGNAL_CREATE_SESSION,
                       G_TYPE_FROM_CLASS (klass),