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
49 #include <pulse/version.h>
50 #include <pulse/xmalloc.h>
51 #include <pulse/utf8.h>
52 #include <pulse/util.h>
53 #include <pulse/i18n.h>
54 #include <pulse/mainloop.h>
55 #include <pulse/timeval.h>
56 #include <pulse/fork-detect.h>
57 #include <pulse/client-conf.h>
59 #include <pulse/client-conf-x11.h>
62 #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.h>
73 #include <pulsecore/socket-util.h>
74 #include <pulsecore/creds.h>
75 #include <pulsecore/macro.h>
76 #include <pulsecore/proplist-util.h>
81 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
83 static const pa_pdispatch_cb_t command_table
[PA_COMMAND_MAX
] = {
84 [PA_COMMAND_REQUEST
] = pa_command_request
,
85 [PA_COMMAND_OVERFLOW
] = pa_command_overflow_or_underflow
,
86 [PA_COMMAND_UNDERFLOW
] = pa_command_overflow_or_underflow
,
87 [PA_COMMAND_PLAYBACK_STREAM_KILLED
] = pa_command_stream_killed
,
88 [PA_COMMAND_RECORD_STREAM_KILLED
] = pa_command_stream_killed
,
89 [PA_COMMAND_PLAYBACK_STREAM_MOVED
] = pa_command_stream_moved
,
90 [PA_COMMAND_RECORD_STREAM_MOVED
] = pa_command_stream_moved
,
91 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
] = pa_command_stream_suspended
,
92 [PA_COMMAND_RECORD_STREAM_SUSPENDED
] = pa_command_stream_suspended
,
93 [PA_COMMAND_STARTED
] = pa_command_stream_started
,
94 [PA_COMMAND_SUBSCRIBE_EVENT
] = pa_command_subscribe_event
,
95 [PA_COMMAND_EXTENSION
] = pa_command_extension
,
96 [PA_COMMAND_PLAYBACK_STREAM_EVENT
] = pa_command_stream_event
,
97 [PA_COMMAND_RECORD_STREAM_EVENT
] = pa_command_stream_event
,
98 [PA_COMMAND_CLIENT_EVENT
] = pa_command_client_event
,
99 [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
,
100 [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
102 static void context_free(pa_context
*c
);
105 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
);
108 pa_context
*pa_context_new(pa_mainloop_api
*mainloop
, const char *name
) {
109 return pa_context_new_with_proplist(mainloop
, name
, NULL
);
112 static void reset_callbacks(pa_context
*c
) {
115 c
->state_callback
= NULL
;
116 c
->state_userdata
= NULL
;
118 c
->subscribe_callback
= NULL
;
119 c
->subscribe_userdata
= NULL
;
121 c
->event_callback
= NULL
;
122 c
->event_userdata
= NULL
;
124 c
->ext_device_manager
.callback
= NULL
;
125 c
->ext_device_manager
.userdata
= NULL
;
127 c
->ext_stream_restore
.callback
= NULL
;
128 c
->ext_stream_restore
.userdata
= NULL
;
131 pa_context
*pa_context_new_with_proplist(pa_mainloop_api
*mainloop
, const char *name
, pa_proplist
*p
) {
136 if (pa_detect_fork())
141 c
= pa_xnew0(pa_context
, 1);
144 c
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
147 pa_proplist_sets(c
->proplist
, PA_PROP_APPLICATION_NAME
, name
);
150 c
->system_bus
= c
->session_bus
= NULL
;
152 c
->mainloop
= mainloop
;
153 c
->playback_streams
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
154 c
->record_streams
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
155 c
->client_index
= PA_INVALID_INDEX
;
156 c
->use_rtclock
= pa_mainloop_is_our_api(mainloop
);
158 PA_LLIST_HEAD_INIT(pa_stream
, c
->streams
);
159 PA_LLIST_HEAD_INIT(pa_operation
, c
->operations
);
162 c
->state
= PA_CONTEXT_UNCONNECTED
;
168 pa_check_signal_is_blocked(SIGPIPE
);
172 c
->conf
= pa_client_conf_new();
173 pa_client_conf_load(c
->conf
, NULL
);
175 pa_client_conf_from_x11(c
->conf
, NULL
);
177 pa_client_conf_env(c
->conf
);
179 if (!(c
->mempool
= pa_mempool_new(!c
->conf
->disable_shm
, c
->conf
->shm_size
))) {
181 if (!c
->conf
->disable_shm
)
182 c
->mempool
= pa_mempool_new(FALSE
, c
->conf
->shm_size
);
193 static void context_unlink(pa_context
*c
) {
198 s
= c
->streams
? pa_stream_ref(c
->streams
) : NULL
;
200 pa_stream
*n
= s
->next
? pa_stream_ref(s
->next
) : NULL
;
201 pa_stream_set_state(s
, c
->state
== PA_CONTEXT_FAILED
? PA_STREAM_FAILED
: PA_STREAM_TERMINATED
);
206 while (c
->operations
)
207 pa_operation_cancel(c
->operations
);
210 pa_pdispatch_unref(c
->pdispatch
);
215 pa_pstream_unlink(c
->pstream
);
216 pa_pstream_unref(c
->pstream
);
221 pa_socket_client_unref(c
->client
);
228 static void context_free(pa_context
*c
) {
236 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->system_bus
), filter_cb
, c
);
237 pa_dbus_wrap_connection_free(c
->system_bus
);
240 if (c
->session_bus
) {
242 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->session_bus
), filter_cb
, c
);
243 pa_dbus_wrap_connection_free(c
->session_bus
);
247 if (c
->record_streams
)
248 pa_hashmap_free(c
->record_streams
, NULL
, NULL
);
249 if (c
->playback_streams
)
250 pa_hashmap_free(c
->playback_streams
, NULL
, NULL
);
253 pa_mempool_free(c
->mempool
);
256 pa_client_conf_free(c
->conf
);
258 pa_strlist_free(c
->server_list
);
261 pa_proplist_free(c
->proplist
);
267 pa_context
* pa_context_ref(pa_context
*c
) {
269 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
275 void pa_context_unref(pa_context
*c
) {
277 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
279 if (PA_REFCNT_DEC(c
) <= 0)
283 void pa_context_set_state(pa_context
*c
, pa_context_state_t st
) {
285 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
294 if (c
->state_callback
)
295 c
->state_callback(c
, c
->state_userdata
);
297 if (st
== PA_CONTEXT_FAILED
|| st
== PA_CONTEXT_TERMINATED
)
303 int pa_context_set_error(pa_context
*c
, int error
) {
304 pa_assert(error
>= 0);
305 pa_assert(error
< PA_ERR_MAX
);
313 void pa_context_fail(pa_context
*c
, int error
) {
315 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
317 pa_context_set_error(c
, error
);
318 pa_context_set_state(c
, PA_CONTEXT_FAILED
);
321 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
322 pa_context
*c
= userdata
;
327 pa_context_fail(c
, PA_ERR_CONNECTIONTERMINATED
);
330 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
331 pa_context
*c
= userdata
;
339 if (pa_pdispatch_run(c
->pdispatch
, packet
, creds
, c
) < 0)
340 pa_context_fail(c
, PA_ERR_PROTOCOL
);
345 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
) {
346 pa_context
*c
= userdata
;
351 pa_assert(chunk
->length
> 0);
353 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
357 if ((s
= pa_hashmap_get(c
->record_streams
, PA_UINT32_TO_PTR(channel
)))) {
359 if (chunk
->memblock
) {
360 pa_memblockq_seek(s
->record_memblockq
, offset
, seek
, TRUE
);
361 pa_memblockq_push_align(s
->record_memblockq
, chunk
);
363 pa_memblockq_seek(s
->record_memblockq
, offset
+chunk
->length
, seek
, TRUE
);
365 if (s
->read_callback
) {
368 if ((l
= pa_memblockq_get_length(s
->record_memblockq
)) > 0)
369 s
->read_callback(s
, l
, s
->read_userdata
);
376 int pa_context_handle_error(pa_context
*c
, uint32_t command
, pa_tagstruct
*t
, pa_bool_t fail
) {
379 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
381 if (command
== PA_COMMAND_ERROR
) {
384 if (pa_tagstruct_getu32(t
, &err
) < 0 ||
385 !pa_tagstruct_eof(t
)) {
386 pa_context_fail(c
, PA_ERR_PROTOCOL
);
390 } else if (command
== PA_COMMAND_TIMEOUT
)
391 err
= PA_ERR_TIMEOUT
;
393 pa_context_fail(c
, PA_ERR_PROTOCOL
);
398 pa_context_fail(c
, PA_ERR_PROTOCOL
);
402 if (err
>= PA_ERR_MAX
)
403 err
= PA_ERR_UNKNOWN
;
406 pa_context_fail(c
, (int) err
);
410 pa_context_set_error(c
, (int) err
);
415 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
416 pa_context
*c
= userdata
;
420 pa_assert(c
->state
== PA_CONTEXT_AUTHORIZING
|| c
->state
== PA_CONTEXT_SETTING_NAME
);
424 if (command
!= PA_COMMAND_REPLY
) {
425 pa_context_handle_error(c
, command
, t
, TRUE
);
430 case PA_CONTEXT_AUTHORIZING
: {
432 pa_bool_t shm_on_remote
= FALSE
;
434 if (pa_tagstruct_getu32(t
, &c
->version
) < 0 ||
435 !pa_tagstruct_eof(t
)) {
436 pa_context_fail(c
, PA_ERR_PROTOCOL
);
440 /* Minimum supported version */
441 if (c
->version
< 8) {
442 pa_context_fail(c
, PA_ERR_VERSION
);
446 /* Starting with protocol version 13 the MSB of the version
447 tag reflects if shm is available for this connection or
449 if (c
->version
>= 13) {
450 shm_on_remote
= !!(c
->version
& 0x80000000U
);
451 c
->version
&= 0x7FFFFFFFU
;
454 pa_log_debug("Protocol version: remote %u, local %u", c
->version
, PA_PROTOCOL_VERSION
);
456 /* Enable shared memory support if possible */
458 if (c
->version
< 10 || (c
->version
>= 13 && !shm_on_remote
))
463 /* Only enable SHM if both sides are owned by the same
464 * user. This is a security measure because otherwise
465 * data private to the user might leak. */
468 const pa_creds
*creds
;
469 if (!(creds
= pa_pdispatch_creds(pd
)) || getuid() != creds
->uid
)
474 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c
->do_shm
));
475 pa_pstream_enable_shm(c
->pstream
, c
->do_shm
);
477 reply
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
479 if (c
->version
>= 13) {
480 pa_init_proplist(c
->proplist
);
481 pa_tagstruct_put_proplist(reply
, c
->proplist
);
483 pa_tagstruct_puts(reply
, pa_proplist_gets(c
->proplist
, PA_PROP_APPLICATION_NAME
));
485 pa_pstream_send_tagstruct(c
->pstream
, reply
);
486 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
488 pa_context_set_state(c
, PA_CONTEXT_SETTING_NAME
);
492 case PA_CONTEXT_SETTING_NAME
:
494 if ((c
->version
>= 13 && (pa_tagstruct_getu32(t
, &c
->client_index
) < 0 ||
495 c
->client_index
== PA_INVALID_INDEX
)) ||
496 !pa_tagstruct_eof(t
)) {
497 pa_context_fail(c
, PA_ERR_PROTOCOL
);
501 pa_context_set_state(c
, PA_CONTEXT_READY
);
505 pa_assert_not_reached();
512 static void setup_context(pa_context
*c
, pa_iochannel
*io
) {
521 pa_assert(!c
->pstream
);
522 c
->pstream
= pa_pstream_new(c
->mainloop
, io
, c
->mempool
);
524 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
525 pa_pstream_set_recieve_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
526 pa_pstream_set_recieve_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
528 pa_assert(!c
->pdispatch
);
529 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, c
->use_rtclock
, command_table
, PA_COMMAND_MAX
);
531 if (!c
->conf
->cookie_valid
)
532 pa_log_info(_("No cookie loaded. Attempting to connect without."));
534 t
= pa_tagstruct_command(c
, PA_COMMAND_AUTH
, &tag
);
537 pa_mempool_is_shared(c
->mempool
) &&
540 pa_log_debug("SHM possible: %s", pa_yes_no(c
->do_shm
));
542 /* Starting with protocol version 13 we use the MSB of the version
543 * tag for informing the other side if we could do SHM or not */
544 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
| (c
->do_shm
? 0x80000000U
: 0));
545 pa_tagstruct_put_arbitrary(t
, c
->conf
->cookie
, sizeof(c
->conf
->cookie
));
551 if (pa_iochannel_creds_supported(io
))
552 pa_iochannel_creds_enable(io
);
554 ucred
.uid
= getuid();
555 ucred
.gid
= getgid();
557 pa_pstream_send_tagstruct_with_creds(c
->pstream
, t
, &ucred
);
560 pa_pstream_send_tagstruct(c
->pstream
, t
);
563 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
565 pa_context_set_state(c
, PA_CONTEXT_AUTHORIZING
);
570 #ifdef ENABLE_LEGACY_RUNTIME_DIR
571 static char *get_old_legacy_runtime_dir(void) {
575 if (!pa_get_user_name(u
, sizeof(u
)))
578 p
= pa_sprintf_malloc("/tmp/pulse-%s", u
);
580 if (stat(p
, &st
) < 0) {
586 if (st
.st_uid
!= getuid()) {
595 static char *get_very_old_legacy_runtime_dir(void) {
599 if (!pa_get_home_dir(h
, sizeof(h
)))
602 p
= pa_sprintf_malloc("%s/.pulse", h
);
604 if (stat(p
, &st
) < 0) {
610 if (st
.st_uid
!= getuid()) {
620 static pa_strlist
*prepend_per_user(pa_strlist
*l
) {
623 #ifdef ENABLE_LEGACY_RUNTIME_DIR
626 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
627 if ((legacy_dir
= get_very_old_legacy_runtime_dir())) {
628 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
629 l
= pa_strlist_prepend(l
, p
);
631 pa_xfree(legacy_dir
);
634 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
635 if ((legacy_dir
= get_old_legacy_runtime_dir())) {
636 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
637 l
= pa_strlist_prepend(l
, p
);
639 pa_xfree(legacy_dir
);
643 /* The per-user instance */
644 if ((ufn
= pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET
))) {
645 l
= pa_strlist_prepend(l
, ufn
);
654 static int context_autospawn(pa_context
*c
) {
661 if (sigaction(SIGCHLD
, NULL
, &sa
) < 0) {
662 pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno
));
663 pa_context_fail(c
, PA_ERR_INTERNAL
);
667 if ((sa
.sa_flags
& SA_NOCLDWAIT
) || sa
.sa_handler
== SIG_IGN
) {
668 pa_log_debug("Process disabled waitpid(), cannot autospawn.");
669 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
673 pa_log_debug("Trying to autospawn...");
675 if (c
->spawn_api
.prefork
)
676 c
->spawn_api
.prefork();
678 if ((pid
= fork()) < 0) {
679 pa_log_error(_("fork(): %s"), pa_cstrerror(errno
));
680 pa_context_fail(c
, PA_ERR_INTERNAL
);
682 if (c
->spawn_api
.postfork
)
683 c
->spawn_api
.postfork();
689 const char *state
= NULL
;
690 const char * argv
[32];
693 if (c
->spawn_api
.atfork
)
694 c
->spawn_api
.atfork();
696 /* We leave most of the cleaning up of the process environment
697 * to the executable. We only clean up the file descriptors to
698 * make sure the executable can actually be loaded
703 argv
[n
++] = c
->conf
->daemon_binary
;
704 argv
[n
++] = "--start";
706 while (n
< PA_ELEMENTSOF(argv
)-1) {
709 if (!(a
= pa_split_spaces(c
->conf
->extra_arguments
, &state
)))
716 pa_assert(n
<= PA_ELEMENTSOF(argv
));
718 execv(argv
[0], (char * const *) argv
);
724 if (c
->spawn_api
.postfork
)
725 c
->spawn_api
.postfork();
728 r
= waitpid(pid
, &status
, 0);
729 } while (r
< 0 && errno
== EINTR
);
733 if (errno
!= ESRCH
) {
734 pa_log(_("waitpid(): %s"), pa_cstrerror(errno
));
735 pa_context_fail(c
, PA_ERR_INTERNAL
);
739 /* hmm, something already reaped our child, so we assume
740 * startup worked, even if we cannot know */
742 } else if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
743 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
758 #endif /* OS_IS_WIN32 */
760 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
);
763 static void track_pulseaudio_on_dbus(pa_context
*c
, DBusBusType type
, pa_dbus_wrap_connection
**conn
) {
769 dbus_error_init(&error
);
771 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, c
->use_rtclock
, type
, &error
)) || dbus_error_is_set(&error
)) {
772 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
776 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
777 pa_log_warn("Failed to add filter function");
780 c
->filter_added
= TRUE
;
782 if (pa_dbus_add_matches(
783 pa_dbus_wrap_connection_get(*conn
), &error
,
784 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL
) < 0) {
786 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
794 pa_dbus_wrap_connection_free(*conn
);
798 dbus_error_free(&error
);
802 static int try_next_connection(pa_context
*c
) {
807 pa_assert(!c
->client
);
813 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
818 if (c
->do_autospawn
) {
820 if ((r
= context_autospawn(c
)) < 0)
823 /* Autospawn only once */
824 c
->do_autospawn
= FALSE
;
826 /* Connect only to per-user sockets this time */
827 c
->server_list
= prepend_per_user(c
->server_list
);
829 /* Retry connection */
835 if (c
->no_fail
&& !c
->server_specified
) {
837 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
839 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
842 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
847 pa_log_debug("Trying to connect to %s...", u
);
850 c
->server
= pa_xstrdup(u
);
852 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, c
->use_rtclock
, u
, PA_NATIVE_DEFAULT_PORT
)))
855 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
856 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
868 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
869 pa_context
*c
= userdata
;
870 int saved_errno
= errno
;
874 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
878 pa_socket_client_unref(client
);
882 /* Try the next item in the list */
883 if (saved_errno
== ECONNREFUSED
||
884 saved_errno
== ETIMEDOUT
||
885 saved_errno
== EHOSTUNREACH
) {
886 try_next_connection(c
);
890 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
894 setup_context(c
, io
);
901 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
902 pa_context
*c
= userdata
;
903 pa_bool_t is_session
;
909 if (c
->state
!= PA_CONTEXT_CONNECTING
)
915 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
917 is_session
= c
->session_bus
&& bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
918 pa_log_debug("Rock!! PulseAudio might be back on %s bus", is_session
? "session" : "system");
921 /* The user instance via PF_LOCAL */
922 c
->server_list
= prepend_per_user(c
->server_list
);
924 /* The system wide instance via PF_LOCAL */
925 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
928 try_next_connection(c
);
931 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
935 int pa_context_connect(
938 pa_context_flags_t flags
,
939 const pa_spawn_api
*api
) {
944 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
946 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
947 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
948 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
949 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
952 c
->conf
->autospawn
= FALSE
;
954 server
= c
->conf
->default_server
;
958 c
->no_fail
= !!(flags
& PA_CONTEXT_NOFAIL
);
959 c
->server_specified
= !!server
;
960 pa_assert(!c
->server_list
);
963 if (!(c
->server_list
= pa_strlist_parse(server
))) {
964 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
971 /* Prepend in reverse order */
973 /* Follow the X display */
974 if (c
->conf
->auto_connect_display
) {
975 if ((d
= getenv("DISPLAY"))) {
976 d
= pa_xstrndup(d
, strcspn(d
, ":"));
979 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
985 /* Add TCP/IP on the localhost */
986 if (c
->conf
->auto_connect_localhost
) {
987 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
988 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
991 /* The system wide instance via PF_LOCAL */
992 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
994 /* The user instance via PF_LOCAL */
995 c
->server_list
= prepend_per_user(c
->server_list
);
998 /* Set up autospawning */
999 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
1003 pa_log_debug("Not doing autospawn since we are root.");
1005 c
->do_autospawn
= TRUE
;
1008 c
->spawn_api
= *api
;
1013 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
1014 r
= try_next_connection(c
);
1017 pa_context_unref(c
);
1022 void pa_context_disconnect(pa_context
*c
) {
1024 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1026 if (pa_detect_fork())
1029 if (PA_CONTEXT_IS_GOOD(c
->state
))
1030 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
1033 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
1035 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1040 int pa_context_errno(pa_context
*c
) {
1043 return PA_ERR_INVALID
;
1045 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1050 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1052 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1054 if (pa_detect_fork())
1057 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1060 c
->state_callback
= cb
;
1061 c
->state_userdata
= userdata
;
1064 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1066 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1068 if (pa_detect_fork())
1071 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1074 c
->event_callback
= cb
;
1075 c
->event_userdata
= userdata
;
1078 int pa_context_is_pending(pa_context
*c
) {
1080 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1082 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1083 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1085 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1086 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1090 static void set_dispatch_callbacks(pa_operation
*o
);
1092 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1093 set_dispatch_callbacks(userdata
);
1096 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1097 set_dispatch_callbacks(userdata
);
1100 static void set_dispatch_callbacks(pa_operation
*o
) {
1104 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1105 pa_assert(o
->context
);
1106 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1107 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1109 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1110 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1112 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1113 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1117 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1118 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1124 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1125 cb(o
->context
, o
->userdata
);
1128 pa_operation_done(o
);
1129 pa_operation_unref(o
);
1133 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1137 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1139 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1140 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1141 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1143 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1144 set_dispatch_callbacks(pa_operation_ref(o
));
1149 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1150 pa_operation
*o
= userdata
;
1155 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1160 if (command
!= PA_COMMAND_REPLY
) {
1161 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1165 } else if (!pa_tagstruct_eof(t
)) {
1166 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1171 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1172 cb(o
->context
, success
, o
->userdata
);
1176 pa_operation_done(o
);
1177 pa_operation_unref(o
);
1180 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
) {
1186 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1188 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1189 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1191 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1193 t
= pa_tagstruct_command(c
, command
, &tag
);
1194 pa_pstream_send_tagstruct(c
->pstream
, t
);
1195 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1200 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1202 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1204 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1207 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1213 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1215 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1216 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1218 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1219 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1220 pa_tagstruct_puts(t
, name
);
1221 pa_pstream_send_tagstruct(c
->pstream
, t
);
1222 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
);
1227 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1233 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1235 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1236 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1238 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1239 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1240 pa_tagstruct_puts(t
, name
);
1241 pa_pstream_send_tagstruct(c
->pstream
, t
);
1242 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
);
1247 int pa_context_is_local(pa_context
*c
) {
1249 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1251 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1252 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1254 return !!c
->is_local
;
1257 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1261 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1264 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1265 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1267 if (c
->version
>= 13) {
1268 pa_proplist
*p
= pa_proplist_new();
1270 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1271 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1272 pa_proplist_free(p
);
1277 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1278 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1279 pa_tagstruct_puts(t
, name
);
1280 pa_pstream_send_tagstruct(c
->pstream
, t
);
1281 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
);
1287 const char* pa_get_library_version(void) {
1288 return PACKAGE_VERSION
;
1291 const char* pa_context_get_server(pa_context
*c
) {
1293 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1295 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1296 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1298 if (*c
->server
== '{') {
1299 char *e
= strchr(c
->server
+1, '}');
1300 return e
? e
+1 : c
->server
;
1306 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1307 return PA_PROTOCOL_VERSION
;
1310 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1312 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1314 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1315 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1320 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1326 t
= pa_tagstruct_new(NULL
, 0);
1327 pa_tagstruct_putu32(t
, command
);
1328 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1333 uint32_t pa_context_get_index(pa_context
*c
) {
1335 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1337 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1338 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1339 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1341 return c
->client_index
;
1344 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
) {
1350 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1352 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1353 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1354 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1355 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1357 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1359 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1360 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1361 pa_tagstruct_put_proplist(t
, p
);
1363 pa_pstream_send_tagstruct(c
->pstream
, t
);
1364 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
);
1366 /* Please note that we don't update c->proplist here, because we
1367 * don't export that field */
1372 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1376 const char * const *k
;
1379 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1381 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1382 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1383 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1384 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1386 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1388 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1390 for (k
= keys
; *k
; k
++)
1391 pa_tagstruct_puts(t
, *k
);
1393 pa_tagstruct_puts(t
, NULL
);
1395 pa_pstream_send_tagstruct(c
->pstream
, t
);
1396 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
);
1398 /* Please note that we don't update c->proplist here, because we
1399 * don't export that field */
1404 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1405 pa_context
*c
= userdata
;
1410 pa_assert(command
== PA_COMMAND_EXTENSION
);
1413 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1417 if (c
->version
< 15) {
1418 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1422 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1423 pa_tagstruct_gets(t
, &name
) < 0) {
1424 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1428 if (!strcmp(name
, "module-stream-restore"))
1429 pa_ext_stream_restore_command(c
, tag
, t
);
1430 else if (!strcmp(name
, "module-device-manager"))
1431 pa_ext_device_manager_command(c
, tag
, t
);
1433 pa_log(_("Received message for unknown extension '%s'"), name
);
1436 pa_context_unref(c
);
1440 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1441 pa_context
*c
= userdata
;
1442 pa_proplist
*pl
= NULL
;
1446 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1449 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1453 if (c
->version
< 15) {
1454 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1458 pl
= pa_proplist_new();
1460 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1461 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1462 !pa_tagstruct_eof(t
) || !event
) {
1463 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1467 if (c
->event_callback
)
1468 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1471 pa_context_unref(c
);
1474 pa_proplist_free(pl
);
1477 pa_time_event
* pa_context_rttime_new(pa_context
*c
, pa_usec_t usec
, pa_time_event_cb_t cb
, void *userdata
) {
1481 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1482 pa_assert(c
->mainloop
);
1484 if (usec
== PA_USEC_INVALID
)
1485 return c
->mainloop
->time_new(c
->mainloop
, NULL
, cb
, userdata
);
1487 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1489 return c
->mainloop
->time_new(c
->mainloop
, &tv
, cb
, userdata
);
1492 void pa_context_rttime_restart(pa_context
*c
, pa_time_event
*e
, pa_usec_t usec
) {
1496 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1497 pa_assert(c
->mainloop
);
1500 if (usec
== PA_USEC_INVALID
)
1501 c
->mainloop
->time_restart(e
, NULL
);
1503 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1504 c
->mainloop
->time_restart(e
, &tv
);
1508 size_t pa_context_get_tile_size(pa_context
*c
, const pa_sample_spec
*ss
) {
1512 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1514 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, (size_t) -1);
1515 PA_CHECK_VALIDITY_RETURN_ANY(c
, !ss
|| pa_sample_spec_valid(ss
), PA_ERR_INVALID
, (size_t) -1);
1517 fs
= ss
? pa_frame_size(ss
) : 1;
1518 mbs
= PA_ROUND_DOWN(pa_mempool_block_size_max(c
->mempool
), fs
);
1519 return PA_MAX(mbs
, fs
);