# 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)
#xserver-layout=
#xserver-config=
#xserver-allow-tcp=false
+#xserver-share=true
#xdmcp-manager=
#xdmcp-port=177
#xdmcp-key=
DISPLAY_SERVER_READY,
START_GREETER,
START_SESSION,
+ CREATE_DISPLAY,
STOPPED,
LAST_SIGNAL
};
/* 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;
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)
{
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)
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)
{
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;
}
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;
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)
{
return NULL;
}
+static Display *
+display_real_create_display (Display *display, Session *session)
+{
+ return NULL;
+}
+
static void
display_init (Display *display)
{
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));
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),
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;
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);
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);
STRING:VOID
OBJECT:VOID
OBJECT:STRING
+OBJECT:OBJECT
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"))
*/
#include "mir-session.h"
-
-struct MirSessionPrivate
-{
- /* Mir server information */
- MirServer *mir_server;
-};
+#include "mir-server.h"
G_DEFINE_TYPE (MirSession, mir_session, SESSION_TYPE);
MirSession *
-mir_session_new (MirServer *mir_server)
+mir_session_new (void)
{
MirSession *session;
session = g_object_new (MIR_SESSION_TYPE, NULL);
- session->priv->mir_server = g_object_ref (mir_server);
+ session_set_log_file (SESSION (session), ".session-errors");
return session;
}
static void
-mir_session_init (MirSession *session)
+mir_session_set_display_server (Session *session, DisplayServer *display_server)
{
- session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session, MIR_SESSION_TYPE, MirSessionPrivate);
+ MirServer *mir_server;
+
+ mir_server = MIR_SERVER (display_server);
+
+ SESSION_CLASS (mir_session_parent_class)->set_display_server (session, display_server);
}
static void
-mir_session_finalize (GObject *object)
+mir_session_init (MirSession *session)
{
- MirSession *self;
-
- self = MIR_SESSION (object);
-
- if (self->priv->mir_server)
- g_object_unref (self->priv->mir_server);
-
- G_OBJECT_CLASS (mir_session_parent_class)->finalize (object);
}
static void
mir_session_class_init (MirSessionClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = mir_session_finalize;
+ SessionClass *session_class = SESSION_CLASS (klass);
- g_type_class_add_private (klass, sizeof (MirSessionPrivate));
+ session_class->set_display_server = mir_session_set_display_server;
}
#define MIR_SESSION_H_
#include "session.h"
-#include "mir-server.h"
G_BEGIN_DECLS
GType mir_session_get_type (void);
-MirSession *mir_session_new (MirServer *mir_server);
+MirSession *mir_session_new (void);
G_END_DECLS
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);
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);
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);
}
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);
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);
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);
/* 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;
} SeatModule;
static GHashTable *seat_modules = NULL;
+static Display *create_display (Seat *seat);
+
void
seat_register_module (const gchar *name, GType type)
{
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)
{
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)
{
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"));
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);
{
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
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);
exit (EXIT_SUCCESS);
}
+static XAuthority *
+read_xauth (void)
+{
+ gchar *xauth_name;
+ guint16 xauth_family;
+ guint8 *xauth_address;
+ gsize xauth_address_length;
+ gchar *xauth_number;
+ guint8 *xauth_data;
+ gsize xauth_data_length;
+
+ xauth_name = read_string ();
+ if (!xauth_name)
+ return NULL;
+
+ read_data (&xauth_family, sizeof (xauth_family));
+ read_data (&xauth_address_length, sizeof (xauth_address_length));
+ xauth_address = g_malloc (xauth_address_length);
+ read_data (xauth_address, xauth_address_length);
+ xauth_number = read_string ();
+ read_data (&xauth_data_length, sizeof (xauth_data_length));
+ xauth_data = g_malloc (xauth_data_length);
+ read_data (xauth_data, xauth_data_length);
+
+ return xauth_new (xauth_family, xauth_address, xauth_address_length, xauth_number, xauth_name, xauth_data, xauth_data_length);
+}
+
int
session_child_run (int argc, char **argv)
{
gchar *tty;
gchar *remote_host_name;
gchar *xdisplay;
- gchar *xauth_name;
XAuthority *xauthority = NULL;
gchar *xauth_filename;
GDBusConnection *bus;
tty = read_string ();
remote_host_name = read_string ();
xdisplay = read_string ();
- xauth_name = read_string ();
- if (xauth_name)
- {
- guint16 xauth_family;
- guint8 *xauth_address;
- gsize xauth_address_length;
- gchar *xauth_number;
- guint8 *xauth_data;
- gsize xauth_data_length;
-
- read_data (&xauth_family, sizeof (xauth_family));
- read_data (&xauth_address_length, sizeof (xauth_address_length));
- xauth_address = g_malloc (xauth_address_length);
- read_data (xauth_address, xauth_address_length);
- xauth_number = read_string ();
- read_data (&xauth_data_length, sizeof (xauth_data_length));
- xauth_data = g_malloc (xauth_data_length);
- read_data (xauth_data, xauth_data_length);
-
- xauthority = xauth_new (xauth_family, xauth_address, xauth_address_length, xauth_number, xauth_name, xauth_data, xauth_data_length);
- }
+ xauthority = read_xauth ();
/* Setup PAM */
result = pam_start (service, username, &conversation, &pam_handle);
/* Get the command to run (blocks) */
log_filename = read_string ();
+ if (version >= 1)
+ {
+ g_free (tty);
+ tty = read_string ();
+ }
xauth_filename = read_string ();
+ if (version >= 1)
+ {
+ g_free (xdisplay);
+ xdisplay = read_string ();
+ if (xauthority)
+ g_object_unref (xauthority);
+ xauthority = read_xauth ();
+ }
read_data (&env_length, sizeof (env_length));
for (i = 0; i < env_length; i++)
pam_putenv (pam_handle, read_string ());
struct SessionPrivate
{
+ /* Display server running on */
+ DisplayServer *display_server;
+
/* PID of child process */
GPid pid;
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)
{
write_data (session, value, sizeof (char) * length);
}
+static void
+write_xauth (Session *session, XAuthority *xauthority)
+{
+ guint16 family;
+ gsize length;
+
+ if (!xauthority)
+ {
+ write_string (session, NULL);
+ return;
+ }
+
+ write_string (session, xauth_get_authorization_name (session->priv->xauthority));
+ family = xauth_get_family (session->priv->xauthority);
+ write_data (session, &family, sizeof (family));
+ length = xauth_get_address_length (session->priv->xauthority);
+ write_data (session, &length, sizeof (length));
+ write_data (session, xauth_get_address (session->priv->xauthority), length);
+ write_string (session, xauth_get_number (session->priv->xauthority));
+ length = xauth_get_authorization_data_length (session->priv->xauthority);
+ write_data (session, &length, sizeof (length));
+ write_data (session, xauth_get_authorization_data (session->priv->xauthority), length);
+}
+
static ssize_t
read_from_child (Session *session, void *buf, size_t count)
{
close (from_child_input);
/* Indicate what version of the protocol we are using */
- version = 0;
+ version = 1;
write_data (session, &version, sizeof (version));
/* Send configuration */
write_string (session, session->priv->tty);
write_string (session, session->priv->remote_host_name);
write_string (session, session->priv->xdisplay);
- if (session->priv->xauthority)
- {
- guint16 family;
- gsize length;
-
- write_string (session, xauth_get_authorization_name (session->priv->xauthority));
- family = xauth_get_family (session->priv->xauthority);
- write_data (session, &family, sizeof (family));
- length = xauth_get_address_length (session->priv->xauthority);
- write_data (session, &length, sizeof (length));
- write_data (session, xauth_get_address (session->priv->xauthority), length);
- write_string (session, xauth_get_number (session->priv->xauthority));
- length = xauth_get_authorization_data_length (session->priv->xauthority);
- write_data (session, &length, sizeof (length));
- write_data (session, xauth_get_authorization_data (session->priv->xauthority), length);
- }
- else
- write_string (session, NULL);
+ write_xauth (session, session->priv->xauthority);
g_debug ("Started session %d with service '%s', username '%s'", session->priv->pid, service, username);
session_run (Session *session, gchar **argv)
{
gsize i, argc;
- gchar *command, *filename;
+ gchar *command, *xauth_filename;
GList *link;
g_return_if_fail (session != NULL);
g_warning ("Failed to set ownership of user authority dir: %s", strerror (errno));
}
- filename = g_build_filename (dir, "xauthority", NULL);
+ xauth_filename = g_build_filename (dir, "xauthority", NULL);
g_free (dir);
}
else
- filename = g_build_filename (user_get_home_directory (session_get_user (session)), ".Xauthority", NULL);
+ xauth_filename = g_build_filename (user_get_home_directory (session_get_user (session)), ".Xauthority", NULL);
write_string (session, session->priv->log_filename);
- write_string (session, filename);
- g_free (filename);
+ write_string (session, session->priv->tty);
+ write_string (session, xauth_filename);
+ g_free (xauth_filename);
+ write_string (session, session->priv->xdisplay);
+ write_xauth (session, session->priv->xauthority);
argc = g_list_length (session->priv->env);
write_data (session, &argc, sizeof (argc));
for (link = session->priv->env; link; link = link->next)
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)
{
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));
#include <security/pam_appl.h>
+#include "display-server.h"
#include "accounts.h"
#include "xauthority.h"
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
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);
#include <sys/stat.h>
#include "xsession.h"
+#include "xserver.h"
#include "configuration.h"
-#include "privileges.h"
-
-struct XSessionPrivate
-{
- /* X server connected to */
- XServer *xserver;
-};
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));
+ session_set_xdisplay (session, xserver_get_address (xserver));
+ authority = xserver_get_authority (xserver);
+ 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)
+{
}
static void
xsession_class_init (XSessionClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = xsession_finalize;
+ SessionClass *session_class = SESSION_CLASS (klass);
- g_type_class_add_private (klass, sizeof (XSessionPrivate));
+ session_class->set_display_server = xsession_set_display_server;
}
#define XSESSION_H_
#include "session.h"
-#include "xserver.h"
G_BEGIN_DECLS
GType xsession_get_type (void);
-XSession *xsession_new (XServer *xserver);
+XSession *xsession_new (void);
G_END_DECLS
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 \
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
--- /dev/null
+#
+# 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
--- /dev/null
+#!/bin/sh
+./src/dbus-env ./src/test-runner xserver-no-share test-gobject-greeter