1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2008 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <errno.h>
32 #include <signal.h>
33
34 #ifdef HAVE_SYS_WAIT_H
35 #include <sys/wait.h>
36 #endif
37
38 #ifdef HAVE_NETDB_H
39 #include <netdb.h>
40 #endif
41
42 #include <pulse/version.h>
43 #include <pulse/xmalloc.h>
44 #include <pulse/util.h>
45 #include <pulse/mainloop.h>
46 #include <pulse/timeval.h>
47 #include <pulse/fork-detect.h>
48 #include <pulse/client-conf.h>
49
50 #include <pulsecore/core-error.h>
51 #include <pulsecore/i18n.h>
52 #include <pulsecore/native-common.h>
53 #include <pulsecore/pdispatch.h>
54 #include <pulsecore/pstream.h>
55 #include <pulsecore/hashmap.h>
56 #include <pulsecore/socket-client.h>
57 #include <pulsecore/pstream-util.h>
58 #include <pulsecore/core-rtclock.h>
59 #include <pulsecore/core-util.h>
60 #include <pulsecore/log.h>
61 #include <pulsecore/socket.h>
62 #include <pulsecore/creds.h>
63 #include <pulsecore/macro.h>
64 #include <pulsecore/proplist-util.h>
65
66 #include "log/audio_log.h"
67
68 #include "internal.h"
69 #include "context.h"
70
71 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
72 static void pa_command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
73 static void pa_command_disable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
74 static void pa_command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
75
76 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
77 [PA_COMMAND_REQUEST] = pa_command_request,
78 [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
79 [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow,
80 [PA_COMMAND_PLAYBACK_STREAM_KILLED] = pa_command_stream_killed,
81 [PA_COMMAND_RECORD_STREAM_KILLED] = pa_command_stream_killed,
82 [PA_COMMAND_PLAYBACK_STREAM_MOVED] = pa_command_stream_moved,
83 [PA_COMMAND_RECORD_STREAM_MOVED] = pa_command_stream_moved,
84 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = pa_command_stream_suspended,
85 [PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended,
86 [PA_COMMAND_STARTED] = pa_command_stream_started,
87 [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
88 [PA_COMMAND_EXTENSION] = pa_command_extension,
89 [PA_COMMAND_PLAYBACK_STREAM_EVENT] = pa_command_stream_event,
90 [PA_COMMAND_RECORD_STREAM_EVENT] = pa_command_stream_event,
91 [PA_COMMAND_CLIENT_EVENT] = pa_command_client_event,
92 [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr,
93 [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr,
94 [PA_COMMAND_ENABLE_SRBCHANNEL] = pa_command_enable_srbchannel,
95 [PA_COMMAND_DISABLE_SRBCHANNEL] = pa_command_disable_srbchannel,
96 [PA_COMMAND_REGISTER_MEMFD_SHMID] = pa_command_register_memfd_shmid,
97 };
98 static void context_free(pa_context *c);
99
100 #ifdef HAVE_DBUS
101 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata);
102 #endif
103
pa_context_new(pa_mainloop_api * mainloop,const char * name)104 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
105 return pa_context_new_with_proplist(mainloop, name, NULL);
106 }
107
reset_callbacks(pa_context * c)108 static void reset_callbacks(pa_context *c) {
109 pa_assert(c);
110
111 c->state_callback = NULL;
112 c->state_userdata = NULL;
113
114 c->subscribe_callback = NULL;
115 c->subscribe_userdata = NULL;
116
117 c->event_callback = NULL;
118 c->event_userdata = NULL;
119
120 c->ext_device_manager.callback = NULL;
121 c->ext_device_manager.userdata = NULL;
122
123 c->ext_device_restore.callback = NULL;
124 c->ext_device_restore.userdata = NULL;
125
126 c->ext_stream_restore.callback = NULL;
127 c->ext_stream_restore.userdata = NULL;
128 }
129
pa_context_new_with_proplist(pa_mainloop_api * mainloop,const char * name,const pa_proplist * p)130 pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, const pa_proplist *p) {
131 pa_context *c;
132 pa_mem_type_t type;
133
134 pa_assert(mainloop);
135
136 if (pa_detect_fork())
137 return NULL;
138
139 pa_init_i18n();
140
141 c = pa_xnew0(pa_context, 1);
142 PA_REFCNT_INIT(c);
143
144 c->error = pa_xnew0(pa_context_error, 1);
145 assert(c->error);
146
147 c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
148
149 if (name)
150 pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
151
152 #ifdef HAVE_DBUS
153 c->system_bus = c->session_bus = NULL;
154 #endif
155 c->mainloop = mainloop;
156 c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
157 c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
158 c->client_index = PA_INVALID_INDEX;
159 c->use_rtclock = pa_mainloop_is_our_api(mainloop);
160
161 PA_LLIST_HEAD_INIT(pa_stream, c->streams);
162 PA_LLIST_HEAD_INIT(pa_operation, c->operations);
163
164 c->error->error = PA_OK;
165 c->state = PA_CONTEXT_UNCONNECTED;
166
167 reset_callbacks(c);
168
169 #ifndef MSG_NOSIGNAL
170 #ifdef SIGPIPE
171 pa_check_signal_is_blocked(SIGPIPE);
172 #endif
173 #endif
174
175 c->conf = pa_client_conf_new();
176 pa_client_conf_load(c->conf, true, true);
177
178 c->srb_template.readfd = -1;
179 c->srb_template.writefd = -1;
180
181 c->memfd_on_local = (!c->conf->disable_memfd && pa_memfd_is_locally_supported());
182
183 type = (c->conf->disable_shm) ? PA_MEM_TYPE_PRIVATE :
184 ((!c->memfd_on_local) ?
185 PA_MEM_TYPE_SHARED_POSIX : PA_MEM_TYPE_SHARED_MEMFD);
186
187 if (!(c->mempool = pa_mempool_new(type, c->conf->shm_size, true))) {
188
189 if (!c->conf->disable_shm) {
190 pa_log_warn("Failed to allocate shared memory pool. Falling back to a normal private one.");
191 c->mempool = pa_mempool_new(PA_MEM_TYPE_PRIVATE, c->conf->shm_size, true);
192 }
193
194 if (!c->mempool) {
195 context_free(c);
196 return NULL;
197 }
198 }
199
200 return c;
201 }
202
context_unlink(pa_context * c)203 static void context_unlink(pa_context *c) {
204 pa_stream *s;
205
206 pa_assert(c);
207
208 s = c->streams ? pa_stream_ref(c->streams) : NULL;
209 while (s) {
210 pa_stream *n = s->next ? pa_stream_ref(s->next) : NULL;
211 pa_stream_set_state(s, c->state == PA_CONTEXT_FAILED ? PA_STREAM_FAILED : PA_STREAM_TERMINATED);
212 pa_stream_unref(s);
213 s = n;
214 }
215
216 while (c->operations)
217 pa_operation_cancel(c->operations);
218
219 if (c->pdispatch) {
220 pa_pdispatch_unref(c->pdispatch);
221 c->pdispatch = NULL;
222 }
223
224 if (c->pstream) {
225 pa_pstream_unlink(c->pstream);
226 pa_pstream_unref(c->pstream);
227 c->pstream = NULL;
228 }
229
230 if (c->srb_template.memblock) {
231 pa_memblock_unref(c->srb_template.memblock);
232 c->srb_template.memblock = NULL;
233 }
234
235 if (c->client) {
236 pa_socket_client_unref(c->client);
237 c->client = NULL;
238 }
239
240 reset_callbacks(c);
241 }
242
context_free(pa_context * c)243 static void context_free(pa_context *c) {
244 pa_assert(c);
245
246 context_unlink(c);
247
248 #ifdef HAVE_DBUS
249 if (c->system_bus) {
250 if (c->filter_added)
251 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->system_bus), filter_cb, c);
252 pa_dbus_wrap_connection_free(c->system_bus);
253 }
254
255 if (c->session_bus) {
256 if (c->filter_added)
257 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->session_bus), filter_cb, c);
258 pa_dbus_wrap_connection_free(c->session_bus);
259 }
260 #endif
261
262 if (c->record_streams)
263 pa_hashmap_free(c->record_streams);
264 if (c->playback_streams)
265 pa_hashmap_free(c->playback_streams);
266
267 if (c->mempool)
268 pa_mempool_unref(c->mempool);
269
270 if (c->conf)
271 pa_client_conf_free(c->conf);
272
273 pa_strlist_free(c->server_list);
274
275 if (c->proplist)
276 pa_proplist_free(c->proplist);
277
278 pa_xfree(c->server);
279 pa_xfree(c->error);
280 pa_xfree(c);
281 }
282
pa_context_ref(pa_context * c)283 pa_context* pa_context_ref(pa_context *c) {
284 pa_assert(c);
285 pa_assert(PA_REFCNT_VALUE(c) >= 1);
286
287 PA_REFCNT_INC(c);
288 return c;
289 }
290
pa_context_unref(pa_context * c)291 void pa_context_unref(pa_context *c) {
292 pa_assert(c);
293 pa_assert(PA_REFCNT_VALUE(c) >= 1);
294
295 if (PA_REFCNT_DEC(c) <= 0)
296 context_free(c);
297 }
298
pa_context_set_state(pa_context * c,pa_context_state_t st)299 void pa_context_set_state(pa_context *c, pa_context_state_t st) {
300 pa_assert(c);
301 pa_assert(PA_REFCNT_VALUE(c) >= 1);
302
303 if (c->state == st)
304 return;
305
306 pa_context_ref(c);
307
308 c->state = st;
309
310 if (c->state_callback)
311 c->state_callback(c, c->state_userdata);
312
313 if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED)
314 context_unlink(c);
315
316 pa_context_unref(c);
317 }
318
pa_context_set_error(const pa_context * c,int error)319 int pa_context_set_error(const pa_context *c, int error) {
320 pa_assert(error >= 0);
321 pa_assert(error < PA_ERR_MAX);
322
323 if (c)
324 c->error->error = error;
325
326 return error;
327 }
328
pa_context_fail(pa_context * c,int error)329 void pa_context_fail(pa_context *c, int error) {
330 pa_assert(c);
331 pa_assert(PA_REFCNT_VALUE(c) >= 1);
332
333 pa_context_set_error(c, error);
334 pa_context_set_state(c, PA_CONTEXT_FAILED);
335 }
336
pstream_die_callback(pa_pstream * p,void * userdata)337 static void pstream_die_callback(pa_pstream *p, void *userdata) {
338 pa_context *c = userdata;
339
340 pa_assert(p);
341 pa_assert(c);
342
343 pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
344 }
345
pstream_packet_callback(pa_pstream * p,pa_packet * packet,pa_cmsg_ancil_data * ancil_data,void * userdata)346 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, pa_cmsg_ancil_data *ancil_data, void *userdata) {
347 pa_context *c = userdata;
348
349 pa_assert(p);
350 pa_assert(packet);
351 pa_assert(c);
352
353 pa_context_ref(c);
354
355 if (pa_pdispatch_run(c->pdispatch, packet, ancil_data, c) < 0)
356 pa_context_fail(c, PA_ERR_PROTOCOL);
357
358 pa_context_unref(c);
359 }
360
handle_srbchannel_memblock(pa_context * c,pa_memblock * memblock)361 static void handle_srbchannel_memblock(pa_context *c, pa_memblock *memblock) {
362 pa_srbchannel *sr;
363 pa_tagstruct *t;
364
365 pa_assert(c);
366
367 /* Memblock sanity check */
368 if (!memblock) {
369 pa_context_fail(c, PA_ERR_PROTOCOL);
370 return;
371 } else if (pa_memblock_is_read_only(memblock)) {
372 pa_context_fail(c, PA_ERR_PROTOCOL);
373 return;
374 } else if (pa_memblock_is_ours(memblock)) {
375 pa_context_fail(c, PA_ERR_PROTOCOL);
376 return;
377 }
378
379 /* Create the srbchannel */
380 c->srb_template.memblock = memblock;
381 pa_memblock_ref(memblock);
382 sr = pa_srbchannel_new_from_template(c->mainloop, &c->srb_template);
383 if (!sr) {
384 pa_log_warn("Failed to create srbchannel from template");
385 c->srb_template.readfd = -1;
386 c->srb_template.writefd = -1;
387 pa_memblock_unref(c->srb_template.memblock);
388 c->srb_template.memblock = NULL;
389 return;
390 }
391
392 /* Ack the enable command */
393 t = pa_tagstruct_new();
394 pa_tagstruct_putu32(t, PA_COMMAND_ENABLE_SRBCHANNEL);
395 pa_tagstruct_putu32(t, c->srb_setup_tag);
396 pa_pstream_send_tagstruct(c->pstream, t);
397
398 /* ...and switch over */
399 pa_pstream_set_srbchannel(c->pstream, sr);
400 }
401
pstream_memblock_callback(pa_pstream * p,uint32_t channel,int64_t offset,pa_seek_mode_t seek,const pa_memchunk * chunk,void * userdata)402 static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) {
403 pa_context *c = userdata;
404 pa_stream *s;
405
406 pa_assert(p);
407 pa_assert(chunk);
408 pa_assert(chunk->length > 0);
409 pa_assert(c);
410 pa_assert(PA_REFCNT_VALUE(c) >= 1);
411
412 pa_context_ref(c);
413
414 if (c->srb_template.readfd != -1 && c->srb_template.memblock == NULL) {
415 handle_srbchannel_memblock(c, chunk->memblock);
416 pa_context_unref(c);
417 return;
418 }
419
420 if ((s = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(channel)))) {
421
422 if (chunk->memblock) {
423 pa_memblockq_seek(s->record_memblockq, offset, seek, true);
424 pa_memblockq_push_align(s->record_memblockq, chunk);
425 } else
426 pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek, true);
427
428 if (s->read_callback) {
429 size_t l;
430
431 if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
432 s->read_callback(s, l, s->read_userdata);
433 }
434 }
435
436 pa_context_unref(c);
437 }
438
pa_context_handle_error(pa_context * c,uint32_t command,pa_tagstruct * t,bool fail)439 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, bool fail) {
440 uint32_t err;
441 pa_assert(c);
442 pa_assert(PA_REFCNT_VALUE(c) >= 1);
443
444 if (command == PA_COMMAND_ERROR) {
445 pa_assert(t);
446
447 if (pa_tagstruct_getu32(t, &err) < 0 ||
448 !pa_tagstruct_eof(t)) {
449 pa_context_fail(c, PA_ERR_PROTOCOL);
450 return -1;
451 }
452
453 } else if (command == PA_COMMAND_TIMEOUT)
454 err = PA_ERR_TIMEOUT;
455 else {
456 pa_context_fail(c, PA_ERR_PROTOCOL);
457 return -1;
458 }
459
460 if (err == PA_OK) {
461 pa_context_fail(c, PA_ERR_PROTOCOL);
462 return -1;
463 }
464
465 if (err >= PA_ERR_MAX)
466 err = PA_ERR_UNKNOWN;
467
468 if (fail) {
469 pa_context_fail(c, (int) err);
470 return -1;
471 }
472
473 pa_context_set_error(c, (int) err);
474
475 return 0;
476 }
477
setup_complete_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)478 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
479 pa_context *c = userdata;
480
481 pa_assert(pd);
482 pa_assert(c);
483 pa_assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME);
484
485 pa_context_ref(c);
486
487 if (command != PA_COMMAND_REPLY) {
488 pa_context_handle_error(c, command, t, true);
489 goto finish;
490 }
491
492 switch(c->state) {
493 case PA_CONTEXT_AUTHORIZING: {
494 pa_tagstruct *reply;
495 bool shm_on_remote = false;
496 bool memfd_on_remote = false;
497
498 if (pa_tagstruct_getu32(t, &c->version) < 0 ||
499 !pa_tagstruct_eof(t)) {
500 pa_context_fail(c, PA_ERR_PROTOCOL);
501 goto finish;
502 }
503
504 /* Minimum supported version */
505 if (c->version < 8) {
506 pa_context_fail(c, PA_ERR_VERSION);
507 goto finish;
508 }
509
510 /* Starting with protocol version 13 the MSB of the version
511 tag reflects if shm is available for this connection or
512 not. */
513 if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 13) {
514 shm_on_remote = !!(c->version & PA_PROTOCOL_FLAG_SHM);
515
516 /* Starting with protocol version 31, the second MSB of the version
517 * tag reflects whether memfd is supported on the other PA end. */
518 if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 31)
519 memfd_on_remote = !!(c->version & PA_PROTOCOL_FLAG_MEMFD);
520
521 /* Reserve the two most-significant _bytes_ of the version tag
522 * for flags. */
523 c->version &= PA_PROTOCOL_VERSION_MASK;
524 }
525
526 pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
527
528 /* Enable shared memory support if possible */
529 if (c->do_shm)
530 if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
531 c->do_shm = false;
532
533 if (c->do_shm) {
534
535 /* Only enable SHM if both sides are owned by the same
536 * user. This is a security measure because otherwise
537 * data private to the user might leak. */
538
539 #ifdef HAVE_CREDS
540 const pa_creds *creds;
541 if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
542 c->do_shm = false;
543 #endif
544 }
545
546 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c->do_shm));
547 pa_pstream_enable_shm(c->pstream, c->do_shm);
548
549 c->shm_type = PA_MEM_TYPE_PRIVATE;
550 if (c->do_shm) {
551 if (c->version >= 31 && memfd_on_remote && c->memfd_on_local) {
552 const char *reason;
553
554 pa_pstream_enable_memfd(c->pstream);
555 if (pa_mempool_is_memfd_backed(c->mempool))
556 if (pa_pstream_register_memfd_mempool(c->pstream, c->mempool, &reason))
557 pa_log("Failed to regester memfd mempool. Reason: %s", reason);
558
559 /* Even if memfd pool registration fails, the negotiated SHM type
560 * shall remain memfd as both endpoints claim to support it. */
561 c->shm_type = PA_MEM_TYPE_SHARED_MEMFD;
562 } else
563 c->shm_type = PA_MEM_TYPE_SHARED_POSIX;
564 }
565
566 AUDIO_INFO_LOG("Memfd possible: %{public}s", pa_yes_no(c->memfd_on_local));
567 AUDIO_INFO_LOG("Negotiated SHM type: %{public}s", pa_mem_type_to_string(c->shm_type));
568
569 reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
570
571 if (c->version >= 13) {
572 pa_init_proplist(c->proplist);
573 pa_tagstruct_put_proplist(reply, c->proplist);
574 } else
575 pa_tagstruct_puts(reply, pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME));
576
577 pa_pstream_send_tagstruct(c->pstream, reply);
578 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
579
580 pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
581 break;
582 }
583
584 case PA_CONTEXT_SETTING_NAME :
585
586 if ((c->version >= 13 && (pa_tagstruct_getu32(t, &c->client_index) < 0 ||
587 c->client_index == PA_INVALID_INDEX)) ||
588 !pa_tagstruct_eof(t)) {
589 pa_context_fail(c, PA_ERR_PROTOCOL);
590 goto finish;
591 }
592
593 pa_context_set_state(c, PA_CONTEXT_READY);
594 break;
595
596 default:
597 pa_assert_not_reached();
598 }
599
600 finish:
601 pa_context_unref(c);
602 }
603
setup_context(pa_context * c,pa_iochannel * io)604 static void setup_context(pa_context *c, pa_iochannel *io) {
605 uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
606 pa_tagstruct *t;
607 uint32_t tag;
608
609 pa_assert(c);
610 pa_assert(io);
611
612 pa_context_ref(c);
613
614 pa_assert(!c->pstream);
615 c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
616
617 pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
618 pa_pstream_set_receive_packet_callback(c->pstream, pstream_packet_callback, c);
619 pa_pstream_set_receive_memblock_callback(c->pstream, pstream_memblock_callback, c);
620
621 pa_assert(!c->pdispatch);
622 c->pdispatch = pa_pdispatch_new(c->mainloop, c->use_rtclock, command_table, PA_COMMAND_MAX);
623
624 if (pa_client_conf_load_cookie(c->conf, cookie, sizeof(cookie)) < 0)
625 pa_log_info("No cookie loaded. Attempting to connect without.");
626
627 t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
628
629 c->do_shm =
630 pa_mempool_is_shared(c->mempool) &&
631 c->is_local;
632
633 pa_log_debug("SHM possible: %s", pa_yes_no(c->do_shm));
634
635 /* Starting with protocol version 13 we use the MSB of the version
636 * tag for informing the other side if we could do SHM or not.
637 * Starting from version 31, second MSB is used to flag memfd support. */
638 pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? PA_PROTOCOL_FLAG_SHM : 0) |
639 (c->memfd_on_local ? PA_PROTOCOL_FLAG_MEMFD: 0));
640 pa_tagstruct_put_arbitrary(t, cookie, sizeof(cookie));
641
642 #ifdef HAVE_CREDS
643 {
644 pa_creds ucred;
645
646 if (pa_iochannel_creds_supported(io))
647 pa_iochannel_creds_enable(io);
648
649 ucred.uid = getuid();
650 ucred.gid = getgid();
651
652 pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
653 }
654 #else
655 pa_pstream_send_tagstruct(c->pstream, t);
656 #endif
657
658 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
659
660 pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
661
662 pa_context_unref(c);
663 }
664
prepend_per_user(pa_strlist * l)665 static pa_strlist *prepend_per_user(pa_strlist *l) {
666 char *ufn;
667
668 /* The per-user instance */
669 if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
670 l = pa_strlist_prepend(l, ufn);
671 pa_xfree(ufn);
672 }
673
674 return l;
675 }
676
677 #ifndef OS_IS_WIN32
678
context_autospawn(pa_context * c)679 static int context_autospawn(pa_context *c) {
680 pid_t pid;
681 int status, r;
682 struct sigaction sa;
683
684 pa_context_ref(c);
685
686 if (sigaction(SIGCHLD, NULL, &sa) < 0) {
687 pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno));
688 pa_context_fail(c, PA_ERR_INTERNAL);
689 goto fail;
690 }
691
692 #ifdef SA_NOCLDWAIT
693 if ((sa.sa_flags & SA_NOCLDWAIT) || sa.sa_handler == SIG_IGN) {
694 #else
695 if (sa.sa_handler == SIG_IGN) {
696 #endif
697 pa_log_debug("Process disabled waitpid(), cannot autospawn.");
698 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
699 goto fail;
700 }
701
702 pa_log_debug("Trying to autospawn...");
703
704 if (c->spawn_api.prefork)
705 c->spawn_api.prefork();
706
707 if ((pid = fork()) < 0) {
708 pa_log_error(_("fork(): %s"), pa_cstrerror(errno));
709 pa_context_fail(c, PA_ERR_INTERNAL);
710
711 if (c->spawn_api.postfork)
712 c->spawn_api.postfork();
713
714 goto fail;
715 } else if (!pid) {
716 /* Child */
717
718 const char *state = NULL;
719 const char * argv[32];
720 unsigned n = 0;
721
722 if (c->spawn_api.atfork)
723 c->spawn_api.atfork();
724
725 /* We leave most of the cleaning up of the process environment
726 * to the executable. We only clean up the file descriptors to
727 * make sure the executable can actually be loaded
728 * correctly. */
729 pa_close_all(-1);
730
731 /* Setup argv */
732 argv[n++] = c->conf->daemon_binary;
733 argv[n++] = "--start";
734
735 while (n < PA_ELEMENTSOF(argv)-1) {
736 char *a;
737
738 if (!(a = pa_split_spaces(c->conf->extra_arguments, &state)))
739 break;
740
741 argv[n++] = a;
742 }
743
744 argv[n++] = NULL;
745 pa_assert(n <= PA_ELEMENTSOF(argv));
746
747 execv(argv[0], (char * const *) argv);
748 _exit(1);
749 }
750
751 /* Parent */
752
753 if (c->spawn_api.postfork)
754 c->spawn_api.postfork();
755
756 do {
757 r = waitpid(pid, &status, 0);
758 } while (r < 0 && errno == EINTR);
759
760 if (r < 0) {
761
762 if (errno != ECHILD) {
763 pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
764 pa_context_fail(c, PA_ERR_INTERNAL);
765 goto fail;
766 }
767
768 /* hmm, something already reaped our child, so we assume
769 * startup worked, even if we cannot know */
770
771 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
772 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
773 goto fail;
774 }
775
776 pa_context_unref(c);
777
778 return 0;
779
780 fail:
781
782 pa_context_unref(c);
783
784 return -1;
785 }
786
787 #endif /* OS_IS_WIN32 */
788
789 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
790
791 #ifdef HAVE_DBUS
792 static void track_pulseaudio_on_dbus(pa_context *c, DBusBusType type, pa_dbus_wrap_connection **conn) {
793 DBusError error;
794
795 pa_assert(c);
796 pa_assert(conn);
797
798 dbus_error_init(&error);
799
800 if (!(*conn = pa_dbus_wrap_connection_new(c->mainloop, c->use_rtclock, type, &error)) || dbus_error_is_set(&error)) {
801 pa_log_warn("Unable to contact DBUS: %s: %s", error.name, error.message);
802 goto fail;
803 }
804
805 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn), filter_cb, c, NULL)) {
806 pa_log_warn("Failed to add filter function");
807 goto fail;
808 }
809 c->filter_added = true;
810
811 if (pa_dbus_add_matches(
812 pa_dbus_wrap_connection_get(*conn), &error,
813 "type='signal',sender='" DBUS_SERVICE_DBUS "',interface='" DBUS_INTERFACE_DBUS "',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL) < 0) {
814
815 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error.name, error.message);
816 goto fail;
817 }
818
819 return;
820
821 fail:
822 if (*conn) {
823 pa_dbus_wrap_connection_free(*conn);
824 *conn = NULL;
825 }
826
827 dbus_error_free(&error);
828 }
829 #endif
830
831 static int try_next_connection(pa_context *c) {
832 char *u = NULL;
833 int r = -1;
834
835 pa_assert(c);
836 pa_assert(!c->client);
837
838 for (;;) {
839 pa_xfree(u);
840 u = NULL;
841
842 c->server_list = pa_strlist_pop(c->server_list, &u);
843
844 if (!u) {
845
846 #ifndef OS_IS_WIN32
847 if (c->do_autospawn) {
848
849 if ((r = context_autospawn(c)) < 0)
850 goto finish;
851
852 /* Autospawn only once */
853 c->do_autospawn = false;
854
855 /* Connect only to per-user sockets this time */
856 c->server_list = prepend_per_user(c->server_list);
857
858 /* Retry connection */
859 continue;
860 }
861 #endif
862
863 #ifdef HAVE_DBUS
864 if (c->no_fail && !c->server_specified) {
865 if (!c->session_bus)
866 track_pulseaudio_on_dbus(c, DBUS_BUS_SESSION, &c->session_bus);
867 if (!c->system_bus)
868 track_pulseaudio_on_dbus(c, DBUS_BUS_SYSTEM, &c->system_bus);
869
870 if (c->session_bus || c->system_bus) {
871 pa_log_debug("Waiting for PA on D-Bus...");
872 break;
873 }
874 } else
875 #endif
876 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
877
878 goto finish;
879 }
880
881 pa_log_debug("Trying to connect to %s...", u);
882
883 pa_xfree(c->server);
884 c->server = pa_xstrdup(u);
885
886 if (!(c->client = pa_socket_client_new_string(c->mainloop, c->use_rtclock, u, PA_NATIVE_DEFAULT_PORT)))
887 continue;
888
889 c->is_local = pa_socket_client_is_local(c->client);
890 pa_socket_client_set_callback(c->client, on_connection, c);
891 break;
892 }
893
894 r = 0;
895
896 finish:
897 pa_xfree(u);
898
899 return r;
900 }
901
902 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
903 pa_context *c = userdata;
904 int saved_errno = errno;
905
906 pa_assert(client);
907 pa_assert(c);
908 pa_assert(c->state == PA_CONTEXT_CONNECTING);
909
910 pa_context_ref(c);
911
912 pa_socket_client_unref(client);
913 c->client = NULL;
914
915 if (!io) {
916 /* Try the next item in the list */
917 if (saved_errno == ECONNREFUSED ||
918 saved_errno == ETIMEDOUT ||
919 saved_errno == EHOSTUNREACH) {
920 try_next_connection(c);
921 goto finish;
922 }
923
924 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
925 goto finish;
926 }
927
928 setup_context(c, io);
929
930 finish:
931 pa_context_unref(c);
932 }
933
934 #ifdef HAVE_DBUS
935 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) {
936 pa_context *c = userdata;
937 bool is_session;
938
939 pa_assert(bus);
940 pa_assert(message);
941 pa_assert(c);
942
943 if (c->state != PA_CONTEXT_CONNECTING)
944 goto finish;
945
946 if (!c->no_fail)
947 goto finish;
948
949 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
950
951 is_session = c->session_bus && bus == pa_dbus_wrap_connection_get(c->session_bus);
952 pa_log_debug("Rock!! PulseAudio might be back on %s bus", is_session ? "session" : "system");
953
954 if (is_session)
955 /* The user instance via PF_LOCAL */
956 c->server_list = prepend_per_user(c->server_list);
957 else
958 /* The system wide instance via PF_LOCAL */
959 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
960
961 if (!c->client)
962 try_next_connection(c);
963
964 finish:
965 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
966 }
967 #endif
968
969 int pa_context_connect(
970 pa_context *c,
971 const char *server,
972 pa_context_flags_t flags,
973 const pa_spawn_api *api) {
974
975 int r = -1;
976
977 pa_assert(c);
978 pa_assert(PA_REFCNT_VALUE(c) >= 1);
979
980 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
981 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
982 PA_CHECK_VALIDITY(c, !(flags & ~(PA_CONTEXT_NOAUTOSPAWN|PA_CONTEXT_NOFAIL)), PA_ERR_INVALID);
983 PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
984
985 if (server)
986 c->conf->autospawn = false;
987 else
988 server = c->conf->default_server;
989
990 pa_context_ref(c);
991
992 c->no_fail = !!(flags & PA_CONTEXT_NOFAIL);
993 c->server_specified = !!server;
994 pa_assert(!c->server_list);
995
996 if (server) {
997 if (!(c->server_list = pa_strlist_parse(server))) {
998 pa_context_fail(c, PA_ERR_INVALIDSERVER);
999 goto finish;
1000 }
1001
1002 } else {
1003 char *d;
1004
1005 /* Prepend in reverse order */
1006
1007 /* Follow the X display */
1008 if (c->conf->auto_connect_display) {
1009 if ((d = getenv("DISPLAY"))) {
1010 d = pa_xstrndup(d, strcspn(d, ":"));
1011
1012 if (*d)
1013 c->server_list = pa_strlist_prepend(c->server_list, d);
1014
1015 pa_xfree(d);
1016 }
1017 }
1018
1019 /* Add TCP/IP on the localhost */
1020 if (c->conf->auto_connect_localhost) {
1021 c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
1022 c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
1023 }
1024
1025 /* The system wide instance via PF_LOCAL */
1026 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
1027
1028 /* The user instance via PF_LOCAL */
1029 c->server_list = prepend_per_user(c->server_list);
1030 }
1031
1032 /* Set up autospawning */
1033 if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
1034
1035 #ifdef HAVE_GETUID
1036 if (getuid() == 0)
1037 pa_log_debug("Not doing autospawn since we are root.");
1038 else {
1039 c->do_autospawn = true;
1040
1041 if (api)
1042 c->spawn_api = *api;
1043 }
1044 #endif
1045 }
1046
1047 pa_context_set_state(c, PA_CONTEXT_CONNECTING);
1048 r = try_next_connection(c);
1049
1050 finish:
1051 pa_context_unref(c);
1052
1053 return r;
1054 }
1055
1056 void pa_context_disconnect(pa_context *c) {
1057 pa_assert(c);
1058 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1059
1060 if (pa_detect_fork())
1061 return;
1062
1063 if (PA_CONTEXT_IS_GOOD(c->state))
1064 pa_context_set_state(c, PA_CONTEXT_TERMINATED);
1065 }
1066
1067 pa_context_state_t pa_context_get_state(const pa_context *c) {
1068 pa_assert(c);
1069 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1070
1071 return c->state;
1072 }
1073
1074 int pa_context_errno(const pa_context *c) {
1075
1076 if (!c)
1077 return PA_ERR_INVALID;
1078
1079 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1080
1081 return c->error->error;
1082 }
1083
1084 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
1085 pa_assert(c);
1086 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1087
1088 if (pa_detect_fork())
1089 return;
1090
1091 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
1092 return;
1093
1094 c->state_callback = cb;
1095 c->state_userdata = userdata;
1096 }
1097
1098 void pa_context_set_event_callback(pa_context *c, pa_context_event_cb_t cb, void *userdata) {
1099 pa_assert(c);
1100 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1101
1102 if (pa_detect_fork())
1103 return;
1104
1105 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
1106 return;
1107
1108 c->event_callback = cb;
1109 c->event_userdata = userdata;
1110 }
1111
1112 int pa_context_is_pending(const pa_context *c) {
1113 pa_assert(c);
1114 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1115
1116 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
1117 PA_CHECK_VALIDITY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE);
1118
1119 return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
1120 (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
1121 c->client;
1122 }
1123
1124 static void set_dispatch_callbacks(pa_operation *o);
1125
1126 static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) {
1127 set_dispatch_callbacks(userdata);
1128 }
1129
1130 static void pstream_drain_callback(pa_pstream *s, void *userdata) {
1131 set_dispatch_callbacks(userdata);
1132 }
1133
1134 static void set_dispatch_callbacks(pa_operation *o) {
1135 int done = 1;
1136
1137 pa_assert(o);
1138 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1139 pa_assert(o->context);
1140 pa_assert(PA_REFCNT_VALUE(o->context) >= 1);
1141 pa_assert(o->context->state == PA_CONTEXT_READY);
1142
1143 pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
1144 pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL);
1145
1146 if (pa_pdispatch_is_pending(o->context->pdispatch)) {
1147 pa_pdispatch_set_drain_callback(o->context->pdispatch, pdispatch_drain_callback, o);
1148 done = 0;
1149 }
1150
1151 if (pa_pstream_is_pending(o->context->pstream)) {
1152 pa_pstream_set_drain_callback(o->context->pstream, pstream_drain_callback, o);
1153 done = 0;
1154 }
1155
1156 if (done) {
1157 if (o->callback) {
1158 pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
1159 cb(o->context, o->userdata);
1160 }
1161
1162 pa_operation_done(o);
1163 pa_operation_unref(o);
1164 }
1165 }
1166
1167 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
1168 pa_operation *o;
1169
1170 pa_assert(c);
1171 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1172
1173 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1174 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1175 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
1176
1177 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1178 set_dispatch_callbacks(pa_operation_ref(o));
1179
1180 return o;
1181 }
1182
1183 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1184 pa_operation *o = userdata;
1185 int success = 1;
1186
1187 pa_assert(pd);
1188 pa_assert(o);
1189 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1190
1191 if (!o->context)
1192 goto finish;
1193
1194 if (command != PA_COMMAND_REPLY) {
1195 if (pa_context_handle_error(o->context, command, t, false) < 0)
1196 goto finish;
1197
1198 success = 0;
1199 } else if (!pa_tagstruct_eof(t)) {
1200 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1201 goto finish;
1202 }
1203
1204 if (o->callback) {
1205 pa_context_success_cb_t cb = (pa_context_success_cb_t) o->callback;
1206 cb(o->context, success, o->userdata);
1207 }
1208
1209 finish:
1210 pa_operation_done(o);
1211 pa_operation_unref(o);
1212 }
1213
1214 pa_operation* pa_context_send_simple_command(pa_context *c, uint32_t command, pa_pdispatch_cb_t internal_cb, pa_operation_cb_t cb, void *userdata) {
1215 pa_tagstruct *t;
1216 pa_operation *o;
1217 uint32_t tag;
1218
1219 pa_assert(c);
1220 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1221
1222 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1223 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1224
1225 o = pa_operation_new(c, NULL, cb, userdata);
1226
1227 t = pa_tagstruct_command(c, command, &tag);
1228 pa_pstream_send_tagstruct(c->pstream, t);
1229 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1230
1231 return o;
1232 }
1233
1234 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) {
1235 pa_assert(c);
1236 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1237
1238 return pa_context_send_simple_command(c, PA_COMMAND_EXIT, pa_context_simple_ack_callback, (pa_operation_cb_t) cb, userdata);
1239 }
1240
1241 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1242 pa_tagstruct *t;
1243 pa_operation *o;
1244 uint32_t tag;
1245
1246 pa_assert(c);
1247 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1248
1249 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1250 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1251
1252 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1253 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
1254 pa_tagstruct_puts(t, name);
1255 pa_pstream_send_tagstruct(c->pstream, t);
1256 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1257
1258 return o;
1259 }
1260
1261 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1262 pa_tagstruct *t;
1263 pa_operation *o;
1264 uint32_t tag;
1265
1266 pa_assert(c);
1267 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1268
1269 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1270 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1271
1272 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1273 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
1274 pa_tagstruct_puts(t, name);
1275 pa_pstream_send_tagstruct(c->pstream, t);
1276 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1277
1278 return o;
1279 }
1280
1281 int pa_context_is_local(const pa_context *c) {
1282 pa_assert(c);
1283 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1284
1285 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, -1);
1286 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, -1);
1287
1288 return c->is_local;
1289 }
1290
1291 pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1292 pa_operation *o;
1293
1294 pa_assert(c);
1295 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1296 pa_assert(name);
1297
1298 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1299 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1300
1301 if (c->version >= 13) {
1302 pa_proplist *p = pa_proplist_new();
1303
1304 pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, name);
1305 o = pa_context_proplist_update(c, PA_UPDATE_REPLACE, p, cb, userdata);
1306 pa_proplist_free(p);
1307 } else {
1308 pa_tagstruct *t;
1309 uint32_t tag;
1310
1311 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1312 t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
1313 pa_tagstruct_puts(t, name);
1314 pa_pstream_send_tagstruct(c->pstream, t);
1315 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1316 }
1317
1318 return o;
1319 }
1320
1321 const char* pa_get_library_version(void) {
1322 return pa_get_headers_version();
1323 }
1324
1325 const char* pa_context_get_server(const pa_context *c) {
1326 pa_assert(c);
1327 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1328
1329 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1330 PA_CHECK_VALIDITY_RETURN_NULL(c, c->server, PA_ERR_NOENTITY);
1331
1332 if (*c->server == '{') {
1333 char *e = strchr(c->server+1, '}');
1334 return e ? e+1 : c->server;
1335 }
1336
1337 return c->server;
1338 }
1339
1340 uint32_t pa_context_get_protocol_version(const pa_context *c) {
1341 return PA_PROTOCOL_VERSION;
1342 }
1343
1344 uint32_t pa_context_get_server_protocol_version(const pa_context *c) {
1345 pa_assert(c);
1346 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1347
1348 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1349 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, PA_INVALID_INDEX);
1350
1351 return c->version;
1352 }
1353
1354 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
1355 pa_tagstruct *t;
1356
1357 pa_assert(c);
1358 pa_assert(tag);
1359
1360 t = pa_tagstruct_new();
1361 pa_tagstruct_putu32(t, command);
1362 pa_tagstruct_putu32(t, *tag = c->ctag++);
1363
1364 return t;
1365 }
1366
1367 uint32_t pa_context_get_index(const pa_context *c) {
1368 pa_assert(c);
1369 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1370
1371 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1372 PA_CHECK_VALIDITY_RETURN_ANY(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX);
1373 PA_CHECK_VALIDITY_RETURN_ANY(c, c->version >= 13, PA_ERR_NOTSUPPORTED, PA_INVALID_INDEX);
1374
1375 return c->client_index;
1376 }
1377
1378 pa_operation *pa_context_proplist_update(pa_context *c, pa_update_mode_t mode, const pa_proplist *p, pa_context_success_cb_t cb, void *userdata) {
1379 pa_operation *o;
1380 pa_tagstruct *t;
1381 uint32_t tag;
1382
1383 pa_assert(c);
1384 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1385
1386 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1387 PA_CHECK_VALIDITY_RETURN_NULL(c, mode == PA_UPDATE_SET || mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE, PA_ERR_INVALID);
1388 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1389 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1390
1391 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1392
1393 t = pa_tagstruct_command(c, PA_COMMAND_UPDATE_CLIENT_PROPLIST, &tag);
1394 pa_tagstruct_putu32(t, (uint32_t) mode);
1395 pa_tagstruct_put_proplist(t, p);
1396
1397 pa_pstream_send_tagstruct(c->pstream, t);
1398 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1399
1400 /* Please note that we don't update c->proplist here, because we
1401 * don't export that field */
1402
1403 return o;
1404 }
1405
1406 pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[], pa_context_success_cb_t cb, void *userdata) {
1407 pa_operation *o;
1408 pa_tagstruct *t;
1409 uint32_t tag;
1410 const char * const *k;
1411
1412 pa_assert(c);
1413 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1414
1415 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1416 PA_CHECK_VALIDITY_RETURN_NULL(c, keys && keys[0], PA_ERR_INVALID);
1417 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1418 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1419
1420 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1421
1422 t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_CLIENT_PROPLIST, &tag);
1423
1424 for (k = keys; *k; k++)
1425 pa_tagstruct_puts(t, *k);
1426
1427 pa_tagstruct_puts(t, NULL);
1428
1429 pa_pstream_send_tagstruct(c->pstream, t);
1430 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1431
1432 /* Please note that we don't update c->proplist here, because we
1433 * don't export that field */
1434
1435 return o;
1436 }
1437
1438 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1439 pa_context *c = userdata;
1440 uint32_t idx;
1441 const char *name;
1442
1443 pa_assert(pd);
1444 pa_assert(command == PA_COMMAND_EXTENSION);
1445 pa_assert(t);
1446 pa_assert(c);
1447 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1448
1449 pa_context_ref(c);
1450
1451 if (c->version < 15) {
1452 pa_context_fail(c, PA_ERR_PROTOCOL);
1453 goto finish;
1454 }
1455
1456 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1457 pa_tagstruct_gets(t, &name) < 0) {
1458 pa_context_fail(c, PA_ERR_PROTOCOL);
1459 goto finish;
1460 }
1461
1462 if (pa_streq(name, "module-device-manager"))
1463 pa_ext_device_manager_command(c, tag, t);
1464 else if (pa_streq(name, "module-device-restore"))
1465 pa_ext_device_restore_command(c, tag, t);
1466 else if (pa_streq(name, "module-stream-restore"))
1467 pa_ext_stream_restore_command(c, tag, t);
1468 else
1469 pa_log(_("Received message for unknown extension '%s'"), name);
1470
1471 finish:
1472 pa_context_unref(c);
1473 }
1474
1475 static void pa_command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1476 pa_context *c = userdata;
1477
1478 #ifdef HAVE_CREDS
1479 pa_cmsg_ancil_data *ancil = NULL;
1480
1481 pa_assert(pd);
1482 pa_assert(command == PA_COMMAND_ENABLE_SRBCHANNEL);
1483 pa_assert(t);
1484 pa_assert(c);
1485 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1486
1487 ancil = pa_pdispatch_take_ancil_data(pd);
1488 if (!ancil)
1489 goto fail;
1490
1491 /* Currently only one srb channel is supported, might change in future versions */
1492 if (c->srb_template.readfd != -1)
1493 goto fail;
1494
1495 if (ancil->nfd != 2 || ancil->fds[0] == -1 || ancil->fds[1] == -1)
1496 goto fail;
1497
1498 pa_context_ref(c);
1499
1500 c->srb_template.readfd = ancil->fds[0];
1501 c->srb_template.writefd = ancil->fds[1];
1502 c->srb_setup_tag = tag;
1503
1504 pa_context_unref(c);
1505
1506 ancil->close_fds_on_cleanup = false;
1507 return;
1508
1509 fail:
1510 if (ancil)
1511 pa_cmsg_ancil_data_close_fds(ancil);
1512
1513 pa_context_fail(c, PA_ERR_PROTOCOL);
1514 return;
1515 #else
1516 pa_assert(c);
1517 pa_context_fail(c, PA_ERR_PROTOCOL);
1518 #endif
1519 }
1520
1521 static void pa_command_disable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1522 pa_context *c = userdata;
1523 pa_tagstruct *t2;
1524
1525 pa_assert(pd);
1526 pa_assert(command == PA_COMMAND_DISABLE_SRBCHANNEL);
1527 pa_assert(t);
1528 pa_assert(c);
1529 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1530
1531 pa_pstream_set_srbchannel(c->pstream, NULL);
1532
1533 c->srb_template.readfd = -1;
1534 c->srb_template.writefd = -1;
1535 if (c->srb_template.memblock) {
1536 pa_memblock_unref(c->srb_template.memblock);
1537 c->srb_template.memblock = NULL;
1538 }
1539
1540 /* Send disable command back again */
1541 t2 = pa_tagstruct_new();
1542 pa_tagstruct_putu32(t2, PA_COMMAND_DISABLE_SRBCHANNEL);
1543 pa_tagstruct_putu32(t2, tag);
1544 pa_pstream_send_tagstruct(c->pstream, t2);
1545 }
1546
1547 static void pa_command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1548 pa_context *c = userdata;
1549
1550 pa_assert(pd);
1551 pa_assert(command == PA_COMMAND_REGISTER_MEMFD_SHMID);
1552 pa_assert(t);
1553 pa_assert(c);
1554 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1555
1556 if (pa_common_command_register_memfd_shmid(c->pstream, pd, c->version, command, t))
1557 pa_context_fail(c, PA_ERR_PROTOCOL);
1558 }
1559
1560 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1561 pa_context *c = userdata;
1562 pa_proplist *pl = NULL;
1563 const char *event;
1564
1565 pa_assert(pd);
1566 pa_assert(command == PA_COMMAND_CLIENT_EVENT);
1567 pa_assert(t);
1568 pa_assert(c);
1569 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1570
1571 pa_context_ref(c);
1572
1573 if (c->version < 15) {
1574 pa_context_fail(c, PA_ERR_PROTOCOL);
1575 goto finish;
1576 }
1577
1578 pl = pa_proplist_new();
1579
1580 if (pa_tagstruct_gets(t, &event) < 0 ||
1581 pa_tagstruct_get_proplist(t, pl) < 0 ||
1582 !pa_tagstruct_eof(t) || !event) {
1583 pa_context_fail(c, PA_ERR_PROTOCOL);
1584 goto finish;
1585 }
1586
1587 if (c->event_callback)
1588 c->event_callback(c, event, pl, c->event_userdata);
1589
1590 finish:
1591 pa_context_unref(c);
1592
1593 if (pl)
1594 pa_proplist_free(pl);
1595 }
1596
1597 pa_time_event* pa_context_rttime_new(const pa_context *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata) {
1598 struct timeval tv;
1599
1600 pa_assert(c);
1601 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1602 pa_assert(c->mainloop);
1603
1604 if (usec == PA_USEC_INVALID)
1605 return c->mainloop->time_new(c->mainloop, NULL, cb, userdata);
1606
1607 pa_timeval_rtstore(&tv, usec, c->use_rtclock);
1608
1609 return c->mainloop->time_new(c->mainloop, &tv, cb, userdata);
1610 }
1611
1612 void pa_context_rttime_restart(const pa_context *c, pa_time_event *e, pa_usec_t usec) {
1613 struct timeval tv;
1614
1615 pa_assert(c);
1616 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1617 pa_assert(c->mainloop);
1618
1619 if (usec == PA_USEC_INVALID)
1620 c->mainloop->time_restart(e, NULL);
1621 else {
1622 pa_timeval_rtstore(&tv, usec, c->use_rtclock);
1623 c->mainloop->time_restart(e, &tv);
1624 }
1625 }
1626
1627 size_t pa_context_get_tile_size(const pa_context *c, const pa_sample_spec *ss) {
1628 size_t fs, mbs;
1629
1630 pa_assert(c);
1631 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1632
1633 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, (size_t) -1);
1634 PA_CHECK_VALIDITY_RETURN_ANY(c, !ss || pa_sample_spec_valid(ss), PA_ERR_INVALID, (size_t) -1);
1635
1636 fs = ss ? pa_frame_size(ss) : 1;
1637 mbs = PA_ROUND_DOWN(pa_mempool_block_size_max(c->mempool), fs);
1638 return PA_MAX(mbs, fs);
1639 }
1640
1641 int pa_context_load_cookie_from_file(pa_context *c, const char *cookie_file_path) {
1642 pa_assert(c);
1643 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1644
1645 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
1646 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
1647 PA_CHECK_VALIDITY(c, !cookie_file_path || *cookie_file_path, PA_ERR_INVALID);
1648
1649 pa_client_conf_set_cookie_file_from_application(c->conf, cookie_file_path);
1650
1651 return 0;
1652 }
1653