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>
36 #ifdef HAVE_SYS_WAIT_H
44 #include <pulse/version.h>
45 #include <pulse/xmalloc.h>
46 #include <pulse/util.h>
47 #include <pulse/mainloop.h>
48 #include <pulse/timeval.h>
49 #include <pulse/fork-detect.h>
50 #include <pulse/client-conf.h>
52 #include <pulse/client-conf-x11.h>
55 #include <pulsecore/core-error.h>
56 #include <pulsecore/i18n.h>
57 #include <pulsecore/native-common.h>
58 #include <pulsecore/pdispatch.h>
59 #include <pulsecore/pstream.h>
60 #include <pulsecore/hashmap.h>
61 #include <pulsecore/socket-client.h>
62 #include <pulsecore/pstream-util.h>
63 #include <pulsecore/core-rtclock.h>
64 #include <pulsecore/core-util.h>
65 #include <pulsecore/log.h>
66 #include <pulsecore/socket.h>
67 #include <pulsecore/creds.h>
68 #include <pulsecore/macro.h>
69 #include <pulsecore/proplist-util.h>
74 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
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
95 static void context_free(pa_context
*c
);
98 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
);
101 pa_context
*pa_context_new(pa_mainloop_api
*mainloop
, const char *name
) {
102 return pa_context_new_with_proplist(mainloop
, name
, NULL
);
105 static void reset_callbacks(pa_context
*c
) {
108 c
->state_callback
= NULL
;
109 c
->state_userdata
= NULL
;
111 c
->subscribe_callback
= NULL
;
112 c
->subscribe_userdata
= NULL
;
114 c
->event_callback
= NULL
;
115 c
->event_userdata
= NULL
;
117 c
->ext_device_manager
.callback
= NULL
;
118 c
->ext_device_manager
.userdata
= NULL
;
120 c
->ext_device_restore
.callback
= NULL
;
121 c
->ext_device_restore
.userdata
= NULL
;
123 c
->ext_stream_restore
.callback
= NULL
;
124 c
->ext_stream_restore
.userdata
= NULL
;
127 pa_context
*pa_context_new_with_proplist(pa_mainloop_api
*mainloop
, const char *name
, pa_proplist
*p
) {
132 if (pa_detect_fork())
137 c
= pa_xnew0(pa_context
, 1);
140 c
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
143 pa_proplist_sets(c
->proplist
, PA_PROP_APPLICATION_NAME
, name
);
146 c
->system_bus
= c
->session_bus
= NULL
;
148 c
->mainloop
= mainloop
;
149 c
->playback_streams
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
150 c
->record_streams
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
151 c
->client_index
= PA_INVALID_INDEX
;
152 c
->use_rtclock
= pa_mainloop_is_our_api(mainloop
);
154 PA_LLIST_HEAD_INIT(pa_stream
, c
->streams
);
155 PA_LLIST_HEAD_INIT(pa_operation
, c
->operations
);
158 c
->state
= PA_CONTEXT_UNCONNECTED
;
164 pa_check_signal_is_blocked(SIGPIPE
);
168 c
->conf
= pa_client_conf_new();
169 pa_client_conf_load(c
->conf
, NULL
);
171 pa_client_conf_from_x11(c
->conf
, NULL
);
173 pa_client_conf_env(c
->conf
);
175 if (!(c
->mempool
= pa_mempool_new(!c
->conf
->disable_shm
, c
->conf
->shm_size
))) {
177 if (!c
->conf
->disable_shm
)
178 c
->mempool
= pa_mempool_new(FALSE
, c
->conf
->shm_size
);
189 static void context_unlink(pa_context
*c
) {
194 s
= c
->streams
? pa_stream_ref(c
->streams
) : NULL
;
196 pa_stream
*n
= s
->next
? pa_stream_ref(s
->next
) : NULL
;
197 pa_stream_set_state(s
, c
->state
== PA_CONTEXT_FAILED
? PA_STREAM_FAILED
: PA_STREAM_TERMINATED
);
202 while (c
->operations
)
203 pa_operation_cancel(c
->operations
);
206 pa_pdispatch_unref(c
->pdispatch
);
211 pa_pstream_unlink(c
->pstream
);
212 pa_pstream_unref(c
->pstream
);
217 pa_socket_client_unref(c
->client
);
224 static void context_free(pa_context
*c
) {
232 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->system_bus
), filter_cb
, c
);
233 pa_dbus_wrap_connection_free(c
->system_bus
);
236 if (c
->session_bus
) {
238 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->session_bus
), filter_cb
, c
);
239 pa_dbus_wrap_connection_free(c
->session_bus
);
243 if (c
->record_streams
)
244 pa_hashmap_free(c
->record_streams
, NULL
, NULL
);
245 if (c
->playback_streams
)
246 pa_hashmap_free(c
->playback_streams
, NULL
, NULL
);
249 pa_mempool_free(c
->mempool
);
252 pa_client_conf_free(c
->conf
);
254 pa_strlist_free(c
->server_list
);
257 pa_proplist_free(c
->proplist
);
263 pa_context
* pa_context_ref(pa_context
*c
) {
265 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
271 void pa_context_unref(pa_context
*c
) {
273 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
275 if (PA_REFCNT_DEC(c
) <= 0)
279 void pa_context_set_state(pa_context
*c
, pa_context_state_t st
) {
281 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
290 if (c
->state_callback
)
291 c
->state_callback(c
, c
->state_userdata
);
293 if (st
== PA_CONTEXT_FAILED
|| st
== PA_CONTEXT_TERMINATED
)
299 int pa_context_set_error(pa_context
*c
, int error
) {
300 pa_assert(error
>= 0);
301 pa_assert(error
< PA_ERR_MAX
);
309 void pa_context_fail(pa_context
*c
, int error
) {
311 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
313 pa_context_set_error(c
, error
);
314 pa_context_set_state(c
, PA_CONTEXT_FAILED
);
317 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
318 pa_context
*c
= userdata
;
323 pa_context_fail(c
, PA_ERR_CONNECTIONTERMINATED
);
326 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
327 pa_context
*c
= userdata
;
335 if (pa_pdispatch_run(c
->pdispatch
, packet
, creds
, c
) < 0)
336 pa_context_fail(c
, PA_ERR_PROTOCOL
);
341 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
) {
342 pa_context
*c
= userdata
;
347 pa_assert(chunk
->length
> 0);
349 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
353 if ((s
= pa_hashmap_get(c
->record_streams
, PA_UINT32_TO_PTR(channel
)))) {
355 if (chunk
->memblock
) {
356 pa_memblockq_seek(s
->record_memblockq
, offset
, seek
, TRUE
);
357 pa_memblockq_push_align(s
->record_memblockq
, chunk
);
359 pa_memblockq_seek(s
->record_memblockq
, offset
+chunk
->length
, seek
, TRUE
);
361 if (s
->read_callback
) {
364 if ((l
= pa_memblockq_get_length(s
->record_memblockq
)) > 0)
365 s
->read_callback(s
, l
, s
->read_userdata
);
372 int pa_context_handle_error(pa_context
*c
, uint32_t command
, pa_tagstruct
*t
, pa_bool_t fail
) {
375 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
377 if (command
== PA_COMMAND_ERROR
) {
380 if (pa_tagstruct_getu32(t
, &err
) < 0 ||
381 !pa_tagstruct_eof(t
)) {
382 pa_context_fail(c
, PA_ERR_PROTOCOL
);
386 } else if (command
== PA_COMMAND_TIMEOUT
)
387 err
= PA_ERR_TIMEOUT
;
389 pa_context_fail(c
, PA_ERR_PROTOCOL
);
394 pa_context_fail(c
, PA_ERR_PROTOCOL
);
398 if (err
>= PA_ERR_MAX
)
399 err
= PA_ERR_UNKNOWN
;
402 pa_context_fail(c
, (int) err
);
406 pa_context_set_error(c
, (int) err
);
411 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
412 pa_context
*c
= userdata
;
416 pa_assert(c
->state
== PA_CONTEXT_AUTHORIZING
|| c
->state
== PA_CONTEXT_SETTING_NAME
);
420 if (command
!= PA_COMMAND_REPLY
) {
421 pa_context_handle_error(c
, command
, t
, TRUE
);
426 case PA_CONTEXT_AUTHORIZING
: {
428 pa_bool_t shm_on_remote
= FALSE
;
430 if (pa_tagstruct_getu32(t
, &c
->version
) < 0 ||
431 !pa_tagstruct_eof(t
)) {
432 pa_context_fail(c
, PA_ERR_PROTOCOL
);
436 /* Minimum supported version */
437 if (c
->version
< 8) {
438 pa_context_fail(c
, PA_ERR_VERSION
);
442 /* Starting with protocol version 13 the MSB of the version
443 tag reflects if shm is available for this connection or
445 if (c
->version
>= 13) {
446 shm_on_remote
= !!(c
->version
& 0x80000000U
);
447 c
->version
&= 0x7FFFFFFFU
;
450 pa_log_debug("Protocol version: remote %u, local %u", c
->version
, PA_PROTOCOL_VERSION
);
452 /* Enable shared memory support if possible */
454 if (c
->version
< 10 || (c
->version
>= 13 && !shm_on_remote
))
459 /* Only enable SHM if both sides are owned by the same
460 * user. This is a security measure because otherwise
461 * data private to the user might leak. */
464 const pa_creds
*creds
;
465 if (!(creds
= pa_pdispatch_creds(pd
)) || getuid() != creds
->uid
)
470 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c
->do_shm
));
471 pa_pstream_enable_shm(c
->pstream
, c
->do_shm
);
473 reply
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
475 if (c
->version
>= 13) {
476 pa_init_proplist(c
->proplist
);
477 pa_tagstruct_put_proplist(reply
, c
->proplist
);
479 pa_tagstruct_puts(reply
, pa_proplist_gets(c
->proplist
, PA_PROP_APPLICATION_NAME
));
481 pa_pstream_send_tagstruct(c
->pstream
, reply
);
482 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
484 pa_context_set_state(c
, PA_CONTEXT_SETTING_NAME
);
488 case PA_CONTEXT_SETTING_NAME
:
490 if ((c
->version
>= 13 && (pa_tagstruct_getu32(t
, &c
->client_index
) < 0 ||
491 c
->client_index
== PA_INVALID_INDEX
)) ||
492 !pa_tagstruct_eof(t
)) {
493 pa_context_fail(c
, PA_ERR_PROTOCOL
);
497 pa_context_set_state(c
, PA_CONTEXT_READY
);
501 pa_assert_not_reached();
508 static void setup_context(pa_context
*c
, pa_iochannel
*io
) {
517 pa_assert(!c
->pstream
);
518 c
->pstream
= pa_pstream_new(c
->mainloop
, io
, c
->mempool
);
520 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
521 pa_pstream_set_receive_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
522 pa_pstream_set_receive_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
524 pa_assert(!c
->pdispatch
);
525 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, c
->use_rtclock
, command_table
, PA_COMMAND_MAX
);
527 if (!c
->conf
->cookie_valid
)
528 pa_log_info(_("No cookie loaded. Attempting to connect without."));
530 t
= pa_tagstruct_command(c
, PA_COMMAND_AUTH
, &tag
);
533 pa_mempool_is_shared(c
->mempool
) &&
536 pa_log_debug("SHM possible: %s", pa_yes_no(c
->do_shm
));
538 /* Starting with protocol version 13 we use the MSB of the version
539 * tag for informing the other side if we could do SHM or not */
540 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
| (c
->do_shm
? 0x80000000U
: 0));
541 pa_tagstruct_put_arbitrary(t
, c
->conf
->cookie
, sizeof(c
->conf
->cookie
));
547 if (pa_iochannel_creds_supported(io
))
548 pa_iochannel_creds_enable(io
);
550 ucred
.uid
= getuid();
551 ucred
.gid
= getgid();
553 pa_pstream_send_tagstruct_with_creds(c
->pstream
, t
, &ucred
);
556 pa_pstream_send_tagstruct(c
->pstream
, t
);
559 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
561 pa_context_set_state(c
, PA_CONTEXT_AUTHORIZING
);
566 #ifdef ENABLE_LEGACY_RUNTIME_DIR
567 static char *get_old_legacy_runtime_dir(void) {
571 if (!pa_get_user_name(u
, sizeof(u
)))
574 p
= pa_sprintf_malloc("/tmp/pulse-%s", u
);
576 if (stat(p
, &st
) < 0) {
582 if (st
.st_uid
!= getuid()) {
591 static char *get_very_old_legacy_runtime_dir(void) {
595 if (!pa_get_home_dir(h
, sizeof(h
)))
598 p
= pa_sprintf_malloc("%s/.pulse", h
);
600 if (stat(p
, &st
) < 0) {
606 if (st
.st_uid
!= getuid()) {
616 static pa_strlist
*prepend_per_user(pa_strlist
*l
) {
619 #ifdef ENABLE_LEGACY_RUNTIME_DIR
622 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
623 if ((legacy_dir
= get_very_old_legacy_runtime_dir())) {
624 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
625 l
= pa_strlist_prepend(l
, p
);
627 pa_xfree(legacy_dir
);
630 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
631 if ((legacy_dir
= get_old_legacy_runtime_dir())) {
632 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
633 l
= pa_strlist_prepend(l
, p
);
635 pa_xfree(legacy_dir
);
639 /* The per-user instance */
640 if ((ufn
= pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET
))) {
641 l
= pa_strlist_prepend(l
, ufn
);
650 static int context_autospawn(pa_context
*c
) {
657 if (sigaction(SIGCHLD
, NULL
, &sa
) < 0) {
658 pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno
));
659 pa_context_fail(c
, PA_ERR_INTERNAL
);
663 if ((sa
.sa_flags
& SA_NOCLDWAIT
) || sa
.sa_handler
== SIG_IGN
) {
664 pa_log_debug("Process disabled waitpid(), cannot autospawn.");
665 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
669 pa_log_debug("Trying to autospawn...");
671 if (c
->spawn_api
.prefork
)
672 c
->spawn_api
.prefork();
674 if ((pid
= fork()) < 0) {
675 pa_log_error(_("fork(): %s"), pa_cstrerror(errno
));
676 pa_context_fail(c
, PA_ERR_INTERNAL
);
678 if (c
->spawn_api
.postfork
)
679 c
->spawn_api
.postfork();
685 const char *state
= NULL
;
686 const char * argv
[32];
689 if (c
->spawn_api
.atfork
)
690 c
->spawn_api
.atfork();
692 /* We leave most of the cleaning up of the process environment
693 * to the executable. We only clean up the file descriptors to
694 * make sure the executable can actually be loaded
699 argv
[n
++] = c
->conf
->daemon_binary
;
700 argv
[n
++] = "--start";
702 while (n
< PA_ELEMENTSOF(argv
)-1) {
705 if (!(a
= pa_split_spaces(c
->conf
->extra_arguments
, &state
)))
712 pa_assert(n
<= PA_ELEMENTSOF(argv
));
714 execv(argv
[0], (char * const *) argv
);
720 if (c
->spawn_api
.postfork
)
721 c
->spawn_api
.postfork();
724 r
= waitpid(pid
, &status
, 0);
725 } while (r
< 0 && errno
== EINTR
);
729 if (errno
!= ESRCH
) {
730 pa_log(_("waitpid(): %s"), pa_cstrerror(errno
));
731 pa_context_fail(c
, PA_ERR_INTERNAL
);
735 /* hmm, something already reaped our child, so we assume
736 * startup worked, even if we cannot know */
738 } else if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
739 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
754 #endif /* OS_IS_WIN32 */
756 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
);
759 static void track_pulseaudio_on_dbus(pa_context
*c
, DBusBusType type
, pa_dbus_wrap_connection
**conn
) {
765 dbus_error_init(&error
);
767 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, c
->use_rtclock
, type
, &error
)) || dbus_error_is_set(&error
)) {
768 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
772 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
773 pa_log_warn("Failed to add filter function");
776 c
->filter_added
= TRUE
;
778 if (pa_dbus_add_matches(
779 pa_dbus_wrap_connection_get(*conn
), &error
,
780 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL
) < 0) {
782 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
790 pa_dbus_wrap_connection_free(*conn
);
794 dbus_error_free(&error
);
798 static int try_next_connection(pa_context
*c
) {
803 pa_assert(!c
->client
);
809 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
814 if (c
->do_autospawn
) {
816 if ((r
= context_autospawn(c
)) < 0)
819 /* Autospawn only once */
820 c
->do_autospawn
= FALSE
;
822 /* Connect only to per-user sockets this time */
823 c
->server_list
= prepend_per_user(c
->server_list
);
825 /* Retry connection */
831 if (c
->no_fail
&& !c
->server_specified
) {
833 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
835 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
838 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
843 pa_log_debug("Trying to connect to %s...", u
);
846 c
->server
= pa_xstrdup(u
);
848 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, c
->use_rtclock
, u
, PA_NATIVE_DEFAULT_PORT
)))
851 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
852 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
864 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
865 pa_context
*c
= userdata
;
866 int saved_errno
= errno
;
870 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
874 pa_socket_client_unref(client
);
878 /* Try the next item in the list */
879 if (saved_errno
== ECONNREFUSED
||
880 saved_errno
== ETIMEDOUT
||
881 saved_errno
== EHOSTUNREACH
) {
882 try_next_connection(c
);
886 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
890 setup_context(c
, io
);
897 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
898 pa_context
*c
= userdata
;
899 pa_bool_t is_session
;
905 if (c
->state
!= PA_CONTEXT_CONNECTING
)
911 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
913 is_session
= c
->session_bus
&& bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
914 pa_log_debug("Rock!! PulseAudio might be back on %s bus", is_session
? "session" : "system");
917 /* The user instance via PF_LOCAL */
918 c
->server_list
= prepend_per_user(c
->server_list
);
920 /* The system wide instance via PF_LOCAL */
921 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
924 try_next_connection(c
);
927 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
931 int pa_context_connect(
934 pa_context_flags_t flags
,
935 const pa_spawn_api
*api
) {
940 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
942 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
943 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
944 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
945 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
948 c
->conf
->autospawn
= FALSE
;
950 server
= c
->conf
->default_server
;
954 c
->no_fail
= !!(flags
& PA_CONTEXT_NOFAIL
);
955 c
->server_specified
= !!server
;
956 pa_assert(!c
->server_list
);
959 if (!(c
->server_list
= pa_strlist_parse(server
))) {
960 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
967 /* Prepend in reverse order */
969 /* Follow the X display */
970 if (c
->conf
->auto_connect_display
) {
971 if ((d
= getenv("DISPLAY"))) {
972 d
= pa_xstrndup(d
, strcspn(d
, ":"));
975 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
981 /* Add TCP/IP on the localhost */
982 if (c
->conf
->auto_connect_localhost
) {
983 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
984 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
987 /* The system wide instance via PF_LOCAL */
988 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
990 /* The user instance via PF_LOCAL */
991 c
->server_list
= prepend_per_user(c
->server_list
);
994 /* Set up autospawning */
995 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
999 pa_log_debug("Not doing autospawn since we are root.");
1001 c
->do_autospawn
= TRUE
;
1004 c
->spawn_api
= *api
;
1009 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
1010 r
= try_next_connection(c
);
1013 pa_context_unref(c
);
1018 void pa_context_disconnect(pa_context
*c
) {
1020 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1022 if (pa_detect_fork())
1025 if (PA_CONTEXT_IS_GOOD(c
->state
))
1026 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
1029 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
1031 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1036 int pa_context_errno(pa_context
*c
) {
1039 return PA_ERR_INVALID
;
1041 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1046 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1048 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1050 if (pa_detect_fork())
1053 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1056 c
->state_callback
= cb
;
1057 c
->state_userdata
= userdata
;
1060 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1062 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1064 if (pa_detect_fork())
1067 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1070 c
->event_callback
= cb
;
1071 c
->event_userdata
= userdata
;
1074 int pa_context_is_pending(pa_context
*c
) {
1076 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1078 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1079 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1081 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1082 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1086 static void set_dispatch_callbacks(pa_operation
*o
);
1088 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1089 set_dispatch_callbacks(userdata
);
1092 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1093 set_dispatch_callbacks(userdata
);
1096 static void set_dispatch_callbacks(pa_operation
*o
) {
1100 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1101 pa_assert(o
->context
);
1102 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1103 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1105 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1106 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1108 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1109 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1113 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1114 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1120 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1121 cb(o
->context
, o
->userdata
);
1124 pa_operation_done(o
);
1125 pa_operation_unref(o
);
1129 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1133 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1135 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1136 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1137 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1139 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1140 set_dispatch_callbacks(pa_operation_ref(o
));
1145 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1146 pa_operation
*o
= userdata
;
1151 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1156 if (command
!= PA_COMMAND_REPLY
) {
1157 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1161 } else if (!pa_tagstruct_eof(t
)) {
1162 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1167 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1168 cb(o
->context
, success
, o
->userdata
);
1172 pa_operation_done(o
);
1173 pa_operation_unref(o
);
1176 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
) {
1182 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1184 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1185 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1187 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1189 t
= pa_tagstruct_command(c
, command
, &tag
);
1190 pa_pstream_send_tagstruct(c
->pstream
, t
);
1191 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1196 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1198 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1200 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1203 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1209 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1211 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1212 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1214 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1215 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1216 pa_tagstruct_puts(t
, name
);
1217 pa_pstream_send_tagstruct(c
->pstream
, t
);
1218 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
);
1223 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1229 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1231 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1232 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1234 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1235 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1236 pa_tagstruct_puts(t
, name
);
1237 pa_pstream_send_tagstruct(c
->pstream
, t
);
1238 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
);
1243 int pa_context_is_local(pa_context
*c
) {
1245 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1247 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1248 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1250 return !!c
->is_local
;
1253 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1257 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1260 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1261 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1263 if (c
->version
>= 13) {
1264 pa_proplist
*p
= pa_proplist_new();
1266 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1267 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1268 pa_proplist_free(p
);
1273 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1274 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1275 pa_tagstruct_puts(t
, name
);
1276 pa_pstream_send_tagstruct(c
->pstream
, t
);
1277 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
);
1283 const char* pa_get_library_version(void) {
1284 return pa_get_headers_version();
1287 const char* pa_context_get_server(pa_context
*c
) {
1289 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1291 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1292 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1294 if (*c
->server
== '{') {
1295 char *e
= strchr(c
->server
+1, '}');
1296 return e
? e
+1 : c
->server
;
1302 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1303 return PA_PROTOCOL_VERSION
;
1306 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1308 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1310 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1311 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1316 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1322 t
= pa_tagstruct_new(NULL
, 0);
1323 pa_tagstruct_putu32(t
, command
);
1324 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1329 uint32_t pa_context_get_index(pa_context
*c
) {
1331 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1333 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1334 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1335 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1337 return c
->client_index
;
1340 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
) {
1346 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1348 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1349 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1350 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1351 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1353 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1355 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1356 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1357 pa_tagstruct_put_proplist(t
, p
);
1359 pa_pstream_send_tagstruct(c
->pstream
, t
);
1360 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
);
1362 /* Please note that we don't update c->proplist here, because we
1363 * don't export that field */
1368 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1372 const char * const *k
;
1375 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1377 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1378 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1379 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1380 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1382 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1384 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1386 for (k
= keys
; *k
; k
++)
1387 pa_tagstruct_puts(t
, *k
);
1389 pa_tagstruct_puts(t
, NULL
);
1391 pa_pstream_send_tagstruct(c
->pstream
, t
);
1392 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
);
1394 /* Please note that we don't update c->proplist here, because we
1395 * don't export that field */
1400 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1401 pa_context
*c
= userdata
;
1406 pa_assert(command
== PA_COMMAND_EXTENSION
);
1409 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1413 if (c
->version
< 15) {
1414 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1418 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1419 pa_tagstruct_gets(t
, &name
) < 0) {
1420 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1424 if (pa_streq(name
, "module-device-manager"))
1425 pa_ext_device_manager_command(c
, tag
, t
);
1426 else if (pa_streq(name
, "module-device-restore"))
1427 pa_ext_device_restore_command(c
, tag
, t
);
1428 else if (pa_streq(name
, "module-stream-restore"))
1429 pa_ext_stream_restore_command(c
, tag
, t
);
1431 pa_log(_("Received message for unknown extension '%s'"), name
);
1434 pa_context_unref(c
);
1438 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1439 pa_context
*c
= userdata
;
1440 pa_proplist
*pl
= NULL
;
1444 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1447 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1451 if (c
->version
< 15) {
1452 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1456 pl
= pa_proplist_new();
1458 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1459 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1460 !pa_tagstruct_eof(t
) || !event
) {
1461 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1465 if (c
->event_callback
)
1466 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1469 pa_context_unref(c
);
1472 pa_proplist_free(pl
);
1475 pa_time_event
* pa_context_rttime_new(pa_context
*c
, pa_usec_t usec
, pa_time_event_cb_t cb
, void *userdata
) {
1479 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1480 pa_assert(c
->mainloop
);
1482 if (usec
== PA_USEC_INVALID
)
1483 return c
->mainloop
->time_new(c
->mainloop
, NULL
, cb
, userdata
);
1485 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1487 return c
->mainloop
->time_new(c
->mainloop
, &tv
, cb
, userdata
);
1490 void pa_context_rttime_restart(pa_context
*c
, pa_time_event
*e
, pa_usec_t usec
) {
1494 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1495 pa_assert(c
->mainloop
);
1498 if (usec
== PA_USEC_INVALID
)
1499 c
->mainloop
->time_restart(e
, NULL
);
1501 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1502 c
->mainloop
->time_restart(e
, &tv
);
1506 size_t pa_context_get_tile_size(pa_context
*c
, const pa_sample_spec
*ss
) {
1510 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1512 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, (size_t) -1);
1513 PA_CHECK_VALIDITY_RETURN_ANY(c
, !ss
|| pa_sample_spec_valid(ss
), PA_ERR_INVALID
, (size_t) -1);
1515 fs
= ss
? pa_frame_size(ss
) : 1;
1516 mbs
= PA_ROUND_DOWN(pa_mempool_block_size_max(c
->mempool
), fs
);
1517 return PA_MAX(mbs
, fs
);