]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - tests/src/test-session.c
Use glib Unix signal handlers to make test programs more reliable
[sojka/lightdm.git] / tests / src / test-session.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <sys/types.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <grp.h>
8 #include <xcb/xcb.h>
9 #include <glib.h>
10 #include <glib-object.h>
11 #include <gio/gio.h>
12
13 #include "status.h"
14
15 static gchar *session_id;
16
17 static GMainLoop *loop;
18
19 static GString *open_fds;
20
21 static GKeyFile *config;
22
23 static xcb_connection_t *connection;
24
25 static gboolean
26 sigint_cb (gpointer user_data)
27 {
28     status_notify ("%s TERMINATE SIGNAL=%d", session_id, SIGINT);
29     g_main_loop_quit (loop);
30     return TRUE;
31 }
32
33 static gboolean
34 sigterm_cb (gpointer user_data)
35 {
36     status_notify ("%s TERMINATE SIGNAL=%d", session_id, SIGTERM);
37     g_main_loop_quit (loop);
38     return TRUE;
39 }
40
41 static void
42 request_cb (const gchar *request)
43 {
44     gchar *r;
45
46     if (!request)
47     {
48         g_main_loop_quit (loop);
49         return;
50     }
51   
52     r = g_strdup_printf ("%s LOGOUT", session_id);
53     if (strcmp (request, r) == 0)
54         exit (EXIT_SUCCESS);
55     g_free (r);
56   
57     r = g_strdup_printf ("%s CRASH", session_id);
58     if (strcmp (request, r) == 0)
59         kill (getpid (), SIGSEGV);
60     g_free (r);
61
62     r = g_strdup_printf ("%s LOCK-SEAT", session_id);
63     if (strcmp (request, r) == 0)
64     {
65         status_notify ("%s LOCK-SEAT", session_id);
66         g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
67                                      "org.freedesktop.DisplayManager",
68                                      getenv ("XDG_SEAT_PATH"),
69                                      "org.freedesktop.DisplayManager.Seat",
70                                      "Lock",
71                                      g_variant_new ("()"),
72                                      G_VARIANT_TYPE ("()"),
73                                      G_DBUS_CALL_FLAGS_NONE,
74                                      1000,
75                                      NULL,
76                                      NULL);
77     }
78     g_free (r);
79
80     r = g_strdup_printf ("%s LOCK-SESSION", session_id);
81     if (strcmp (request, r) == 0)
82     {
83         status_notify ("%s LOCK-SESSION", session_id);
84         g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
85                                      "org.freedesktop.DisplayManager",
86                                      getenv ("XDG_SESSION_PATH"),
87                                      "org.freedesktop.DisplayManager.Session",
88                                      "Lock",
89                                      g_variant_new ("()"),
90                                      G_VARIANT_TYPE ("()"),
91                                      G_DBUS_CALL_FLAGS_NONE,
92                                      1000,
93                                      NULL,
94                                      NULL);
95     }
96     g_free (r);
97
98     r = g_strdup_printf ("%s LIST-GROUPS", session_id);
99     if (strcmp (request, r) == 0)
100     {
101         int n_groups, i;
102         gid_t *groups;
103         GString *group_list;
104
105         n_groups = getgroups (0, NULL);
106         groups = malloc (sizeof (gid_t) * n_groups);
107         n_groups = getgroups (n_groups, groups);
108         group_list = g_string_new ("");
109         for (i = 0; i < n_groups; i++)
110         {
111             struct group *group;
112
113             if (i != 0)
114                 g_string_append (group_list, ",");
115             group = getgrgid (groups[i]);
116             if (group)
117                 g_string_append (group_list, group->gr_name);
118             else
119                 g_string_append_printf (group_list, "%d", groups[i]);
120         }
121         status_notify ("%s LIST-GROUPS GROUPS=%s", session_id, group_list->str);
122         g_string_free (group_list, TRUE);
123         free (groups);
124     }
125
126     r = g_strdup_printf ("%s READ-ENV NAME=", session_id);
127     if (g_str_has_prefix (request, r))
128     {
129         const gchar *name = request + strlen (r);
130         const gchar *value = g_getenv (name);
131         status_notify ("%s READ-ENV NAME=%s VALUE=%s", session_id, name, value ? value : "");
132     }
133     g_free (r);
134
135     r = g_strdup_printf ("%s WRITE-STDOUT TEXT=", session_id);
136     if (g_str_has_prefix (request, r))
137         g_print ("%s", request + strlen (r));
138     g_free (r);
139
140     r = g_strdup_printf ("%s WRITE-STDERR TEXT=", session_id);
141     if (g_str_has_prefix (request, r))
142         g_printerr ("%s", request + strlen (r));
143     g_free (r);
144
145     r = g_strdup_printf ("%s READ FILE=", session_id);
146     if (g_str_has_prefix (request, r))
147     {
148         const gchar *name = request + strlen (r);
149         gchar *contents;
150         GError *error = NULL;
151
152         if (g_file_get_contents (name, &contents, NULL, &error))
153             status_notify ("%s READ FILE=%s TEXT=%s", session_id, name, contents);
154         else
155             status_notify ("%s READ FILE=%s ERROR=%s", session_id, name, error->message);
156         g_clear_error (&error);
157     }
158     g_free (r);
159
160     r = g_strdup_printf ("%s LIST-UNKNOWN-FILE-DESCRIPTORS", session_id);
161     if (strcmp (request, r) == 0)
162         status_notify ("%s LIST-UNKNOWN-FILE-DESCRIPTORS FDS=%s", session_id, open_fds->str);
163     g_free (r);
164 }
165
166 int
167 main (int argc, char **argv)
168 {
169     gchar *display;
170     int fd, open_max;
171
172     display = getenv ("DISPLAY");
173     if (display == NULL)
174         session_id = g_strdup ("SESSION-?");
175     else if (display[0] == ':')
176         session_id = g_strdup_printf ("SESSION-X-%s", display + 1);
177     else
178         session_id = g_strdup_printf ("SESSION-X-%s", display);
179
180     open_fds = g_string_new ("");
181     open_max = sysconf (_SC_OPEN_MAX);
182     for (fd = STDERR_FILENO + 1; fd < open_max; fd++)
183     {
184         if (fcntl (fd, F_GETFD) >= 0)
185             g_string_append_printf (open_fds, "%d,", fd);
186     }
187     if (g_str_has_suffix (open_fds->str, ","))
188         open_fds->str[strlen (open_fds->str) - 1] = '\0';
189
190 #if !defined(GLIB_VERSION_2_36)
191     g_type_init ();
192 #endif
193
194     loop = g_main_loop_new (NULL, FALSE);
195
196     g_unix_signal_add (SIGINT, sigint_cb, NULL);
197     g_unix_signal_add (SIGTERM, sigterm_cb, NULL);
198
199     status_connect (request_cb);
200
201     if (argc > 1)
202         status_notify ("%s START NAME=%s USER=%s", session_id, argv[1], getenv ("USER"));
203     else
204         status_notify ("%s START USER=%s", session_id, getenv ("USER"));
205
206     config = g_key_file_new ();
207     g_key_file_load_from_file (config, g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), G_KEY_FILE_NONE, NULL);
208
209     connection = xcb_connect (NULL, NULL);
210
211     if (xcb_connection_has_error (connection))
212     {
213         status_notify ("%s CONNECT-XSERVER-ERROR", session_id);
214         return EXIT_FAILURE;
215     }
216
217     status_notify ("%s CONNECT-XSERVER", session_id);
218
219     g_main_loop_run (loop);
220
221     return EXIT_SUCCESS;
222 }