1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
1 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
2 |
*
|
|
3 |
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
|
4 |
*
|
|
5 |
* This program is free software; you can redistribute it and/or modify
|
|
6 |
* it under the terms of the GNU General Public License as published by
|
|
7 |
* the Free Software Foundation; either version 2 of the License, or
|
|
8 |
* (at your option) any later version.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
* GNU General Public License for more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License
|
|
16 |
* along with this program; if not, write to the Free Software
|
|
1.4.52
by Jeremy Bicha
Import upstream version 3.5.92.1 |
17 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
18 |
*
|
19 |
*/
|
|
20 |
||
21 |
#include "config.h" |
|
22 |
||
23 |
#include <stdlib.h> |
|
24 |
#include <stdio.h> |
|
25 |
#include <fcntl.h> |
|
26 |
#include <unistd.h> |
|
27 |
#include <string.h> |
|
28 |
#include <sys/types.h> |
|
29 |
#include <sys/wait.h> |
|
30 |
#include <errno.h> |
|
31 |
#include <ctype.h> |
|
32 |
#include <pwd.h> |
|
33 |
#include <grp.h> |
|
34 |
#include <signal.h> |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
35 |
#include <sys/ioctl.h> |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
36 |
#include <sys/resource.h> |
37 |
||
1.4.45
by Kees Cook
Import upstream version 2.30.4 |
38 |
#ifdef HAVE_SYS_PRCTL_H
|
39 |
#include <sys/prctl.h> |
|
40 |
#endif
|
|
41 |
||
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
42 |
#ifdef WITH_PLYMOUTH
|
215
by Robert Ancell
* debian/control: |
43 |
#include <linux/vt.h> |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
44 |
#endif
|
45 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
46 |
#include <glib/gi18n.h> |
47 |
#include <glib/gstdio.h> |
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
48 |
#include <gio/gio.h> |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
49 |
|
50 |
#include <X11/Xlib.h> /* for Display */ |
|
51 |
||
52 |
#include "gdm-common.h" |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
53 |
#include "gdm-settings-direct.h" |
54 |
#include "gdm-settings-keys.h" |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
55 |
|
56 |
#include "gdm-server.h" |
|
57 |
||
58 |
extern char **environ; |
|
59 |
||
60 |
#define GDM_SERVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SERVER, GdmServerPrivate))
|
|
61 |
||
62 |
/* These are the servstat values, also used as server
|
|
63 |
* process exit codes */
|
|
64 |
#define SERVER_TIMEOUT 2 /* Server didn't start */ |
|
65 |
#define SERVER_DEAD 250 /* Server stopped */ |
|
66 |
#define SERVER_PENDING 251 /* Server started but not ready for connections yet */ |
|
67 |
#define SERVER_RUNNING 252 /* Server running and ready for connections */ |
|
68 |
#define SERVER_ABORT 253 /* Server failed badly. Suspending display. */ |
|
69 |
||
70 |
#define MAX_LOGS 5
|
|
71 |
||
72 |
struct GdmServerPrivate |
|
73 |
{
|
|
74 |
char *command; |
|
75 |
GPid pid; |
|
76 |
||
77 |
gboolean disable_tcp; |
|
78 |
int priority; |
|
79 |
char *user_name; |
|
80 |
char *session_args; |
|
81 |
||
82 |
char *log_dir; |
|
83 |
char *display_name; |
|
84 |
char *display_device; |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
85 |
char *display_seat_id; |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
86 |
char *auth_file; |
87 |
||
88 |
gboolean is_parented; |
|
89 |
char *parent_display_name; |
|
90 |
char *parent_auth_file; |
|
91 |
char *chosen_hostname; |
|
92 |
||
93 |
guint child_watch_id; |
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
94 |
guint sigusr1_id; |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
95 |
|
96 |
gboolean is_initial; |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
97 |
};
|
98 |
||
99 |
enum { |
|
100 |
PROP_0, |
|
101 |
PROP_DISPLAY_NAME, |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
102 |
PROP_DISPLAY_SEAT_ID, |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
103 |
PROP_DISPLAY_DEVICE, |
104 |
PROP_AUTH_FILE, |
|
105 |
PROP_IS_PARENTED, |
|
106 |
PROP_PARENT_DISPLAY_NAME, |
|
107 |
PROP_PARENT_AUTH_FILE, |
|
108 |
PROP_CHOSEN_HOSTNAME, |
|
109 |
PROP_COMMAND, |
|
110 |
PROP_PRIORITY, |
|
111 |
PROP_USER_NAME, |
|
112 |
PROP_SESSION_ARGS, |
|
113 |
PROP_LOG_DIR, |
|
114 |
PROP_DISABLE_TCP, |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
115 |
PROP_IS_INITIAL, |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
116 |
};
|
117 |
||
118 |
enum { |
|
119 |
READY, |
|
120 |
EXITED, |
|
121 |
DIED, |
|
122 |
LAST_SIGNAL
|
|
123 |
};
|
|
124 |
||
125 |
static guint signals [LAST_SIGNAL] = { 0, }; |
|
126 |
||
127 |
static void gdm_server_class_init (GdmServerClass *klass); |
|
128 |
static void gdm_server_init (GdmServer *server); |
|
129 |
static void gdm_server_finalize (GObject *object); |
|
130 |
||
131 |
G_DEFINE_TYPE (GdmServer, gdm_server, G_TYPE_OBJECT) |
|
132 |
||
133 |
static char * |
|
134 |
_gdm_server_query_ck_for_display_device (GdmServer *server) |
|
135 |
{
|
|
136 |
char *out; |
|
137 |
char *command; |
|
138 |
int status; |
|
139 |
gboolean res; |
|
140 |
GError *error; |
|
141 |
||
142 |
g_return_val_if_fail (GDM_IS_SERVER (server), NULL); |
|
143 |
||
144 |
error = NULL; |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
145 |
command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s", |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
146 |
server->priv->display_name); |
147 |
||
148 |
g_debug ("GdmServer: Running helper %s", command); |
|
149 |
out = NULL; |
|
150 |
res = g_spawn_command_line_sync (command, |
|
151 |
&out, |
|
152 |
NULL, |
|
153 |
&status, |
|
154 |
&error); |
|
155 |
if (! res) { |
|
156 |
g_warning ("Could not run helper: %s", error->message); |
|
157 |
g_error_free (error); |
|
158 |
} else { |
|
159 |
out = g_strstrip (out); |
|
160 |
g_debug ("GdmServer: Got tty: '%s'", out); |
|
161 |
}
|
|
162 |
||
163 |
g_free (command); |
|
164 |
||
165 |
return out; |
|
166 |
}
|
|
167 |
||
168 |
char * |
|
169 |
gdm_server_get_display_device (GdmServer *server) |
|
170 |
{
|
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
171 |
#ifdef WITH_SYSTEMD
|
274
by Martin Pitt
* Add debian/patches/00git_logind_check.patch: Fix checks for logind. |
172 |
if (LOGIND_RUNNING()) { |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
173 |
/* systemd finds the display device out on its own based on the display */
|
174 |
return NULL; |
|
175 |
}
|
|
176 |
#endif
|
|
177 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
178 |
if (server->priv->display_device == NULL) { |
179 |
server->priv->display_device = |
|
180 |
_gdm_server_query_ck_for_display_device (server); |
|
181 |
||
182 |
g_object_notify (G_OBJECT (server), "display-device"); |
|
183 |
}
|
|
184 |
||
185 |
return g_strdup (server->priv->display_device); |
|
186 |
}
|
|
187 |
||
188 |
static gboolean |
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
189 |
on_sigusr1 (gpointer user_data) |
190 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
191 |
{
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
192 |
GdmServer *server = user_data; |
193 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
194 |
g_debug ("GdmServer: Got USR1 from X server - emitting READY"); |
195 |
||
196 |
g_signal_emit (server, signals[READY], 0); |
|
197 |
return FALSE; |
|
198 |
}
|
|
199 |
||
200 |
/* We keep a connection (parent_dsp) open with the parent X server
|
|
201 |
* before running a proxy on it to prevent the X server resetting
|
|
202 |
* as we open and close other connections.
|
|
203 |
* Note that XDMCP servers, by default, reset when the seed X
|
|
204 |
* connection closes whereas usually the X server only quits when
|
|
205 |
* all X connections have closed.
|
|
206 |
*/
|
|
207 |
#if 0
|
|
208 |
static gboolean
|
|
209 |
connect_to_parent (GdmServer *server)
|
|
210 |
{
|
|
211 |
int maxtries;
|
|
212 |
int openretries;
|
|
213 |
||
214 |
g_debug ("GdmServer: Connecting to parent display \'%s\'",
|
|
215 |
d->parent_disp);
|
|
216 |
||
217 |
d->parent_dsp = NULL;
|
|
218 |
||
219 |
maxtries = SERVER_IS_XDMCP (d) ? 10 : 2;
|
|
220 |
||
221 |
openretries = 0;
|
|
222 |
while (openretries < maxtries &&
|
|
223 |
d->parent_dsp == NULL) {
|
|
224 |
d->parent_dsp = XOpenDisplay (d->parent_disp);
|
|
225 |
||
226 |
if G_UNLIKELY (d->parent_dsp == NULL) {
|
|
227 |
g_debug ("GdmServer: Sleeping %d on a retry", 1+openretries*2);
|
|
228 |
gdm_sleep_no_signal (1+openretries*2);
|
|
229 |
openretries++;
|
|
230 |
}
|
|
231 |
}
|
|
232 |
||
233 |
if (d->parent_dsp == NULL)
|
|
234 |
gdm_error (_("%s: failed to connect to parent display \'%s\'"),
|
|
235 |
"gdm_server_start", d->parent_disp);
|
|
236 |
||
237 |
return d->parent_dsp != NULL;
|
|
238 |
}
|
|
239 |
#endif
|
|
240 |
||
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
241 |
static void |
242 |
gdm_server_init_command (GdmServer *server) |
|
243 |
{
|
|
244 |
gboolean debug = FALSE; |
|
245 |
const char *debug_options; |
|
246 |
||
247 |
if (server->priv->command != NULL) { |
|
248 |
return; |
|
249 |
}
|
|
250 |
||
251 |
gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); |
|
252 |
if (debug) { |
|
253 |
debug_options = " -logverbose 7 -core "; |
|
254 |
} else { |
|
255 |
debug_options = ""; |
|
256 |
}
|
|
257 |
||
258 |
#ifdef WITH_SYSTEMD
|
|
259 |
||
260 |
/* This is a temporary hack to work around the fact that XOrg
|
|
261 |
* currently lacks support for multi-seat hotplugging for
|
|
262 |
* display devices. This bit should be removed as soon as XOrg
|
|
263 |
* gains native support for automatically enumerating usb
|
|
264 |
* based graphics adapters at start-up via udev. */
|
|
265 |
||
266 |
/* systemd ships an X server wrapper tool which simply invokes
|
|
267 |
* the usual X but ensures it only uses the display devices of
|
|
268 |
* the seat. */
|
|
269 |
||
270 |
/* We do not rely on this wrapper server if, a) the machine
|
|
271 |
* wasn't booted using systemd, or b) the wrapper tool is
|
|
272 |
* missing, or c) we are running for the main seat 'seat0'. */
|
|
273 |
||
274
by Martin Pitt
* Add debian/patches/00git_logind_check.patch: Fix checks for logind. |
274 |
if (!LOGIND_RUNNING()) { |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
275 |
goto fallback; |
276 |
}
|
|
277 |
||
278 |
if (g_access (SYSTEMD_X_SERVER, X_OK) < 0) { |
|
279 |
goto fallback; |
|
280 |
}
|
|
281 |
||
282 |
if (server->priv->display_seat_id == NULL || |
|
283 |
strcmp (server->priv->display_seat_id, "seat0") == 0) { |
|
284 |
goto fallback; |
|
285 |
}
|
|
286 |
||
1.4.52
by Jeremy Bicha
Import upstream version 3.5.92.1 |
287 |
server->priv->command = g_strdup_printf (SYSTEMD_X_SERVER " -background none -verbose%s", debug_options); |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
288 |
return; |
289 |
||
290 |
fallback: |
|
291 |
#endif
|
|
292 |
||
1.4.52
by Jeremy Bicha
Import upstream version 3.5.92.1 |
293 |
server->priv->command = g_strdup_printf (X_SERVER " -background none -verbose%s", debug_options); |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
294 |
}
|
295 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
296 |
static gboolean |
297 |
gdm_server_resolve_command_line (GdmServer *server, |
|
298 |
const char *vtarg, |
|
299 |
int *argcp, |
|
300 |
char ***argvp) |
|
301 |
{
|
|
302 |
int argc; |
|
303 |
char **argv; |
|
304 |
int len; |
|
305 |
int i; |
|
306 |
gboolean gotvtarg = FALSE; |
|
307 |
gboolean query_in_arglist = FALSE; |
|
308 |
||
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
309 |
gdm_server_init_command (server); |
310 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
311 |
g_shell_parse_argv (server->priv->command, &argc, &argv, NULL); |
312 |
||
313 |
for (len = 0; argv != NULL && argv[len] != NULL; len++) { |
|
314 |
char *arg = argv[len]; |
|
315 |
||
316 |
/* HACK! Not to add vt argument to servers that already force
|
|
317 |
* allocation. Mostly for backwards compat only */
|
|
318 |
if (strncmp (arg, "vt", 2) == 0 && |
|
319 |
isdigit (arg[2]) && |
|
320 |
(arg[3] == '\0' || |
|
321 |
(isdigit (arg[3]) && arg[4] == '\0'))) |
|
322 |
gotvtarg = TRUE; |
|
323 |
if (strcmp (arg, "-query") == 0 || |
|
324 |
strcmp (arg, "-indirect") == 0) |
|
325 |
query_in_arglist = TRUE; |
|
326 |
}
|
|
327 |
||
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
328 |
argv = g_renew (char *, argv, len + 12); |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
329 |
/* shift args down one */
|
330 |
for (i = len - 1; i >= 1; i--) { |
|
331 |
argv[i+1] = argv[i]; |
|
332 |
}
|
|
333 |
||
334 |
/* server number is the FIRST argument, before any others */
|
|
335 |
argv[1] = g_strdup (server->priv->display_name); |
|
336 |
len++; |
|
337 |
||
338 |
if (server->priv->auth_file != NULL) { |
|
339 |
argv[len++] = g_strdup ("-auth"); |
|
340 |
argv[len++] = g_strdup (server->priv->auth_file); |
|
341 |
}
|
|
342 |
||
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
343 |
#ifdef WITH_SYSTEMD
|
274
by Martin Pitt
* Add debian/patches/00git_logind_check.patch: Fix checks for logind. |
344 |
if (LOGIND_RUNNING() && server->priv->display_seat_id != NULL) { |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
345 |
argv[len++] = g_strdup ("-seat"); |
346 |
argv[len++] = g_strdup (server->priv->display_seat_id); |
|
347 |
}
|
|
348 |
#endif
|
|
349 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
350 |
if (server->priv->chosen_hostname) { |
351 |
/* run just one session */
|
|
352 |
argv[len++] = g_strdup ("-terminate"); |
|
353 |
argv[len++] = g_strdup ("-query"); |
|
354 |
argv[len++] = g_strdup (server->priv->chosen_hostname); |
|
355 |
query_in_arglist = TRUE; |
|
356 |
}
|
|
357 |
||
358 |
if (server->priv->disable_tcp && ! query_in_arglist) { |
|
359 |
argv[len++] = g_strdup ("-nolisten"); |
|
360 |
argv[len++] = g_strdup ("tcp"); |
|
361 |
}
|
|
362 |
||
363 |
if (vtarg != NULL && ! gotvtarg) { |
|
364 |
argv[len++] = g_strdup (vtarg); |
|
365 |
}
|
|
366 |
||
367 |
argv[len++] = NULL; |
|
368 |
||
369 |
*argvp = argv; |
|
370 |
*argcp = len; |
|
371 |
||
372 |
return TRUE; |
|
373 |
}
|
|
374 |
||
375 |
static void |
|
376 |
rotate_logs (const char *path, |
|
377 |
guint n_copies) |
|
378 |
{
|
|
379 |
int i; |
|
380 |
||
381 |
for (i = n_copies - 1; i > 0; i--) { |
|
382 |
char *name_n; |
|
383 |
char *name_n1; |
|
384 |
||
385 |
name_n = g_strdup_printf ("%s.%d", path, i); |
|
386 |
if (i > 1) { |
|
387 |
name_n1 = g_strdup_printf ("%s.%d", path, i - 1); |
|
388 |
} else { |
|
389 |
name_n1 = g_strdup (path); |
|
390 |
}
|
|
391 |
||
392 |
VE_IGNORE_EINTR (g_unlink (name_n)); |
|
393 |
VE_IGNORE_EINTR (g_rename (name_n1, name_n)); |
|
394 |
||
395 |
g_free (name_n1); |
|
396 |
g_free (name_n); |
|
397 |
}
|
|
398 |
||
399 |
VE_IGNORE_EINTR (g_unlink (path)); |
|
400 |
}
|
|
401 |
||
402 |
static void |
|
403 |
change_user (GdmServer *server) |
|
404 |
{
|
|
405 |
struct passwd *pwent; |
|
406 |
||
407 |
if (server->priv->user_name == NULL) { |
|
408 |
return; |
|
409 |
}
|
|
410 |
||
1.4.46
by Sebastien Bacher
Import upstream version 2.30.5 |
411 |
gdm_get_pwent_for_name (server->priv->user_name, &pwent); |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
412 |
if (pwent == NULL) { |
413 |
g_warning (_("Server was to be spawned by user %s but that user doesn't exist"), |
|
414 |
server->priv->user_name); |
|
415 |
_exit (1); |
|
416 |
}
|
|
417 |
||
418 |
g_debug ("GdmServer: Changing (uid:gid) for child process to (%d:%d)", |
|
419 |
pwent->pw_uid, |
|
420 |
pwent->pw_gid); |
|
421 |
||
422 |
if (pwent->pw_uid != 0) { |
|
423 |
if (setgid (pwent->pw_gid) < 0) { |
|
424 |
g_warning (_("Couldn't set groupid to %d"), |
|
425 |
pwent->pw_gid); |
|
426 |
_exit (1); |
|
427 |
}
|
|
428 |
||
429 |
if (initgroups (pwent->pw_name, pwent->pw_gid) < 0) { |
|
430 |
g_warning (_("initgroups () failed for %s"), |
|
431 |
pwent->pw_name); |
|
432 |
_exit (1); |
|
433 |
}
|
|
434 |
||
435 |
if (setuid (pwent->pw_uid) < 0) { |
|
436 |
g_warning (_("Couldn't set userid to %d"), |
|
437 |
(int)pwent->pw_uid); |
|
438 |
_exit (1); |
|
439 |
}
|
|
440 |
} else { |
|
441 |
gid_t groups[1] = { 0 }; |
|
442 |
||
443 |
if (setgid (0) < 0) { |
|
1.4.43
by Martin Pitt
Import upstream version 2.30.2 |
444 |
g_warning (_("Couldn't set groupid to %d"), 0); |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
445 |
/* Don't error out, it's not fatal, if it fails we'll
|
446 |
* just still be */
|
|
447 |
}
|
|
448 |
||
449 |
/* this will get rid of any suplementary groups etc... */
|
|
450 |
setgroups (1, groups); |
|
451 |
}
|
|
452 |
}
|
|
453 |
||
454 |
static void |
|
455 |
server_child_setup (GdmServer *server) |
|
456 |
{
|
|
457 |
int logfd; |
|
458 |
struct sigaction ign_signal; |
|
459 |
sigset_t mask; |
|
460 |
char *log_file; |
|
461 |
char *log_path; |
|
462 |
||
463 |
log_file = g_strdup_printf ("%s.log", server->priv->display_name); |
|
464 |
log_path = g_build_filename (server->priv->log_dir, log_file, NULL); |
|
465 |
g_free (log_file); |
|
466 |
||
467 |
/* Rotate the X server logs */
|
|
468 |
rotate_logs (log_path, MAX_LOGS); |
|
469 |
||
470 |
/* Log all output from spawned programs to a file */
|
|
471 |
g_debug ("GdmServer: Opening logfile for server %s", log_path); |
|
472 |
||
473 |
VE_IGNORE_EINTR (g_unlink (log_path)); |
|
474 |
VE_IGNORE_EINTR (logfd = open (log_path, O_CREAT|O_APPEND|O_TRUNC|O_WRONLY|O_EXCL, 0644)); |
|
475 |
||
476 |
g_free (log_path); |
|
477 |
||
478 |
if (logfd != -1) { |
|
479 |
VE_IGNORE_EINTR (dup2 (logfd, 1)); |
|
480 |
VE_IGNORE_EINTR (dup2 (logfd, 2)); |
|
481 |
close (logfd); |
|
482 |
} else { |
|
1.4.47
by Martin Pitt
Import upstream version 2.32.0 |
483 |
g_warning (_("%s: Could not open log file for display %s!"), |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
484 |
"gdm_server_spawn", |
485 |
server->priv->display_name); |
|
486 |
}
|
|
487 |
||
488 |
/* The X server expects USR1/TTIN/TTOU to be SIG_IGN */
|
|
489 |
ign_signal.sa_handler = SIG_IGN; |
|
490 |
ign_signal.sa_flags = SA_RESTART; |
|
491 |
sigemptyset (&ign_signal.sa_mask); |
|
492 |
||
493 |
if (sigaction (SIGUSR1, &ign_signal, NULL) < 0) { |
|
494 |
g_warning (_("%s: Error setting %s to %s"), |
|
495 |
"gdm_server_spawn", "USR1", "SIG_IGN"); |
|
496 |
_exit (SERVER_ABORT); |
|
497 |
}
|
|
498 |
||
499 |
if (sigaction (SIGTTIN, &ign_signal, NULL) < 0) { |
|
500 |
g_warning (_("%s: Error setting %s to %s"), |
|
501 |
"gdm_server_spawn", "TTIN", "SIG_IGN"); |
|
502 |
_exit (SERVER_ABORT); |
|
503 |
}
|
|
504 |
||
505 |
if (sigaction (SIGTTOU, &ign_signal, NULL) < 0) { |
|
506 |
g_warning (_("%s: Error setting %s to %s"), |
|
507 |
"gdm_server_spawn", "TTOU", "SIG_IGN"); |
|
508 |
_exit (SERVER_ABORT); |
|
509 |
}
|
|
510 |
||
511 |
/* And HUP and TERM are at SIG_DFL from gdm_unset_signals,
|
|
512 |
we also have an empty mask and all that fun stuff */
|
|
513 |
||
514 |
/* unblock signals (especially HUP/TERM/USR1) so that we
|
|
515 |
* can control the X server */
|
|
516 |
sigemptyset (&mask); |
|
517 |
sigprocmask (SIG_SETMASK, &mask, NULL); |
|
518 |
||
1.4.45
by Kees Cook
Import upstream version 2.30.4 |
519 |
/* Terminate the process when the parent dies */
|
520 |
#ifdef HAVE_SYS_PRCTL_H
|
|
521 |
prctl (PR_SET_PDEATHSIG, SIGTERM); |
|
522 |
#endif
|
|
523 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
524 |
if (server->priv->priority != 0) { |
525 |
if (setpriority (PRIO_PROCESS, 0, server->priv->priority)) { |
|
526 |
g_warning (_("%s: Server priority couldn't be set to %d: %s"), |
|
527 |
"gdm_server_spawn", |
|
528 |
server->priv->priority, |
|
529 |
g_strerror (errno)); |
|
530 |
}
|
|
531 |
}
|
|
532 |
||
533 |
setpgid (0, 0); |
|
534 |
||
535 |
change_user (server); |
|
536 |
}
|
|
537 |
||
538 |
static void |
|
539 |
listify_hash (const char *key, |
|
540 |
const char *value, |
|
541 |
GPtrArray *env) |
|
542 |
{
|
|
543 |
char *str; |
|
544 |
str = g_strdup_printf ("%s=%s", key, value); |
|
545 |
g_ptr_array_add (env, str); |
|
546 |
}
|
|
547 |
||
548 |
static GPtrArray * |
|
549 |
get_server_environment (GdmServer *server) |
|
550 |
{
|
|
551 |
GPtrArray *env; |
|
552 |
char **l; |
|
553 |
GHashTable *hash; |
|
554 |
||
555 |
env = g_ptr_array_new (); |
|
556 |
||
557 |
/* create a hash table of current environment, then update keys has necessary */
|
|
558 |
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); |
|
559 |
for (l = environ; *l != NULL; l++) { |
|
560 |
char **str; |
|
561 |
str = g_strsplit (*l, "=", 2); |
|
562 |
g_hash_table_insert (hash, str[0], str[1]); |
|
1.4.45
by Kees Cook
Import upstream version 2.30.4 |
563 |
g_free (str); |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
564 |
}
|
565 |
||
566 |
/* modify environment here */
|
|
567 |
if (server->priv->is_parented) { |
|
568 |
if (server->priv->parent_auth_file != NULL) { |
|
569 |
g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (server->priv->parent_auth_file)); |
|
570 |
}
|
|
571 |
||
572 |
if (server->priv->parent_display_name != NULL) { |
|
573 |
g_hash_table_insert (hash, g_strdup ("DISPLAY"), g_strdup (server->priv->parent_display_name)); |
|
574 |
}
|
|
575 |
} else { |
|
576 |
g_hash_table_insert (hash, g_strdup ("DISPLAY="), g_strdup (server->priv->display_name)); |
|
577 |
}
|
|
578 |
||
579 |
if (server->priv->user_name != NULL) { |
|
580 |
struct passwd *pwent; |
|
581 |
||
1.4.46
by Sebastien Bacher
Import upstream version 2.30.5 |
582 |
gdm_get_pwent_for_name (server->priv->user_name, &pwent); |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
583 |
|
584 |
if (pwent->pw_dir != NULL |
|
585 |
&& g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) { |
|
586 |
g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (pwent->pw_dir)); |
|
587 |
} else { |
|
588 |
/* Hack */
|
|
589 |
g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup ("/")); |
|
590 |
}
|
|
591 |
g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup (pwent->pw_shell)); |
|
592 |
g_hash_table_remove (hash, "MAIL"); |
|
593 |
}
|
|
594 |
||
595 |
g_hash_table_foreach (hash, (GHFunc)listify_hash, env); |
|
596 |
g_hash_table_destroy (hash); |
|
597 |
||
598 |
g_ptr_array_add (env, NULL); |
|
599 |
||
600 |
return env; |
|
601 |
}
|
|
602 |
||
603 |
static void |
|
604 |
server_add_xserver_args (GdmServer *server, |
|
605 |
int *argc, |
|
606 |
char ***argv) |
|
607 |
{
|
|
608 |
int count; |
|
609 |
char **args; |
|
610 |
int len; |
|
611 |
int i; |
|
612 |
||
613 |
len = *argc; |
|
614 |
g_shell_parse_argv (server->priv->session_args, &count, &args, NULL); |
|
615 |
*argv = g_renew (char *, *argv, len + count + 1); |
|
616 |
||
617 |
for (i=0; i < count;i++) { |
|
618 |
*argv[len++] = g_strdup (args[i]); |
|
619 |
}
|
|
620 |
||
621 |
*argc += count; |
|
622 |
||
623 |
argv[len] = NULL; |
|
624 |
g_strfreev (args); |
|
625 |
}
|
|
626 |
||
627 |
static void |
|
628 |
server_child_watch (GPid pid, |
|
629 |
int status, |
|
630 |
GdmServer *server) |
|
631 |
{
|
|
632 |
g_debug ("GdmServer: child (pid:%d) done (%s:%d)", |
|
633 |
(int) pid, |
|
634 |
WIFEXITED (status) ? "status" |
|
635 |
: WIFSIGNALED (status) ? "signal" |
|
636 |
: "unknown", |
|
637 |
WIFEXITED (status) ? WEXITSTATUS (status) |
|
638 |
: WIFSIGNALED (status) ? WTERMSIG (status) |
|
639 |
: -1); |
|
640 |
||
1.4.51
by Jeremy Bicha
Import upstream version 3.5.91 |
641 |
g_object_ref (server); |
642 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
643 |
if (WIFEXITED (status)) { |
644 |
int code = WEXITSTATUS (status); |
|
645 |
g_signal_emit (server, signals [EXITED], 0, code); |
|
646 |
} else if (WIFSIGNALED (status)) { |
|
647 |
int num = WTERMSIG (status); |
|
648 |
g_signal_emit (server, signals [DIED], 0, num); |
|
649 |
}
|
|
650 |
||
651 |
g_spawn_close_pid (server->priv->pid); |
|
652 |
server->priv->pid = -1; |
|
1.4.51
by Jeremy Bicha
Import upstream version 3.5.91 |
653 |
|
654 |
g_object_unref (server); |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
655 |
}
|
656 |
||
657 |
static gboolean |
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
658 |
gdm_server_spawn (GdmServer *server, |
659 |
const char *vtarg, |
|
660 |
GError **error) |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
661 |
{
|
662 |
int argc; |
|
663 |
gchar **argv = NULL; |
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
664 |
GPtrArray *env = NULL; |
665 |
gboolean ret = FALSE; |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
666 |
char *freeme; |
667 |
||
668 |
/* Figure out the server command */
|
|
669 |
argv = NULL; |
|
670 |
argc = 0; |
|
671 |
gdm_server_resolve_command_line (server, |
|
672 |
vtarg, |
|
673 |
&argc, |
|
674 |
&argv); |
|
675 |
||
676 |
if (server->priv->session_args) { |
|
677 |
server_add_xserver_args (server, &argc, &argv); |
|
678 |
}
|
|
679 |
||
680 |
if (argv[0] == NULL) { |
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
681 |
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, |
682 |
_("%s: Empty server command for display %s"), |
|
683 |
"gdm_server_spawn", |
|
684 |
server->priv->display_name); |
|
1.4.52
by Jeremy Bicha
Import upstream version 3.5.92.1 |
685 |
goto out; |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
686 |
}
|
687 |
||
688 |
env = get_server_environment (server); |
|
689 |
||
690 |
freeme = g_strjoinv (" ", argv); |
|
691 |
g_debug ("GdmServer: Starting X server process: %s", freeme); |
|
692 |
g_free (freeme); |
|
693 |
||
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
694 |
if (!g_spawn_async_with_pipes (NULL, |
695 |
argv, |
|
696 |
(char **)env->pdata, |
|
697 |
G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, |
|
698 |
(GSpawnChildSetupFunc)server_child_setup, |
|
699 |
server, |
|
700 |
&server->priv->pid, |
|
701 |
NULL, |
|
702 |
NULL, |
|
703 |
NULL, |
|
704 |
error)) |
|
705 |
goto out; |
|
706 |
||
707 |
g_debug ("GdmServer: Started X server process %d - waiting for READY", (int)server->priv->pid); |
|
708 |
||
709 |
server->priv->child_watch_id = g_child_watch_add (server->priv->pid, |
|
710 |
(GChildWatchFunc)server_child_watch, |
|
711 |
server); |
|
712 |
||
713 |
ret = TRUE; |
|
714 |
out: |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
715 |
g_strfreev (argv); |
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
716 |
if (env) { |
717 |
g_ptr_array_foreach (env, (GFunc)g_free, NULL); |
|
718 |
g_ptr_array_free (env, TRUE); |
|
1.4.52
by Jeremy Bicha
Import upstream version 3.5.92.1 |
719 |
}
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
720 |
return ret; |
721 |
}
|
|
722 |
||
723 |
/**
|
|
724 |
* gdm_server_start:
|
|
725 |
* @disp: Pointer to a GdmDisplay structure
|
|
726 |
*
|
|
727 |
* Starts a local X server. Handles retries and fatal errors properly.
|
|
728 |
*/
|
|
729 |
||
730 |
gboolean
|
|
731 |
gdm_server_start (GdmServer *server) |
|
732 |
{
|
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
733 |
gboolean res = FALSE; |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
734 |
const char *vtarg = NULL; |
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
735 |
GError *local_error = NULL; |
736 |
GError **error = &local_error; |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
737 |
|
738 |
/* Hardcode the VT for the initial X server, but nothing else */
|
|
739 |
if (server->priv->is_initial) { |
|
740 |
vtarg = "vt" GDM_INITIAL_VT; |
|
741 |
||
742 |
#ifdef WITH_SYSTEMD
|
|
743 |
/* undo the hardcoding if we are an auxillary seat */
|
|
274
by Martin Pitt
* Add debian/patches/00git_logind_check.patch: Fix checks for logind. |
744 |
if (LOGIND_RUNNING()) { |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
745 |
if (strcmp (server->priv->display_seat_id, "seat0") != 0) { |
746 |
vtarg = NULL; |
|
747 |
}
|
|
748 |
}
|
|
749 |
#endif
|
|
750 |
}
|
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
751 |
|
752 |
/* fork X server process */
|
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
753 |
if (!gdm_server_spawn (server, vtarg, error)) { |
754 |
goto out; |
|
755 |
}
|
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
756 |
|
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
757 |
res = TRUE; |
758 |
out: |
|
759 |
if (local_error) { |
|
760 |
g_printerr ("%s\n", local_error->message); |
|
761 |
g_clear_error (&local_error); |
|
762 |
}
|
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
763 |
return res; |
764 |
}
|
|
765 |
||
766 |
static void |
|
767 |
server_died (GdmServer *server) |
|
768 |
{
|
|
769 |
int exit_status; |
|
770 |
||
771 |
g_debug ("GdmServer: Waiting on process %d", server->priv->pid); |
|
772 |
exit_status = gdm_wait_on_pid (server->priv->pid); |
|
773 |
||
774 |
if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) { |
|
775 |
g_debug ("GdmServer: Wait on child process failed"); |
|
776 |
} else { |
|
777 |
/* exited normally */
|
|
778 |
}
|
|
779 |
||
780 |
g_spawn_close_pid (server->priv->pid); |
|
781 |
server->priv->pid = -1; |
|
782 |
||
783 |
if (server->priv->display_device != NULL) { |
|
784 |
g_free (server->priv->display_device); |
|
785 |
server->priv->display_device = NULL; |
|
786 |
g_object_notify (G_OBJECT (server), "display-device"); |
|
787 |
}
|
|
788 |
||
789 |
g_debug ("GdmServer: Server died"); |
|
790 |
}
|
|
791 |
||
792 |
gboolean
|
|
793 |
gdm_server_stop (GdmServer *server) |
|
794 |
{
|
|
795 |
int res; |
|
796 |
||
797 |
if (server->priv->pid <= 1) { |
|
798 |
return TRUE; |
|
799 |
}
|
|
800 |
||
801 |
/* remove watch source before we can wait on child */
|
|
802 |
if (server->priv->child_watch_id > 0) { |
|
803 |
g_source_remove (server->priv->child_watch_id); |
|
804 |
server->priv->child_watch_id = 0; |
|
805 |
}
|
|
806 |
||
807 |
g_debug ("GdmServer: Stopping server"); |
|
808 |
||
809 |
res = gdm_signal_pid (server->priv->pid, SIGTERM); |
|
810 |
if (res < 0) { |
|
811 |
} else { |
|
812 |
server_died (server); |
|
813 |
}
|
|
814 |
||
815 |
return TRUE; |
|
816 |
}
|
|
817 |
||
818 |
||
819 |
static void |
|
820 |
_gdm_server_set_display_name (GdmServer *server, |
|
821 |
const char *name) |
|
822 |
{
|
|
823 |
g_free (server->priv->display_name); |
|
824 |
server->priv->display_name = g_strdup (name); |
|
825 |
}
|
|
826 |
||
827 |
static void |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
828 |
_gdm_server_set_display_seat_id (GdmServer *server, |
829 |
const char *name) |
|
830 |
{
|
|
831 |
g_free (server->priv->display_seat_id); |
|
832 |
server->priv->display_seat_id = g_strdup (name); |
|
833 |
}
|
|
834 |
||
835 |
static void |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
836 |
_gdm_server_set_auth_file (GdmServer *server, |
837 |
const char *auth_file) |
|
838 |
{
|
|
839 |
g_free (server->priv->auth_file); |
|
840 |
server->priv->auth_file = g_strdup (auth_file); |
|
841 |
}
|
|
842 |
||
843 |
static void |
|
844 |
_gdm_server_set_user_name (GdmServer *server, |
|
845 |
const char *name) |
|
846 |
{
|
|
847 |
g_free (server->priv->user_name); |
|
848 |
server->priv->user_name = g_strdup (name); |
|
849 |
}
|
|
850 |
||
851 |
static void |
|
852 |
_gdm_server_set_disable_tcp (GdmServer *server, |
|
853 |
gboolean disabled) |
|
854 |
{
|
|
855 |
server->priv->disable_tcp = disabled; |
|
856 |
}
|
|
857 |
||
858 |
static void |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
859 |
_gdm_server_set_is_initial (GdmServer *server, |
860 |
gboolean initial) |
|
861 |
{
|
|
862 |
server->priv->is_initial = initial; |
|
863 |
}
|
|
864 |
||
865 |
static void |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
866 |
gdm_server_set_property (GObject *object, |
867 |
guint prop_id, |
|
868 |
const GValue *value, |
|
869 |
GParamSpec *pspec) |
|
870 |
{
|
|
871 |
GdmServer *self; |
|
872 |
||
873 |
self = GDM_SERVER (object); |
|
874 |
||
875 |
switch (prop_id) { |
|
876 |
case PROP_DISPLAY_NAME: |
|
877 |
_gdm_server_set_display_name (self, g_value_get_string (value)); |
|
878 |
break; |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
879 |
case PROP_DISPLAY_SEAT_ID: |
880 |
_gdm_server_set_display_seat_id (self, g_value_get_string (value)); |
|
881 |
break; |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
882 |
case PROP_AUTH_FILE: |
883 |
_gdm_server_set_auth_file (self, g_value_get_string (value)); |
|
884 |
break; |
|
885 |
case PROP_USER_NAME: |
|
886 |
_gdm_server_set_user_name (self, g_value_get_string (value)); |
|
887 |
break; |
|
888 |
case PROP_DISABLE_TCP: |
|
889 |
_gdm_server_set_disable_tcp (self, g_value_get_boolean (value)); |
|
890 |
break; |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
891 |
case PROP_IS_INITIAL: |
892 |
_gdm_server_set_is_initial (self, g_value_get_boolean (value)); |
|
893 |
break; |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
894 |
default: |
895 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
|
896 |
break; |
|
897 |
}
|
|
898 |
}
|
|
899 |
||
900 |
static void |
|
901 |
gdm_server_get_property (GObject *object, |
|
902 |
guint prop_id, |
|
903 |
GValue *value, |
|
904 |
GParamSpec *pspec) |
|
905 |
{
|
|
906 |
GdmServer *self; |
|
907 |
||
908 |
self = GDM_SERVER (object); |
|
909 |
||
910 |
switch (prop_id) { |
|
911 |
case PROP_DISPLAY_NAME: |
|
912 |
g_value_set_string (value, self->priv->display_name); |
|
913 |
break; |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
914 |
case PROP_DISPLAY_SEAT_ID: |
915 |
g_value_set_string (value, self->priv->display_seat_id); |
|
916 |
break; |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
917 |
case PROP_DISPLAY_DEVICE: |
918 |
g_value_take_string (value, |
|
919 |
gdm_server_get_display_device (self)); |
|
920 |
break; |
|
921 |
case PROP_AUTH_FILE: |
|
922 |
g_value_set_string (value, self->priv->auth_file); |
|
923 |
break; |
|
924 |
case PROP_USER_NAME: |
|
925 |
g_value_set_string (value, self->priv->user_name); |
|
926 |
break; |
|
927 |
case PROP_DISABLE_TCP: |
|
928 |
g_value_set_boolean (value, self->priv->disable_tcp); |
|
929 |
break; |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
930 |
case PROP_IS_INITIAL: |
931 |
g_value_set_boolean (value, self->priv->is_initial); |
|
932 |
break; |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
933 |
default: |
934 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
|
935 |
break; |
|
936 |
}
|
|
937 |
}
|
|
938 |
||
939 |
static void |
|
940 |
gdm_server_class_init (GdmServerClass *klass) |
|
941 |
{
|
|
942 |
GObjectClass *object_class = G_OBJECT_CLASS (klass); |
|
943 |
||
944 |
object_class->get_property = gdm_server_get_property; |
|
945 |
object_class->set_property = gdm_server_set_property; |
|
946 |
object_class->finalize = gdm_server_finalize; |
|
947 |
||
948 |
g_type_class_add_private (klass, sizeof (GdmServerPrivate)); |
|
949 |
||
950 |
signals [READY] = |
|
951 |
g_signal_new ("ready", |
|
952 |
G_TYPE_FROM_CLASS (object_class), |
|
953 |
G_SIGNAL_RUN_LAST, |
|
954 |
G_STRUCT_OFFSET (GdmServerClass, ready), |
|
955 |
NULL, |
|
956 |
NULL, |
|
957 |
g_cclosure_marshal_VOID__VOID, |
|
958 |
G_TYPE_NONE, |
|
959 |
0); |
|
960 |
signals [EXITED] = |
|
961 |
g_signal_new ("exited", |
|
962 |
G_OBJECT_CLASS_TYPE (object_class), |
|
963 |
G_SIGNAL_RUN_FIRST, |
|
964 |
G_STRUCT_OFFSET (GdmServerClass, exited), |
|
965 |
NULL, |
|
966 |
NULL, |
|
967 |
g_cclosure_marshal_VOID__INT, |
|
968 |
G_TYPE_NONE, |
|
969 |
1, |
|
970 |
G_TYPE_INT); |
|
971 |
signals [DIED] = |
|
972 |
g_signal_new ("died", |
|
973 |
G_OBJECT_CLASS_TYPE (object_class), |
|
974 |
G_SIGNAL_RUN_FIRST, |
|
975 |
G_STRUCT_OFFSET (GdmServerClass, died), |
|
976 |
NULL, |
|
977 |
NULL, |
|
978 |
g_cclosure_marshal_VOID__INT, |
|
979 |
G_TYPE_NONE, |
|
980 |
1, |
|
981 |
G_TYPE_INT); |
|
982 |
||
983 |
g_object_class_install_property (object_class, |
|
984 |
PROP_DISPLAY_NAME, |
|
985 |
g_param_spec_string ("display-name", |
|
986 |
"name", |
|
987 |
"name", |
|
988 |
NULL, |
|
989 |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); |
|
990 |
g_object_class_install_property (object_class, |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
991 |
PROP_DISPLAY_SEAT_ID, |
992 |
g_param_spec_string ("display-seat-id", |
|
993 |
"Seat ID", |
|
994 |
"ID of the seat this display is running on", |
|
995 |
NULL, |
|
996 |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); |
|
997 |
g_object_class_install_property (object_class, |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
998 |
PROP_DISPLAY_DEVICE, |
999 |
g_param_spec_string ("display-device", |
|
1000 |
"Display Device", |
|
1001 |
"Path to terminal display is running on", |
|
1002 |
NULL, |
|
1003 |
G_PARAM_READABLE)); |
|
1004 |
g_object_class_install_property (object_class, |
|
1005 |
PROP_AUTH_FILE, |
|
1006 |
g_param_spec_string ("auth-file", |
|
1007 |
"Authorization File", |
|
1008 |
"Path to X authorization file", |
|
1009 |
NULL, |
|
1010 |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); |
|
1011 |
||
1012 |
g_object_class_install_property (object_class, |
|
1013 |
PROP_USER_NAME, |
|
1014 |
g_param_spec_string ("user-name", |
|
1015 |
"user name", |
|
1016 |
"user name", |
|
1017 |
NULL, |
|
1018 |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); |
|
1019 |
g_object_class_install_property (object_class, |
|
1020 |
PROP_DISABLE_TCP, |
|
1021 |
g_param_spec_boolean ("disable-tcp", |
|
1022 |
NULL, |
|
1023 |
NULL, |
|
1024 |
TRUE, |
|
1025 |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
1026 |
g_object_class_install_property (object_class, |
1027 |
PROP_IS_INITIAL, |
|
1028 |
g_param_spec_boolean ("is-initial", |
|
1029 |
NULL, |
|
1030 |
NULL, |
|
1031 |
FALSE, |
|
1032 |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
1033 |
}
|
1034 |
||
1035 |
static void |
|
1036 |
gdm_server_init (GdmServer *server) |
|
1037 |
{
|
|
1038 |
||
1039 |
server->priv = GDM_SERVER_GET_PRIVATE (server); |
|
1040 |
||
1041 |
server->priv->pid = -1; |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
1042 |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
1043 |
server->priv->log_dir = g_strdup (LOGDIR); |
1044 |
||
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
1045 |
server->priv->sigusr1_id = g_unix_signal_add (SIGUSR1, |
1046 |
on_sigusr1, |
|
1047 |
server); |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
1048 |
}
|
1049 |
||
1050 |
static void |
|
1051 |
gdm_server_finalize (GObject *object) |
|
1052 |
{
|
|
1053 |
GdmServer *server; |
|
1054 |
||
1055 |
g_return_if_fail (object != NULL); |
|
1056 |
g_return_if_fail (GDM_IS_SERVER (object)); |
|
1057 |
||
1058 |
server = GDM_SERVER (object); |
|
1059 |
||
1060 |
g_return_if_fail (server->priv != NULL); |
|
1061 |
||
1.4.55
by Jeremy Bicha
Import upstream version 3.8.1.1 |
1062 |
if (server->priv->sigusr1_id > 0) |
1063 |
g_source_remove (server->priv->sigusr1_id); |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
1064 |
|
1065 |
gdm_server_stop (server); |
|
1066 |
||
1.4.45
by Kees Cook
Import upstream version 2.30.4 |
1067 |
g_free (server->priv->command); |
1068 |
g_free (server->priv->user_name); |
|
1069 |
g_free (server->priv->session_args); |
|
1070 |
g_free (server->priv->log_dir); |
|
1071 |
g_free (server->priv->display_name); |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
1072 |
g_free (server->priv->display_seat_id); |
1.4.45
by Kees Cook
Import upstream version 2.30.4 |
1073 |
g_free (server->priv->display_device); |
1074 |
g_free (server->priv->auth_file); |
|
1075 |
g_free (server->priv->parent_display_name); |
|
1076 |
g_free (server->priv->parent_auth_file); |
|
1077 |
g_free (server->priv->chosen_hostname); |
|
1078 |
||
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
1079 |
G_OBJECT_CLASS (gdm_server_parent_class)->finalize (object); |
1080 |
}
|
|
1081 |
||
1082 |
GdmServer * |
|
1083 |
gdm_server_new (const char *display_name, |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
1084 |
const char *seat_id, |
1085 |
const char *auth_file, |
|
1086 |
gboolean initial) |
|
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
1087 |
{
|
1088 |
GObject *object; |
|
1089 |
||
1090 |
object = g_object_new (GDM_TYPE_SERVER, |
|
1091 |
"display-name", display_name, |
|
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
1092 |
"display-seat-id", seat_id, |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
1093 |
"auth-file", auth_file, |
1.4.50
by Fabien Tassin
Import upstream version 3.5.90+git20120827.b558e179 |
1094 |
"is-initial", initial, |
1.4.31
by Sebastien Bacher
Import upstream version 2.26.1 |
1095 |
NULL); |
1096 |
||
1097 |
return GDM_SERVER (object); |
|
1098 |
}
|