2 This file is part of PulseAudio.
4 Copyright 2004-2008 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
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.
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.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30 #include <sys/types.h>
38 #ifdef HAVE_SYS_WAIT_H
42 #ifdef HAVE_SYS_SOCKET_H
43 #include <sys/socket.h>
52 #include <pulse/version.h>
53 #include <pulse/xmalloc.h>
54 #include <pulse/utf8.h>
55 #include <pulse/util.h>
56 #include <pulse/i18n.h>
57 #include <pulse/mainloop.h>
58 #include <pulse/timeval.h>
60 #include <pulsecore/winsock.h>
61 #include <pulsecore/core-error.h>
63 #include <pulsecore/native-common.h>
64 #include <pulsecore/pdispatch.h>
65 #include <pulsecore/pstream.h>
66 #include <pulsecore/hashmap.h>
67 #include <pulsecore/socket-client.h>
68 #include <pulsecore/pstream-util.h>
69 #include <pulsecore/core-rtclock.h>
70 #include <pulsecore/core-util.h>
71 #include <pulsecore/log.h>
72 #include <pulsecore/socket-util.h>
73 #include <pulsecore/creds.h>
74 #include <pulsecore/macro.h>
75 #include <pulsecore/proplist-util.h>
79 #include "client-conf.h"
80 #include "fork-detect.h"
83 #include "client-conf-x11.h"
88 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
90 static const pa_pdispatch_cb_t command_table
[PA_COMMAND_MAX
] = {
91 [PA_COMMAND_REQUEST
] = pa_command_request
,
92 [PA_COMMAND_OVERFLOW
] = pa_command_overflow_or_underflow
,
93 [PA_COMMAND_UNDERFLOW
] = pa_command_overflow_or_underflow
,
94 [PA_COMMAND_PLAYBACK_STREAM_KILLED
] = pa_command_stream_killed
,
95 [PA_COMMAND_RECORD_STREAM_KILLED
] = pa_command_stream_killed
,
96 [PA_COMMAND_PLAYBACK_STREAM_MOVED
] = pa_command_stream_moved
,
97 [PA_COMMAND_RECORD_STREAM_MOVED
] = pa_command_stream_moved
,
98 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
] = pa_command_stream_suspended
,
99 [PA_COMMAND_RECORD_STREAM_SUSPENDED
] = pa_command_stream_suspended
,
100 [PA_COMMAND_STARTED
] = pa_command_stream_started
,
101 [PA_COMMAND_SUBSCRIBE_EVENT
] = pa_command_subscribe_event
,
102 [PA_COMMAND_EXTENSION
] = pa_command_extension
,
103 [PA_COMMAND_PLAYBACK_STREAM_EVENT
] = pa_command_stream_event
,
104 [PA_COMMAND_RECORD_STREAM_EVENT
] = pa_command_stream_event
,
105 [PA_COMMAND_CLIENT_EVENT
] = pa_command_client_event
,
106 [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
,
107 [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
109 static void context_free(pa_context
*c
);
112 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
);
115 pa_context
*pa_context_new(pa_mainloop_api
*mainloop
, const char *name
) {
116 return pa_context_new_with_proplist(mainloop
, name
, NULL
);
119 static void reset_callbacks(pa_context
*c
) {
122 c
->state_callback
= NULL
;
123 c
->state_userdata
= NULL
;
125 c
->subscribe_callback
= NULL
;
126 c
->subscribe_userdata
= NULL
;
128 c
->event_callback
= NULL
;
129 c
->event_userdata
= NULL
;
131 c
->ext_device_manager
.callback
= NULL
;
132 c
->ext_device_manager
.userdata
= NULL
;
134 c
->ext_stream_restore
.callback
= NULL
;
135 c
->ext_stream_restore
.userdata
= NULL
;
138 pa_context
*pa_context_new_with_proplist(pa_mainloop_api
*mainloop
, const char *name
, pa_proplist
*p
) {
143 if (pa_detect_fork())
148 c
= pa_xnew(pa_context
, 1);
151 c
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
154 pa_proplist_sets(c
->proplist
, PA_PROP_APPLICATION_NAME
, name
);
157 c
->system_bus
= c
->session_bus
= NULL
;
159 c
->mainloop
= mainloop
;
163 c
->playback_streams
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
164 c
->record_streams
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
165 c
->client_index
= PA_INVALID_INDEX
;
166 c
->use_rtclock
= pa_mainloop_is_our_api(mainloop
);
168 PA_LLIST_HEAD_INIT(pa_stream
, c
->streams
);
169 PA_LLIST_HEAD_INIT(pa_operation
, c
->operations
);
172 c
->state
= PA_CONTEXT_UNCONNECTED
;
179 c
->server_list
= NULL
;
184 c
->server_specified
= FALSE
;
186 c
->do_autospawn
= FALSE
;
187 memset(&c
->spawn_api
, 0, sizeof(c
->spawn_api
));
191 pa_check_signal_is_blocked(SIGPIPE
);
195 c
->conf
= pa_client_conf_new();
196 pa_client_conf_load(c
->conf
, NULL
);
198 pa_client_conf_from_x11(c
->conf
, NULL
);
200 pa_client_conf_env(c
->conf
);
202 if (!(c
->mempool
= pa_mempool_new(!c
->conf
->disable_shm
, c
->conf
->shm_size
))) {
204 if (!c
->conf
->disable_shm
)
205 c
->mempool
= pa_mempool_new(FALSE
, c
->conf
->shm_size
);
216 static void context_unlink(pa_context
*c
) {
221 s
= c
->streams
? pa_stream_ref(c
->streams
) : NULL
;
223 pa_stream
*n
= s
->next
? pa_stream_ref(s
->next
) : NULL
;
224 pa_stream_set_state(s
, c
->state
== PA_CONTEXT_FAILED
? PA_STREAM_FAILED
: PA_STREAM_TERMINATED
);
229 while (c
->operations
)
230 pa_operation_cancel(c
->operations
);
233 pa_pdispatch_unref(c
->pdispatch
);
238 pa_pstream_unlink(c
->pstream
);
239 pa_pstream_unref(c
->pstream
);
244 pa_socket_client_unref(c
->client
);
251 static void context_free(pa_context
*c
) {
258 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->system_bus
), filter_cb
, c
);
259 pa_dbus_wrap_connection_free(c
->system_bus
);
262 if (c
->session_bus
) {
263 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->session_bus
), filter_cb
, c
);
264 pa_dbus_wrap_connection_free(c
->session_bus
);
268 if (c
->record_streams
)
269 pa_hashmap_free(c
->record_streams
, NULL
, NULL
);
270 if (c
->playback_streams
)
271 pa_hashmap_free(c
->playback_streams
, NULL
, NULL
);
274 pa_mempool_free(c
->mempool
);
277 pa_client_conf_free(c
->conf
);
279 pa_strlist_free(c
->server_list
);
282 pa_proplist_free(c
->proplist
);
288 pa_context
* pa_context_ref(pa_context
*c
) {
290 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
296 void pa_context_unref(pa_context
*c
) {
298 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
300 if (PA_REFCNT_DEC(c
) <= 0)
304 void pa_context_set_state(pa_context
*c
, pa_context_state_t st
) {
306 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
315 if (c
->state_callback
)
316 c
->state_callback(c
, c
->state_userdata
);
318 if (st
== PA_CONTEXT_FAILED
|| st
== PA_CONTEXT_TERMINATED
)
324 int pa_context_set_error(pa_context
*c
, int error
) {
325 pa_assert(error
>= 0);
326 pa_assert(error
< PA_ERR_MAX
);
334 void pa_context_fail(pa_context
*c
, int error
) {
336 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
338 pa_context_set_error(c
, error
);
339 pa_context_set_state(c
, PA_CONTEXT_FAILED
);
342 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
343 pa_context
*c
= userdata
;
348 pa_context_fail(c
, PA_ERR_CONNECTIONTERMINATED
);
351 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
352 pa_context
*c
= userdata
;
360 if (pa_pdispatch_run(c
->pdispatch
, packet
, creds
, c
) < 0)
361 pa_context_fail(c
, PA_ERR_PROTOCOL
);
366 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
) {
367 pa_context
*c
= userdata
;
372 pa_assert(chunk
->length
> 0);
374 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
378 if ((s
= pa_hashmap_get(c
->record_streams
, PA_UINT32_TO_PTR(channel
)))) {
380 if (chunk
->memblock
) {
381 pa_memblockq_seek(s
->record_memblockq
, offset
, seek
, TRUE
);
382 pa_memblockq_push_align(s
->record_memblockq
, chunk
);
384 pa_memblockq_seek(s
->record_memblockq
, offset
+chunk
->length
, seek
, TRUE
);
386 if (s
->read_callback
) {
389 if ((l
= pa_memblockq_get_length(s
->record_memblockq
)) > 0)
390 s
->read_callback(s
, l
, s
->read_userdata
);
397 int pa_context_handle_error(pa_context
*c
, uint32_t command
, pa_tagstruct
*t
, pa_bool_t fail
) {
400 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
402 if (command
== PA_COMMAND_ERROR
) {
405 if (pa_tagstruct_getu32(t
, &err
) < 0 ||
406 !pa_tagstruct_eof(t
)) {
407 pa_context_fail(c
, PA_ERR_PROTOCOL
);
411 } else if (command
== PA_COMMAND_TIMEOUT
)
412 err
= PA_ERR_TIMEOUT
;
414 pa_context_fail(c
, PA_ERR_PROTOCOL
);
419 pa_context_fail(c
, PA_ERR_PROTOCOL
);
423 if (err
>= PA_ERR_MAX
)
424 err
= PA_ERR_UNKNOWN
;
427 pa_context_fail(c
, (int) err
);
431 pa_context_set_error(c
, (int) err
);
436 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
437 pa_context
*c
= userdata
;
441 pa_assert(c
->state
== PA_CONTEXT_AUTHORIZING
|| c
->state
== PA_CONTEXT_SETTING_NAME
);
445 if (command
!= PA_COMMAND_REPLY
) {
446 pa_context_handle_error(c
, command
, t
, TRUE
);
451 case PA_CONTEXT_AUTHORIZING
: {
453 pa_bool_t shm_on_remote
= FALSE
;
455 if (pa_tagstruct_getu32(t
, &c
->version
) < 0 ||
456 !pa_tagstruct_eof(t
)) {
457 pa_context_fail(c
, PA_ERR_PROTOCOL
);
461 /* Minimum supported version */
462 if (c
->version
< 8) {
463 pa_context_fail(c
, PA_ERR_VERSION
);
467 /* Starting with protocol version 13 the MSB of the version
468 tag reflects if shm is available for this connection or
470 if (c
->version
>= 13) {
471 shm_on_remote
= !!(c
->version
& 0x80000000U
);
472 c
->version
&= 0x7FFFFFFFU
;
475 pa_log_debug("Protocol version: remote %u, local %u", c
->version
, PA_PROTOCOL_VERSION
);
477 /* Enable shared memory support if possible */
479 if (c
->version
< 10 || (c
->version
>= 13 && !shm_on_remote
))
484 /* Only enable SHM if both sides are owned by the same
485 * user. This is a security measure because otherwise
486 * data private to the user might leak. */
489 const pa_creds
*creds
;
490 if (!(creds
= pa_pdispatch_creds(pd
)) || getuid() != creds
->uid
)
495 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c
->do_shm
));
496 pa_pstream_enable_shm(c
->pstream
, c
->do_shm
);
498 reply
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
500 if (c
->version
>= 13) {
501 pa_init_proplist(c
->proplist
);
502 pa_tagstruct_put_proplist(reply
, c
->proplist
);
504 pa_tagstruct_puts(reply
, pa_proplist_gets(c
->proplist
, PA_PROP_APPLICATION_NAME
));
506 pa_pstream_send_tagstruct(c
->pstream
, reply
);
507 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
509 pa_context_set_state(c
, PA_CONTEXT_SETTING_NAME
);
513 case PA_CONTEXT_SETTING_NAME
:
515 if ((c
->version
>= 13 && (pa_tagstruct_getu32(t
, &c
->client_index
) < 0 ||
516 c
->client_index
== PA_INVALID_INDEX
)) ||
517 !pa_tagstruct_eof(t
)) {
518 pa_context_fail(c
, PA_ERR_PROTOCOL
);
522 pa_context_set_state(c
, PA_CONTEXT_READY
);
526 pa_assert_not_reached();
533 static void setup_context(pa_context
*c
, pa_iochannel
*io
) {
542 pa_assert(!c
->pstream
);
543 c
->pstream
= pa_pstream_new(c
->mainloop
, io
, c
->mempool
);
545 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
546 pa_pstream_set_recieve_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
547 pa_pstream_set_recieve_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
549 pa_assert(!c
->pdispatch
);
550 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, c
->use_rtclock
, command_table
, PA_COMMAND_MAX
);
552 if (!c
->conf
->cookie_valid
)
553 pa_log_info(_("No cookie loaded. Attempting to connect without."));
555 t
= pa_tagstruct_command(c
, PA_COMMAND_AUTH
, &tag
);
558 pa_mempool_is_shared(c
->mempool
) &&
561 pa_log_debug("SHM possible: %s", pa_yes_no(c
->do_shm
));
563 /* Starting with protocol version 13 we use the MSB of the version
564 * tag for informing the other side if we could do SHM or not */
565 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
| (c
->do_shm
? 0x80000000U
: 0));
566 pa_tagstruct_put_arbitrary(t
, c
->conf
->cookie
, sizeof(c
->conf
->cookie
));
572 if (pa_iochannel_creds_supported(io
))
573 pa_iochannel_creds_enable(io
);
575 ucred
.uid
= getuid();
576 ucred
.gid
= getgid();
578 pa_pstream_send_tagstruct_with_creds(c
->pstream
, t
, &ucred
);
581 pa_pstream_send_tagstruct(c
->pstream
, t
);
584 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
586 pa_context_set_state(c
, PA_CONTEXT_AUTHORIZING
);
591 #ifdef ENABLE_LEGACY_RUNTIME_DIR
592 static char *get_old_legacy_runtime_dir(void) {
596 if (!pa_get_user_name(u
, sizeof(u
)))
599 p
= pa_sprintf_malloc("/tmp/pulse-%s", u
);
601 if (stat(p
, &st
) < 0) {
606 if (st
.st_uid
!= getuid()) {
614 static char *get_very_old_legacy_runtime_dir(void) {
618 if (!pa_get_home_dir(h
, sizeof(h
)))
621 p
= pa_sprintf_malloc("%s/.pulse", h
);
623 if (stat(p
, &st
) < 0) {
628 if (st
.st_uid
!= getuid()) {
637 static pa_strlist
*prepend_per_user(pa_strlist
*l
) {
640 #ifdef ENABLE_LEGACY_RUNTIME_DIR
641 static char *legacy_dir
;
643 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
644 if ((legacy_dir
= get_very_old_legacy_runtime_dir())) {
645 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
646 l
= pa_strlist_prepend(l
, p
);
648 pa_xfree(legacy_dir
);
651 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
652 if ((legacy_dir
= get_old_legacy_runtime_dir())) {
653 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
654 l
= pa_strlist_prepend(l
, p
);
656 pa_xfree(legacy_dir
);
660 /* The per-user instance */
661 if ((ufn
= pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET
))) {
662 l
= pa_strlist_prepend(l
, ufn
);
671 static int context_autospawn(pa_context
*c
) {
678 if (sigaction(SIGCHLD
, NULL
, &sa
) < 0) {
679 pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno
));
680 pa_context_fail(c
, PA_ERR_INTERNAL
);
684 if ((sa
.sa_flags
& SA_NOCLDWAIT
) || sa
.sa_handler
== SIG_IGN
) {
685 pa_log_debug("Process disabled waitpid(), cannot autospawn.");
686 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
690 pa_log_debug("Trying to autospawn...");
692 if (c
->spawn_api
.prefork
)
693 c
->spawn_api
.prefork();
695 if ((pid
= fork()) < 0) {
696 pa_log_error(_("fork(): %s"), pa_cstrerror(errno
));
697 pa_context_fail(c
, PA_ERR_INTERNAL
);
699 if (c
->spawn_api
.postfork
)
700 c
->spawn_api
.postfork();
706 const char *state
= NULL
;
707 const char * argv
[32];
710 if (c
->spawn_api
.atfork
)
711 c
->spawn_api
.atfork();
713 /* We leave most of the cleaning up of the process environment
714 * to the executable. We only clean up the file descriptors to
715 * make sure the executable can actually be loaded
720 argv
[n
++] = c
->conf
->daemon_binary
;
721 argv
[n
++] = "--start";
723 while (n
< PA_ELEMENTSOF(argv
)-1) {
726 if (!(a
= pa_split_spaces(c
->conf
->extra_arguments
, &state
)))
733 pa_assert(n
<= PA_ELEMENTSOF(argv
));
735 execv(argv
[0], (char * const *) argv
);
741 if (c
->spawn_api
.postfork
)
742 c
->spawn_api
.postfork();
745 r
= waitpid(pid
, &status
, 0);
746 } while (r
< 0 && errno
== EINTR
);
750 if (errno
!= ESRCH
) {
751 pa_log(_("waitpid(): %s"), pa_cstrerror(errno
));
752 pa_context_fail(c
, PA_ERR_INTERNAL
);
756 /* hmm, something already reaped our child, so we assume
757 * startup worked, even if we cannot know */
759 } else if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
760 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
775 #endif /* OS_IS_WIN32 */
777 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
);
780 static void track_pulseaudio_on_dbus(pa_context
*c
, DBusBusType type
, pa_dbus_wrap_connection
**conn
) {
786 dbus_error_init(&error
);
788 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, c
->use_rtclock
, type
, &error
)) || dbus_error_is_set(&error
)) {
789 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
793 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
794 pa_log_warn("Failed to add filter function");
798 if (pa_dbus_add_matches(
799 pa_dbus_wrap_connection_get(*conn
), &error
,
800 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL
) < 0) {
802 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
810 pa_dbus_wrap_connection_free(*conn
);
814 dbus_error_free(&error
);
818 static int try_next_connection(pa_context
*c
) {
823 pa_assert(!c
->client
);
829 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
834 if (c
->do_autospawn
) {
836 if ((r
= context_autospawn(c
)) < 0)
839 /* Autospawn only once */
840 c
->do_autospawn
= FALSE
;
842 /* Connect only to per-user sockets this time */
843 c
->server_list
= prepend_per_user(c
->server_list
);
845 /* Retry connection */
851 if (c
->no_fail
&& !c
->server_specified
) {
853 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
855 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
858 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
863 pa_log_debug("Trying to connect to %s...", u
);
866 c
->server
= pa_xstrdup(u
);
868 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, c
->use_rtclock
, u
, PA_NATIVE_DEFAULT_PORT
)))
871 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
872 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
884 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
885 pa_context
*c
= userdata
;
886 int saved_errno
= errno
;
890 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
894 pa_socket_client_unref(client
);
898 /* Try the next item in the list */
899 if (saved_errno
== ECONNREFUSED
||
900 saved_errno
== ETIMEDOUT
||
901 saved_errno
== EHOSTUNREACH
) {
902 try_next_connection(c
);
906 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
910 setup_context(c
, io
);
917 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
918 pa_context
*c
= userdata
;
919 pa_bool_t is_session
;
925 if (c
->state
!= PA_CONTEXT_CONNECTING
)
931 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
933 is_session
= c
->session_bus
&& bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
934 pa_log_debug("Rock!! PulseAudio might be back on %s bus", is_session
? "session" : "system");
937 /* The user instance via PF_LOCAL */
938 c
->server_list
= prepend_per_user(c
->server_list
);
940 /* The system wide instance via PF_LOCAL */
941 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
944 try_next_connection(c
);
947 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
951 int pa_context_connect(
954 pa_context_flags_t flags
,
955 const pa_spawn_api
*api
) {
960 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
962 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
963 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
964 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
965 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
968 c
->conf
->autospawn
= FALSE
;
970 server
= c
->conf
->default_server
;
974 c
->no_fail
= !!(flags
& PA_CONTEXT_NOFAIL
);
975 c
->server_specified
= !!server
;
976 pa_assert(!c
->server_list
);
979 if (!(c
->server_list
= pa_strlist_parse(server
))) {
980 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
987 /* Prepend in reverse order */
989 /* Follow the X display */
990 if ((d
= getenv("DISPLAY"))) {
991 d
= pa_xstrndup(d
, strcspn(d
, ":"));
994 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
999 /* Add TCP/IP on the localhost */
1000 if (c
->conf
->auto_connect_localhost
) {
1001 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
1002 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
1005 /* The system wide instance via PF_LOCAL */
1006 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
1008 /* The user instance via PF_LOCAL */
1009 c
->server_list
= prepend_per_user(c
->server_list
);
1012 /* Set up autospawning */
1013 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
1016 pa_log_debug("Not doing autospawn since we are root.");
1018 c
->do_autospawn
= TRUE
;
1021 c
->spawn_api
= *api
;
1025 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
1026 r
= try_next_connection(c
);
1029 pa_context_unref(c
);
1034 void pa_context_disconnect(pa_context
*c
) {
1036 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1038 if (pa_detect_fork())
1041 if (PA_CONTEXT_IS_GOOD(c
->state
))
1042 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
1045 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
1047 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1052 int pa_context_errno(pa_context
*c
) {
1055 return PA_ERR_INVALID
;
1057 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1062 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1064 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1066 if (pa_detect_fork())
1069 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1072 c
->state_callback
= cb
;
1073 c
->state_userdata
= userdata
;
1076 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1078 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1080 if (pa_detect_fork())
1083 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1086 c
->event_callback
= cb
;
1087 c
->event_userdata
= userdata
;
1090 int pa_context_is_pending(pa_context
*c
) {
1092 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1094 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1095 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1097 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1098 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1102 static void set_dispatch_callbacks(pa_operation
*o
);
1104 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1105 set_dispatch_callbacks(userdata
);
1108 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1109 set_dispatch_callbacks(userdata
);
1112 static void set_dispatch_callbacks(pa_operation
*o
) {
1116 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1117 pa_assert(o
->context
);
1118 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1119 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1121 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1122 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1124 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1125 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1129 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1130 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1136 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1137 cb(o
->context
, o
->userdata
);
1140 pa_operation_done(o
);
1141 pa_operation_unref(o
);
1145 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1149 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1151 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1152 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1153 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1155 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1156 set_dispatch_callbacks(pa_operation_ref(o
));
1161 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1162 pa_operation
*o
= userdata
;
1167 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1172 if (command
!= PA_COMMAND_REPLY
) {
1173 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1177 } else if (!pa_tagstruct_eof(t
)) {
1178 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1183 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1184 cb(o
->context
, success
, o
->userdata
);
1188 pa_operation_done(o
);
1189 pa_operation_unref(o
);
1192 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
) {
1198 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
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
);
1203 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1205 t
= pa_tagstruct_command(c
, command
, &tag
);
1206 pa_pstream_send_tagstruct(c
->pstream
, t
);
1207 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1212 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1214 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1216 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1219 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1225 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1227 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1228 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1230 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1231 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1232 pa_tagstruct_puts(t
, name
);
1233 pa_pstream_send_tagstruct(c
->pstream
, t
);
1234 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
);
1239 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1245 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1247 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1248 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1250 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1251 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1252 pa_tagstruct_puts(t
, name
);
1253 pa_pstream_send_tagstruct(c
->pstream
, t
);
1254 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
);
1259 int pa_context_is_local(pa_context
*c
) {
1261 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1263 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1264 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1266 return !!c
->is_local
;
1269 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1273 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
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
);
1279 if (c
->version
>= 13) {
1280 pa_proplist
*p
= pa_proplist_new();
1282 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1283 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1284 pa_proplist_free(p
);
1289 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1290 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1291 pa_tagstruct_puts(t
, name
);
1292 pa_pstream_send_tagstruct(c
->pstream
, t
);
1293 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
);
1299 const char* pa_get_library_version(void) {
1300 return PACKAGE_VERSION
;
1303 const char* pa_context_get_server(pa_context
*c
) {
1305 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1307 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1308 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1310 if (*c
->server
== '{') {
1311 char *e
= strchr(c
->server
+1, '}');
1312 return e
? e
+1 : c
->server
;
1318 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1319 return PA_PROTOCOL_VERSION
;
1322 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1324 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1326 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1327 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1332 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1338 t
= pa_tagstruct_new(NULL
, 0);
1339 pa_tagstruct_putu32(t
, command
);
1340 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1345 uint32_t pa_context_get_index(pa_context
*c
) {
1347 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1349 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1350 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1351 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1353 return c
->client_index
;
1356 pa_operation
*pa_context_proplist_update(pa_context
*c
, pa_update_mode_t mode
, pa_proplist
*p
, pa_context_success_cb_t cb
, void *userdata
) {
1362 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1364 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1365 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1366 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1367 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1369 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1371 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1372 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1373 pa_tagstruct_put_proplist(t
, p
);
1375 pa_pstream_send_tagstruct(c
->pstream
, t
);
1376 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
);
1378 /* Please note that we don't update c->proplist here, because we
1379 * don't export that field */
1384 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1388 const char * const *k
;
1391 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1393 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1394 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1395 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1396 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1398 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1400 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1402 for (k
= keys
; *k
; k
++)
1403 pa_tagstruct_puts(t
, *k
);
1405 pa_tagstruct_puts(t
, NULL
);
1407 pa_pstream_send_tagstruct(c
->pstream
, t
);
1408 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
);
1410 /* Please note that we don't update c->proplist here, because we
1411 * don't export that field */
1416 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1417 pa_context
*c
= userdata
;
1422 pa_assert(command
== PA_COMMAND_EXTENSION
);
1425 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1429 if (c
->version
< 15) {
1430 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1434 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1435 pa_tagstruct_gets(t
, &name
) < 0) {
1436 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1440 if (!strcmp(name
, "module-stream-restore"))
1441 pa_ext_stream_restore_command(c
, tag
, t
);
1442 else if (!strcmp(name
, "module-device-manager"))
1443 pa_ext_device_manager_command(c
, tag
, t
);
1445 pa_log(_("Received message for unknown extension '%s'"), name
);
1448 pa_context_unref(c
);
1452 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1453 pa_context
*c
= userdata
;
1454 pa_proplist
*pl
= NULL
;
1458 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1461 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1465 if (c
->version
< 15) {
1466 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1470 pl
= pa_proplist_new();
1472 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1473 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1474 !pa_tagstruct_eof(t
) || !event
) {
1475 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1479 if (c
->event_callback
)
1480 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1483 pa_context_unref(c
);
1486 pa_proplist_free(pl
);
1489 pa_time_event
* pa_context_rttime_new(pa_context
*c
, pa_usec_t usec
, pa_time_event_cb_t cb
, void *userdata
) {
1493 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1494 pa_assert(c
->mainloop
);
1496 if (usec
== PA_USEC_INVALID
)
1497 return c
->mainloop
->time_new(c
->mainloop
, NULL
, cb
, userdata
);
1499 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1501 return c
->mainloop
->time_new(c
->mainloop
, &tv
, cb
, userdata
);
1504 void pa_context_rttime_restart(pa_context
*c
, pa_time_event
*e
, pa_usec_t usec
) {
1508 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1509 pa_assert(c
->mainloop
);
1512 if (usec
== PA_USEC_INVALID
)
1513 c
->mainloop
->time_restart(e
, NULL
);
1515 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1516 c
->mainloop
->time_restart(e
, &tv
);
1520 size_t pa_context_get_tile_size(pa_context
*c
, const pa_sample_spec
*ss
) {
1524 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1526 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, (size_t) -1);
1527 PA_CHECK_VALIDITY_RETURN_ANY(c
, !ss
|| pa_sample_spec_valid(ss
), PA_ERR_INVALID
, (size_t) -1);
1529 fs
= ss
? pa_frame_size(ss
) : 1;
1530 mbs
= PA_ROUND_DOWN(pa_mempool_block_size_max(c
->mempool
), fs
);
1531 return PA_MAX(mbs
, fs
);