aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-multimedia/pulseaudio/pulseaudio/0001-systemd-complement-module-console-kit-with-module-sy.patch
blob: 456e04f64c9998473e8b776e5f6f6126d8bd3e2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
From 860d1cf3a76701ade38784822abb24285176227c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sat, 17 Mar 2012 01:52:41 +0100
Subject: [PATCH 01/47] systemd: complement module-console-kit with
 module-systemd-login

ConsoleKit has been deprecated and replaced by systemd's logind daemon,
hence provide the same functionality of module-console-kit in
module-systemd-login. This also makes sure that the CK module becomes a
NOP if the system is booted with systemd, resp. that the systemd module
becomes a NOP if the system is booted without systemd, thus being nice
to OSes such as Debian which want to support multiple init systems.
---
 configure.ac                       |   18 +++
 src/Makefile.am                    |   15 ++-
 src/daemon/default.pa.in           |    3 +
 src/modules/module-console-kit.c   |   12 ++
 src/modules/module-systemd-login.c |  243 ++++++++++++++++++++++++++++++++++++
 5 files changed, 289 insertions(+), 2 deletions(-)
 create mode 100644 src/modules/module-systemd-login.c

diff --git a/configure.ac b/configure.ac
index 8d7f43a..7bdd401 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1108,6 +1108,22 @@ AM_CONDITIONAL([HAVE_XEN], [test "x$HAVE_XEN" = x1])
 
 ORC_CHECK([0.4.11])
 
+#### systemd support (optional) ####
+
+AC_ARG_ENABLE([systemd],
+    AS_HELP_STRING([--disable-systemd],[Disable optional systemd support]))
+
+AS_IF([test "x$enable_systemd" != "xno"],
+    [PKG_CHECK_MODULES(SYSTEMD, [ libsystemd-login libsystemd-daemon ], HAVE_SYSTEMD=1, HAVE_SYSTEMD=0)],
+    HAVE_SYSTEMD=0)
+
+AS_IF([test "x$enable_systemd" = "xyes" && test "x$HAVE_SYSTEMD" = "x0"],
+    [AC_MSG_ERROR([*** Needed systemd support not found])])
+
+AC_SUBST(HAVE_SYSTEMD)
+AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$HAVE_SYSTEMD" = x1])
+AS_IF([test "x$HAVE_SYSTEMD" = "x1"], AC_DEFINE([HAVE_SYSTEMD], 1, [Have SYSTEMD?]))
+
 #### Build and Install man pages ####
 
 AC_ARG_ENABLE([manpages],
@@ -1361,6 +1377,7 @@ AS_IF([test "x$HAVE_XEN" = "x1"], ENABLE_XEN=yes, ENABLE_XEN=no)
 AS_IF([test "x$HAVE_DBUS" = "x1"], ENABLE_DBUS=yes, ENABLE_DBUS=no)
 AS_IF([test "x$HAVE_HAL" = "x1"], ENABLE_HAL=yes, ENABLE_HAL=no)
 AS_IF([test "x$HAVE_UDEV" = "x1"], ENABLE_UDEV=yes, ENABLE_UDEV=no)
+AS_IF([test "x$HAVE_SYSTEMD" = "x1"], ENABLE_SYSTEMD=yes, ENABLE_SYSTEMD=no)
 AS_IF([test "x$HAVE_BLUEZ" = "x1"], ENABLE_BLUEZ=yes, ENABLE_BLUEZ=no)
 AS_IF([test "x$HAVE_HAL_COMPAT" = "x1"], ENABLE_HAL_COMPAT=yes, ENABLE_HAL_COMPAT=no)
 AS_IF([test "x$HAVE_TCPWRAP" = "x1"], ENABLE_TCPWRAP=yes, ENABLE_TCPWRAP=no)
@@ -1415,6 +1432,7 @@ echo "
       Enable BlueZ:                ${ENABLE_BLUEZ}
     Enable udev:                   ${ENABLE_UDEV}
       Enable HAL->udev compat:     ${ENABLE_HAL_COMPAT}
+    Enable systemd login:          ${ENABLE_SYSTEMD}
     Enable TCP Wrappers:           ${ENABLE_TCPWRAP}
     Enable libsamplerate:          ${ENABLE_LIBSAMPLERATE}
     Enable IPv6:                   ${ENABLE_IPV6}
diff --git a/src/Makefile.am b/src/Makefile.am
index 034981c..0451da0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1218,6 +1218,11 @@ modlibexec_LTLIBRARIES += \
 		module-udev-detect.la
 endif
 
+if HAVE_SYSTEMD
+modlibexec_LTLIBRARIES += \
+		module-systemd-login.la
+endif
+
 if HAVE_DBUS
 modlibexec_LTLIBRARIES += \
 		module-rygel-media-server.la \
@@ -1319,6 +1324,7 @@ SYMDEF_FILES = \
 		module-echo-cancel-symdef.h \
 		module-hal-detect-symdef.h \
 		module-udev-detect-symdef.h \
+		module-systemd-login-symdef.h \
 		module-bluetooth-proximity-symdef.h \
 		module-bluetooth-discover-symdef.h \
 		module-bluetooth-device-symdef.h \
@@ -1876,8 +1882,13 @@ module_udev_detect_la_CFLAGS = $(AM_CFLAGS) $(UDEV_CFLAGS)
 
 module_console_kit_la_SOURCES = modules/module-console-kit.c
 module_console_kit_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_console_kit_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS)
-module_console_kit_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+module_console_kit_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(SYSTEMD_LIBS)
+module_console_kit_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) $(SYSTEMD_CFLAGS)
+
+module_systemd_login_la_SOURCES = modules/module-systemd-login.c
+module_systemd_login_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_systemd_login_la_LIBADD = $(MODULE_LIBADD) $(SYSTEMD_LIBS)
+module_systemd_login_la_CFLAGS = $(AM_CFLAGS) $(SYSTEMD_CFLAGS)
 
 # GConf support
 module_gconf_la_SOURCES = modules/gconf/module-gconf.c
diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
index 633bb77..88b5944 100755
--- a/src/daemon/default.pa.in
+++ b/src/daemon/default.pa.in
@@ -150,6 +150,9 @@ load-module module-suspend-on-idle
 .ifexists module-console-kit@PA_SOEXT@
 load-module module-console-kit
 .endif
+.ifexists module-systemd-login@PA_SOEXT@
+load-module module-systemd-login
+.endif
 
 ### Enable positioned event sounds
 load-module module-position-event-sounds
diff --git a/src/modules/module-console-kit.c b/src/modules/module-console-kit.c
index 4c5857c..29f7e66 100644
--- a/src/modules/module-console-kit.c
+++ b/src/modules/module-console-kit.c
@@ -30,6 +30,11 @@
 #include <stdlib.h>
 #include <sys/types.h>
 
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-login.h>
+#include <systemd/sd-daemon.h>
+#endif
+
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/module.h>
@@ -280,6 +285,13 @@ int pa__init(pa_module*m) {
 
     dbus_error_init(&error);
 
+#ifdef HAVE_SYSTEMD
+    /* If systemd support is enabled and we boot on systemd we
+       shouldn't watch ConsoleKit but systemd's logind service. */
+    if (sd_booted() > 0)
+        return 0;
+#endif
+
     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
         pa_log("Failed to parse module arguments");
         goto fail;
diff --git a/src/modules/module-systemd-login.c b/src/modules/module-systemd-login.c
new file mode 100644
index 0000000..024c1eb
--- /dev/null
+++ b/src/modules/module-systemd-login.c
@@ -0,0 +1,243 @@
+/***
+    This file is part of PulseAudio.
+
+    Copyright 2012 Lennart Poettering
+
+    PulseAudio is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License,
+    or (at your option) any later version.
+
+    PulseAudio is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with PulseAudio; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+    USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <systemd/sd-login.h>
+#include <systemd/sd-daemon.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/module.h>
+#include <pulsecore/log.h>
+#include <pulsecore/hashmap.h>
+#include <pulsecore/idxset.h>
+#include <pulsecore/modargs.h>
+
+#include "module-systemd-login-symdef.h"
+
+PA_MODULE_AUTHOR("Lennart Poettering");
+PA_MODULE_DESCRIPTION("Create a client for each login session of this user");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+
+static const char* const valid_modargs[] = {
+    NULL
+};
+
+struct session {
+    char *id;
+    pa_client *client;
+};
+
+struct userdata {
+    pa_module *module;
+    pa_core *core;
+    pa_hashmap *sessions, *previous_sessions;
+    sd_login_monitor *monitor;
+    pa_io_event *io;
+};
+
+static int add_session(struct userdata *u, const char *id) {
+    struct session *session;
+    pa_client_new_data data;
+
+    session = pa_xnew(struct session, 1);
+    session->id = pa_xstrdup(id);
+
+    pa_client_new_data_init(&data);
+    data.module = u->module;
+    data.driver = __FILE__;
+    pa_proplist_setf(data.proplist, PA_PROP_APPLICATION_NAME, "Login Session %s", id);
+    pa_proplist_sets(data.proplist, "systemd-login.session", id);
+    session->client = pa_client_new(u->core, &data);
+    pa_client_new_data_done(&data);
+
+    if (!session->client) {
+        pa_xfree(session->id);
+        pa_xfree(session);
+        return -1;
+    }
+
+    pa_hashmap_put(u->sessions, session->id, session);
+
+    pa_log_debug("Added new session %s", id);
+    return 0;
+}
+
+static void free_session(struct session *session) {
+    pa_assert(session);
+
+    pa_log_debug("Removing session %s", session->id);
+
+    pa_client_free(session->client);
+    pa_xfree(session->id);
+    pa_xfree(session);
+}
+
+static int get_session_list(struct userdata *u) {
+    int r;
+    char **sessions;
+    pa_hashmap *h;
+    struct session *o;
+
+    pa_assert(u);
+
+    r = sd_uid_get_sessions(getuid(), 0, &sessions);
+    if (r < 0)
+        return -1;
+
+    /* We copy all sessions that still exist from one hashmap to the
+     * other and then flush the remaining ones */
+
+    h = u->previous_sessions;
+    u->previous_sessions = u->sessions;
+    u->sessions = h;
+
+    if (sessions) {
+        char **s;
+
+        /* Note that the sessions array is allocated with libc's
+         * malloc()/free() calls, hence do not use pa_xfree() to free
+         * this here. */
+
+        for (s = sessions; *s; s++) {
+            o = pa_hashmap_remove(u->previous_sessions, *s);
+            if (o)
+                pa_hashmap_put(u->sessions, o->id, o);
+            else
+                add_session(u, *s);
+
+            free(*s);
+        }
+
+        free(sessions);
+    }
+
+    while ((o = pa_hashmap_steal_first(u->previous_sessions)))
+        free_session(o);
+
+    return 0;
+}
+
+static void monitor_cb(
+        pa_mainloop_api*a,
+        pa_io_event* e,
+        int fd,
+        pa_io_event_flags_t events,
+        void *userdata) {
+
+    struct userdata *u = userdata;
+
+    pa_assert(u);
+
+    sd_login_monitor_flush(u->monitor);
+    get_session_list(u);
+}
+
+int pa__init(pa_module *m) {
+    struct userdata *u = NULL;
+    pa_modargs *ma;
+    sd_login_monitor *monitor = NULL;
+    int r;
+
+    pa_assert(m);
+
+    /* If we are not actually booting with systemd become a NOP */
+    if (sd_booted() <= 0)
+        return 0;
+
+    ma = pa_modargs_new(m->argument, valid_modargs);
+    if (!ma) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    r = sd_login_monitor_new("session", &monitor);
+    if (r < 0) {
+        pa_log("Failed to create session monitor: %s", strerror(-r));
+        goto fail;
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->core = m->core;
+    u->module = m;
+    u->sessions = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    u->previous_sessions = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    u->monitor = monitor;
+
+    u->io = u->core->mainloop->io_new(u->core->mainloop, sd_login_monitor_get_fd(monitor), PA_IO_EVENT_INPUT, monitor_cb, u);
+
+    if (get_session_list(u) < 0)
+        goto fail;
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+    struct session *session;
+
+    pa_assert(m);
+
+    u = m->userdata;
+    if (!u)
+        return;
+
+    if (u->sessions) {
+        while ((session = pa_hashmap_steal_first(u->sessions)))
+            free_session(session);
+
+        pa_hashmap_free(u->sessions, NULL, NULL);
+
+        while ((session = pa_hashmap_steal_first(u->previous_sessions)))
+            free_session(session);
+
+        pa_hashmap_free(u->previous_sessions, NULL, NULL);
+    }
+
+    if (u->io)
+        m->core->mainloop->io_free(u->io);
+
+    if (u->monitor)
+        sd_login_monitor_unref(u->monitor);
+
+    pa_xfree(u);
+}
-- 
1.7.5.4