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