]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Merge with trunk
authorRobert Ancell <robert.ancell@canonical.com>
Tue, 9 Jul 2013 04:07:14 +0000 (16:07 +1200)
committerRobert Ancell <robert.ancell@canonical.com>
Tue, 9 Jul 2013 04:07:14 +0000 (16:07 +1200)
19 files changed:
data/lightdm.conf
src/display.c
src/display.h
src/ldm-marshal.list
src/lightdm.c
src/seat-unity.c
src/seat-xdmcp-session.c
src/seat-xlocal.c
src/seat-xremote.c
src/seat-xvnc.c
src/seat.c
src/seat.h
src/session.c
src/session.h
src/xsession.c
src/xsession.h
tests/Makefile.am
tests/scripts/xserver-no-share.conf [new file with mode: 0644]
tests/test-xserver-no-share [new file with mode: 0755]

index 3934f8cfbdcc703d41f971af7b663493588b2894..20148a02dc7ee3fa2888a9c96632fbba4d3d758f 100644 (file)
@@ -40,6 +40,7 @@
 # xserver-layout = Layout to pass to X server
 # xserver-config = Config file to pass to X server
 # xserver-allow-tcp = True if TCP/IP connections are allowed to this X server
+# xserver-share = True if the X server is shared for both greeter and session
 # xdmcp-manager = XDMCP manager to connect to (implies xserver-allow-tcp=true)
 # xdmcp-port = XDMCP UDP/IP port to communicate on
 # xdmcp-key = Authentication key to use for XDM-AUTHENTICATION-1 (stored in keys.conf)
@@ -72,6 +73,7 @@
 #xserver-layout=
 #xserver-config=
 #xserver-allow-tcp=false
+#xserver-share=true
 #xdmcp-manager=
 #xdmcp-port=177
 #xdmcp-key=
index 9034a5892937bdaa30c963a65086d57b8ccd05b9..f849a60e0a6e1f760de6bf0b0f44c6ada5fd130b 100644 (file)
@@ -30,6 +30,7 @@ enum
     DISPLAY_SERVER_READY,
     START_GREETER,
     START_SESSION,
+    CREATE_DISPLAY,
     STOPPED,
     LAST_SIGNAL
 };
@@ -40,6 +41,9 @@ struct DisplayPrivate
     /* Display server */
     DisplayServer *display_server;
 
+    /* TRUE if the session can run on the same display server as the greeter */
+    gboolean share_display_server;
+
     /* Greeter session */
     gchar *greeter_session;
 
@@ -133,6 +137,13 @@ display_get_display_server (Display *display)
     return display->priv->display_server;
 }
 
+void
+display_set_share_display_server (Display *display, gboolean share_display_server)
+{
+    g_return_if_fail (display != NULL);
+    display->priv->share_display_server = share_display_server;
+}
+
 const gchar *
 display_get_username (Display *display)
 {
@@ -288,6 +299,7 @@ create_session (Display *display)
     g_signal_emit (display, signals[CREATE_SESSION], 0, &session);
     if (!session)
         return NULL;
+    session_set_display_server (session, display->priv->display_server);
 
     /* Connect using the session bus */
     if (getuid () != 0)
@@ -367,6 +379,16 @@ greeter_start_authentication_cb (Greeter *greeter, const gchar *username, Displa
     return create_session (display);
 }
 
+static Display *
+create_display (Display *display, Session *session)
+{
+    Display *d;
+
+    g_signal_emit (display, signals[CREATE_DISPLAY], 0, session, &d);
+
+    return d;
+}
+
 static gboolean
 greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *session_name, Display *display)
 {
@@ -402,9 +424,14 @@ greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *sessi
             return TRUE;
     }
 
-    /* Stop the greeter, the session will start when the greeter has quit */
-    g_debug ("Stopping greeter");
-    session_stop (display->priv->session);
+    /* If we can re-use this display server, then stop the greeter and start the session when it is done */
+    if (display->priv->share_display_server)
+    {
+        g_debug ("Stopping greeter");
+        session_stop (display->priv->session);
+    }
+    else
+        create_display (display, greeter_get_authentication_session (greeter));
 
     return TRUE;
 }
@@ -799,6 +826,14 @@ display_server_ready_cb (DisplayServer *display_server, Display *display)
         return;
     }
 
+    /* If already have a session, run it */
+    if (display->priv->session != NULL)
+    {
+        if (display_start_session (display))
+            display_stop (display);
+        return;
+    }
+
     /* Don't run any sessions on local terminals */
     if (!display_server_get_start_local_sessions (display_server))
         return;
@@ -847,6 +882,19 @@ display_start (Display *display)
     return TRUE;
 }
 
+gboolean
+display_start_with_session (Display *display, Session *session)
+{
+    g_return_val_if_fail (display != NULL, FALSE);
+    g_return_val_if_fail (session != NULL, FALSE);
+
+    display->priv->session = g_object_ref (session);
+    g_signal_connect_after (display->priv->session, "stopped", G_CALLBACK (user_session_stopped_cb), display);
+    session_set_display_server (session, display->priv->display_server);
+
+    return display_start (display);
+}
+
 gboolean
 display_get_is_ready (Display *display)
 {
@@ -938,6 +986,12 @@ display_real_get_guest_username (Display *display)
     return NULL;
 }
 
+static Display *
+display_real_create_display (Display *display, Session *session)
+{
+    return NULL;
+}
+
 static void
 display_init (Display *display)
 {
@@ -983,6 +1037,7 @@ display_class_init (DisplayClass *klass)
     klass->get_guest_username = display_real_get_guest_username;
     klass->start_greeter = display_start_greeter;
     klass->start_session = display_start_session;
+    klass->create_display = display_real_create_display;
     object_class->finalize = display_finalize;
 
     g_type_class_add_private (klass, sizeof (DisplayPrivate));
@@ -1054,6 +1109,14 @@ display_class_init (DisplayClass *klass)
                       g_signal_accumulator_true_handled, NULL,
                       ldm_marshal_BOOLEAN__VOID,
                       G_TYPE_BOOLEAN, 0);
+    signals[CREATE_DISPLAY] =
+        g_signal_new ("create-display",
+                      G_TYPE_FROM_CLASS (klass),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (DisplayClass, create_display),
+                      NULL, NULL,
+                      ldm_marshal_OBJECT__OBJECT,
+                      DISPLAY_TYPE, 1, SESSION_TYPE);
     signals[STOPPED] =
         g_signal_new ("stopped",
                       G_TYPE_FROM_CLASS (klass),
index 73efc0164601c49dc2212cae1dc58145e8870678..dff397a36dbd8dc1a3aa349f9f03d9e215c00d9e 100644 (file)
@@ -44,6 +44,7 @@ typedef struct
     void (*ready)(Display *display);
     gboolean (*switch_to_user)(Display *display, User *user);
     gboolean (*switch_to_guest)(Display *display);
+    Display *(*create_display)(Display *display, Session *session);
     gchar *(*get_guest_username)(Display *display);
     void (*stopped)(Display *display);
 } DisplayClass;
@@ -54,6 +55,8 @@ Display *display_new (DisplayServer *display_server);
 
 DisplayServer *display_get_display_server (Display *display);
 
+void display_set_share_display_server (Display *display, gboolean share_display_server);
+
 const gchar *display_get_username (Display *display);
 
 Session *display_get_session (Display *display);
@@ -84,6 +87,8 @@ void display_set_user_session (Display *display, SessionType type, const gchar *
 
 gboolean display_start (Display *display);
 
+gboolean display_start_with_session (Display *display, Session *session);
+
 gboolean display_get_is_ready (Display *display);
 
 void display_lock (Display *display);
index 9be211acee8a4341004efabea8d24fc8e6c6a9fb..4edb9616bc48738188ead19e2683dfb8e2a659e6 100644 (file)
@@ -5,3 +5,4 @@ BOOLEAN:OBJECT
 STRING:VOID
 OBJECT:VOID
 OBJECT:STRING
+OBJECT:OBJECT
index 9ca9874658011e9c8913572222c9cc42ee3197c8..fba6f7aad1ffe470f6b37ea683a1a1b36c9cdaa4 100644 (file)
@@ -1040,6 +1040,8 @@ main (int argc, char **argv)
         config_set_string (config_get_instance (), "SeatDefaults", "type", "xlocal");
     if (!config_has_key (config_get_instance (), "SeatDefaults", "xserver-command"))
         config_set_string (config_get_instance (), "SeatDefaults", "xserver-command", "X");
+    if (!config_has_key (config_get_instance (), "SeatDefaults", "xserver-share"))
+        config_set_boolean (config_get_instance (), "SeatDefaults", "xserver-share", TRUE);
     if (!config_has_key (config_get_instance (), "SeatDefaults", "unity-compositor-command"))
         config_set_string (config_get_instance (), "SeatDefaults", "unity-compositor-command", "unity-system-compositor");
     if (!config_has_key (config_get_instance (), "SeatDefaults", "start-session"))
index 88d4d0c269d8194a522e8eeb3734eb63ac04dade..6f4b15e092cc470b11e6d9b466a168c5a24e4f49 100644 (file)
@@ -474,7 +474,7 @@ seat_unity_create_session (Seat *seat, Display *display)
     else
         vt_number = SEAT_UNITY (seat)->priv->vt;
 
-    session = xsession_new (XSERVER (xserver));
+    session = xsession_new ();
     t = g_strdup_printf ("/dev/tty%d", vt_number);
     session_set_tty (SESSION (session), t);
     g_free (t);
index 84ad8d47c6fb521828db162c271d5a104561b737..72d6a8cee525d6178437346c5aa736634ebcfb87 100644 (file)
@@ -57,7 +57,7 @@ seat_xdmcp_session_create_session (Seat *seat, Display *display)
 
     xserver = XSERVER_REMOTE (display_get_display_server (display));
 
-    session = xsession_new (XSERVER (xserver));
+    session = xsession_new ();
     session_set_remote_host_name (SESSION (session), xserver_get_hostname (XSERVER (xserver)));
 
     return SESSION (session);
index d1c240c47e6679c18225a38ab42226ae7d8ab74c..e1e5cca8261a9222ab62170c0089efac21fce8ef 100644 (file)
@@ -23,6 +23,7 @@ static void
 seat_xlocal_setup (Seat *seat)
 {
     seat_set_can_switch (seat, TRUE);
+    seat_set_share_display_server (seat, seat_get_boolean_property (seat, "xserver-share"));
     SEAT_CLASS (seat_xlocal_parent_class)->setup (seat);
 }
 
@@ -113,7 +114,7 @@ seat_xlocal_create_session (Seat *seat, Display *display)
 
     xserver = XSERVER_LOCAL (display_get_display_server (display));
 
-    session = xsession_new (XSERVER (xserver));
+    session = xsession_new ();
     t = g_strdup_printf ("/dev/tty%d", xserver_local_get_vt (xserver));
     session_set_tty (SESSION (session), t);
     g_free (t);
index e6e999d8fc4669a9f86383e4a65fa5fb0f90148b..888ea122e2b39f3a599f7ec5cedc02015eba9574 100644 (file)
@@ -52,7 +52,7 @@ seat_xremote_create_session (Seat *seat, Display *display)
 
     xserver = XSERVER_REMOTE (display_get_display_server (display));
 
-    session = xsession_new (XSERVER (xserver));
+    session = xsession_new ();
     session_set_remote_host_name (SESSION (session), xserver_get_hostname (XSERVER (xserver)));
 
     return SESSION (session);
index c063a3c6c07f98fa1c8c9c0daba2410f85a8878c..2e126f3a0a757f81154462c5d0559751ddee5f66 100644 (file)
@@ -76,7 +76,7 @@ seat_xvnc_create_session (Seat *seat, Display *display)
 
     xserver = XSERVER_XVNC (display_get_display_server (display));
 
-    session = xsession_new (XSERVER (xserver));
+    session = xsession_new ();
     address = G_INET_SOCKET_ADDRESS (g_socket_get_remote_address (SEAT_XVNC (seat)->priv->connection, NULL));
     hostname = g_inet_address_to_string (g_inet_socket_address_get_address (address));
     session_set_remote_host_name (SESSION (session), hostname);
index c6250c9cdc6016d88e4e91fef1d2eca2a093293d..77dbec6e2d87560660060687d1c47c724eac61f5 100644 (file)
@@ -32,6 +32,9 @@ struct SeatPrivate
     /* TRUE if able to switch users */
     gboolean can_switch;
 
+    /* TRUE if display server can be shared for sessions */
+    gboolean share_display_server;
+
     /* Name of guest account */
     gchar *guest_username;
 
@@ -54,6 +57,8 @@ typedef struct
 } SeatModule;
 static GHashTable *seat_modules = NULL;
 
+static Display *create_display (Seat *seat);
+
 void
 seat_register_module (const gchar *name, GType type)
 {
@@ -132,6 +137,14 @@ seat_set_can_switch (Seat *seat, gboolean can_switch)
     seat->priv->can_switch = can_switch;
 }
 
+void
+seat_set_share_display_server (Seat *seat, gboolean share_display_server)
+{
+    g_return_if_fail (seat != NULL);
+
+    seat->priv->share_display_server = share_display_server;
+}
+
 gboolean
 seat_start (Seat *seat)
 {
@@ -409,6 +422,20 @@ display_ready_cb (Display *display, Seat *seat)
     SEAT_GET_CLASS (seat)->set_active_display (seat, display);
 }
 
+static Display *
+display_create_display_cb (Display *display, Session *session, Seat *seat)
+{
+    Display *d;
+
+    d = create_display (seat);
+    g_signal_connect (d, "ready", G_CALLBACK (display_ready_cb), seat);
+    g_signal_emit (seat, signals[DISPLAY_ADDED], 0, d);
+
+    display_start_with_session (d, session);
+
+    return g_object_ref (d);
+}
+
 static void
 check_stopped (Seat *seat)
 {
@@ -492,6 +519,7 @@ create_display (Seat *seat)
     g_signal_connect (display, "start-greeter", G_CALLBACK (display_start_greeter_cb), seat);
     g_signal_connect (display, "start-session", G_CALLBACK (display_start_session_cb), seat);
     g_signal_connect_after (display, "start-session", G_CALLBACK (display_session_started_cb), seat);
+    g_signal_connect (display, "create-display", G_CALLBACK (display_create_display_cb), seat);
     g_signal_connect (display, "stopped", G_CALLBACK (display_stopped_cb), seat);
     display_set_greeter_session (display, seat_get_string_property (seat, "greeter-session"));
     display_set_session_wrapper (display, seat_get_string_property (seat, "session-wrapper"));
@@ -502,6 +530,7 @@ create_display (Seat *seat)
     display_set_allow_guest (display, seat_get_allow_guest (seat));
     display_set_greeter_allow_guest (display, seat_get_greeter_allow_guest (seat));
     display_set_user_session (display, SESSION_TYPE_LOCAL, seat_get_string_property (seat, "user-session"));
+    display_set_share_display_server (display, seat->priv->share_display_server);
 
     seat->priv->displays = g_list_append (seat->priv->displays, display);
 
@@ -779,6 +808,7 @@ seat_init (Seat *seat)
 {
     seat->priv = G_TYPE_INSTANCE_GET_PRIVATE (seat, SEAT_TYPE, SeatPrivate);
     seat->priv->properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+    seat->priv->share_display_server = TRUE;
 }
 
 static void
index 5ca0e3e4bb2e32d403cf879ed2ba4728e9c47273..0c2f3ccf1d1c2c8dfb396c654c3c864b316d6b80 100644 (file)
@@ -67,6 +67,8 @@ gint seat_get_integer_property (Seat *seat, const gchar *name);
 
 void seat_set_can_switch (Seat *seat, gboolean can_switch);
 
+void seat_set_share_display_server (Seat *seat, gboolean share_display_server);
+
 gboolean seat_start (Seat *seat);
 
 GList *seat_get_displays (Seat *seat);
index 1b877ad598cf5b08a46e5ebe891277ccb627f434..b778c4c408325efef1b44971a6fde297306b82ff 100644 (file)
@@ -37,6 +37,9 @@ static guint signals[LAST_SIGNAL] = { 0 };
 
 struct SessionPrivate
 {
+    /* Display server running on */
+    DisplayServer *display_server;
+
     /* PID of child process */
     GPid pid;
 
@@ -114,6 +117,22 @@ session_set_class (Session *session, const gchar *class)
     session->priv->class = g_strdup (class);
 }
 
+static void
+session_real_set_display_server (Session *session, DisplayServer *display_server)
+{
+    if (session->priv->display_server)
+        g_object_unref (session->priv->display_server);
+    session->priv->display_server = g_object_ref (display_server);
+}
+
+void
+session_set_display_server (Session *session, DisplayServer *display_server)
+{
+    g_return_if_fail (session != NULL);
+    g_return_if_fail (display_server != NULL);
+    SESSION_GET_CLASS (session)->set_display_server (session, display_server);
+}
+
 void
 session_set_tty (Session *session, const gchar *tty)
 {
@@ -629,6 +648,8 @@ session_finalize (GObject *object)
     Session *self = SESSION (object);
     int i;
 
+    if (self->priv->display_server)
+        g_object_unref (self->priv->display_server);
     if (self->priv->pid)
         kill (self->priv->pid, SIGKILL);
     if (self->priv->from_child_channel)
@@ -663,6 +684,7 @@ session_class_init (SessionClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+    klass->set_display_server = session_real_set_display_server;
     object_class->finalize = session_finalize;
 
     g_type_class_add_private (klass, sizeof (SessionPrivate));
index c3523b1ebe5067461289d07c6e11eecd614791bd..6d5640c99988eae651e3c60ab807e9607ef8f6f8 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <security/pam_appl.h>
 
+#include "display-server.h"
 #include "accounts.h"
 #include "xauthority.h"
 
@@ -41,6 +42,7 @@ typedef struct
     void (*got_messages)(Session *session);
     void (*authentication_complete)(Session *session);
     void (*stopped)(Session *session);
+    void (*set_display_server)(Session *session, DisplayServer *display_server);
 } SessionClass;
 
 typedef enum
@@ -59,6 +61,8 @@ void session_set_log_file (Session *session, const gchar *filename);
 
 void session_set_class (Session *session, const gchar *class);
 
+void session_set_display_server (Session *session, DisplayServer *display_server);
+
 void session_set_tty (Session *session, const gchar *tty);
 
 void session_set_xdisplay (Session *session, const gchar *xdisplay);
index 0c0b99dfd42ecd4539e7ea2d7b903311695bac27..4ed255c6ee0c4afdd34ee2458a050c20e38feece 100644 (file)
@@ -27,50 +27,46 @@ struct XSessionPrivate
 G_DEFINE_TYPE (XSession, xsession, SESSION_TYPE);
 
 XSession *
-xsession_new (XServer *xserver)
+xsession_new (void)
 {
     XSession *session;
-    XAuthority *authority;
 
     session = g_object_new (XSESSION_TYPE, NULL);
-    session->priv->xserver = g_object_ref (xserver);
-
-    session_set_env (SESSION (session), "DISPLAY", xserver_get_address (xserver));
-    session_set_tty (SESSION (session), xserver_get_address (xserver));
-    session_set_xdisplay (SESSION (session), xserver_get_address (xserver));
-    authority = xserver_get_authority (xserver);
-    if (authority)
-        session_set_xauthority (SESSION (session), authority, config_get_boolean (config_get_instance (), "LightDM", "user-authority-in-system-dir"));
     session_set_log_file (SESSION (session), ".xsession-errors");
-
+  
     return session;
 }
 
 static void
-xsession_init (XSession *session)
+xsession_set_display_server (Session *session, DisplayServer *display_server)
 {
-    session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session, XSESSION_TYPE, XSessionPrivate);
-}
+    XServer *xserver;
+    XAuthority *authority;
 
-static void
-xsession_finalize (GObject *object)
-{
-    XSession *self;
+    xserver = XSERVER (display_server);
 
-    self = XSESSION (object);
+    session_set_env (session, "DISPLAY", xserver_get_address (xserver));
+    session_set_tty (session, xserver_get_address (xserver)); // FIXME: This is applied before authentication, it needs to be resent before the process it run
+    session_set_xdisplay (session, xserver_get_address (xserver)); // FIXME: This is applied before authentication, it needs to be resent before the process it run
+    authority = xserver_get_authority (xserver); // FIXME: This is applied before authentication, it needs to be resent before the process it run
+    if (authority)
+        session_set_xauthority (session, authority, config_get_boolean (config_get_instance (), "LightDM", "user-authority-in-system-dir"));
 
-    if (self->priv->xserver)
-        g_object_unref (self->priv->xserver);
+    SESSION_CLASS (xsession_parent_class)->set_display_server (session, display_server);
+}
 
-    G_OBJECT_CLASS (xsession_parent_class)->finalize (object);
+static void
+xsession_init (XSession *session)
+{
+    session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session, XSESSION_TYPE, XSessionPrivate);
 }
 
 static void
 xsession_class_init (XSessionClass *klass)
 {
-    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    SessionClass *session_class = SESSION_CLASS (klass);
 
-    object_class->finalize = xsession_finalize;
+    session_class->set_display_server = xsession_set_display_server;
 
     g_type_class_add_private (klass, sizeof (XSessionPrivate));
 }
index f6b9530a39f67c1fc7985ffb9e961ff73b7de59d..4e759c60568cd4db81821c9255725aeaa998d339 100644 (file)
@@ -35,7 +35,7 @@ typedef struct
 
 GType xsession_get_type (void);
 
-XSession *xsession_new (XServer *xserver);
+XSession *xsession_new (void);
 
 G_END_DECLS
 
index e7efbfe583789f068276a2a43322797668a304ad..67dd342ce1798f37d004931b444ca8996dff67d9 100644 (file)
@@ -106,6 +106,7 @@ TESTS = \
        test-login-python-remote-session \
        test-login-session-crash \
        test-login-xserver-crash \
+       test-xserver-no-share \
        test-home-dir-on-authenticate \
        test-home-dir-on-session \
        test-plymouth-active-vt \
@@ -374,4 +375,5 @@ EXTRA_DIST = \
        scripts/xauthority.conf \
        scripts/xdmcp-login.conf \
        scripts/xdmcp-open-file-descriptors.conf \
-       scripts/xserver-fail-start.conf
+       scripts/xserver-fail-start.conf \
+       scripts/xserver-no-share.conf
diff --git a/tests/scripts/xserver-no-share.conf b/tests/scripts/xserver-no-share.conf
new file mode 100644 (file)
index 0000000..c62fdf2
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# Check can configure a new X server to start for the session
+#
+
+[SeatDefaults]
+user-session=default
+xserver-share=false
+
+#?RUNNER DAEMON-START
+
+# X server starts
+#?XSERVER-0 START VT=7
+#?XSERVER-0 INDICATE-READY
+#?XSERVER-0 ACCEPT-CONNECT
+
+# Greeter starts
+#?GREETER-X-0 START
+#?XSERVER-0 ACCEPT-CONNECT
+#?GREETER-X-0 CONNECT-XSERVER
+#?GREETER-X-0 CONNECT-TO-DAEMON
+#?GREETER-X-0 CONNECTED-TO-DAEMON
+
+# Log into account with a password
+#?*GREETER-X-0 AUTHENTICATE USERNAME=have-password1
+#?GREETER-X-0 SHOW-PROMPT TEXT="Password:"
+#?*GREETER-X-0 RESPOND TEXT="password"
+#?GREETER-X-0 AUTHENTICATION-COMPLETE USERNAME=have-password1 AUTHENTICATED=TRUE
+#?*GREETER-X-0 START-SESSION
+
+# New X server starts for session
+#?XSERVER-1 START VT=8
+#?XSERVER-1 INDICATE-READY
+#?XSERVER-1 ACCEPT-CONNECT
+
+# Session starts
+#?SESSION-X-1 START USER=have-password1
+#?XSERVER-1 ACCEPT-CONNECT
+#?SESSION-X-1 CONNECT-XSERVER
+
+# Greeter stops
+#?GREETER-X-0 TERMINATE SIGNAL=15
+#?XSERVER-0 TERMINATE SIGNAL=15
+
+# Cleanup
+#?*STOP-DAEMON
+#?SESSION-X-1 TERMINATE SIGNAL=15
+#?XSERVER-1 TERMINATE SIGNAL=15
+#?RUNNER DAEMON-EXIT STATUS=0
diff --git a/tests/test-xserver-no-share b/tests/test-xserver-no-share
new file mode 100755 (executable)
index 0000000..7e91a19
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+./src/dbus-env ./src/test-runner xserver-no-share test-gobject-greeter