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/dynarray.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_stream_restore
.callback
= NULL
;
132 c
->ext_stream_restore
.userdata
= NULL
;
135 pa_context
*pa_context_new_with_proplist(pa_mainloop_api
*mainloop
, const char *name
, pa_proplist
*p
) {
140 if (pa_detect_fork())
145 c
= pa_xnew(pa_context
, 1);
148 c
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
151 pa_proplist_sets(c
->proplist
, PA_PROP_APPLICATION_NAME
, name
);
154 c
->system_bus
= c
->session_bus
= NULL
;
156 c
->mainloop
= mainloop
;
160 c
->playback_streams
= pa_dynarray_new();
161 c
->record_streams
= pa_dynarray_new();
162 c
->client_index
= PA_INVALID_INDEX
;
163 c
->use_rtclock
= pa_mainloop_is_our_api(mainloop
);
165 PA_LLIST_HEAD_INIT(pa_stream
, c
->streams
);
166 PA_LLIST_HEAD_INIT(pa_operation
, c
->operations
);
169 c
->state
= PA_CONTEXT_UNCONNECTED
;
176 c
->server_list
= NULL
;
181 c
->server_specified
= FALSE
;
183 c
->do_autospawn
= FALSE
;
184 memset(&c
->spawn_api
, 0, sizeof(c
->spawn_api
));
188 pa_check_signal_is_blocked(SIGPIPE
);
192 c
->conf
= pa_client_conf_new();
193 pa_client_conf_load(c
->conf
, NULL
);
195 pa_client_conf_from_x11(c
->conf
, NULL
);
197 pa_client_conf_env(c
->conf
);
199 if (!(c
->mempool
= pa_mempool_new(!c
->conf
->disable_shm
, c
->conf
->shm_size
))) {
201 if (!c
->conf
->disable_shm
)
202 c
->mempool
= pa_mempool_new(FALSE
, c
->conf
->shm_size
);
213 static void context_unlink(pa_context
*c
) {
218 s
= c
->streams
? pa_stream_ref(c
->streams
) : NULL
;
220 pa_stream
*n
= s
->next
? pa_stream_ref(s
->next
) : NULL
;
221 pa_stream_set_state(s
, c
->state
== PA_CONTEXT_FAILED
? PA_STREAM_FAILED
: PA_STREAM_TERMINATED
);
226 while (c
->operations
)
227 pa_operation_cancel(c
->operations
);
230 pa_pdispatch_unref(c
->pdispatch
);
235 pa_pstream_unlink(c
->pstream
);
236 pa_pstream_unref(c
->pstream
);
241 pa_socket_client_unref(c
->client
);
248 static void context_free(pa_context
*c
) {
255 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->system_bus
), filter_cb
, c
);
256 pa_dbus_wrap_connection_free(c
->system_bus
);
259 if (c
->session_bus
) {
260 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->session_bus
), filter_cb
, c
);
261 pa_dbus_wrap_connection_free(c
->session_bus
);
265 if (c
->record_streams
)
266 pa_dynarray_free(c
->record_streams
, NULL
, NULL
);
267 if (c
->playback_streams
)
268 pa_dynarray_free(c
->playback_streams
, NULL
, NULL
);
271 pa_mempool_free(c
->mempool
);
274 pa_client_conf_free(c
->conf
);
276 pa_strlist_free(c
->server_list
);
279 pa_proplist_free(c
->proplist
);
285 pa_context
* pa_context_ref(pa_context
*c
) {
287 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
293 void pa_context_unref(pa_context
*c
) {
295 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
297 if (PA_REFCNT_DEC(c
) <= 0)
301 void pa_context_set_state(pa_context
*c
, pa_context_state_t st
) {
303 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
312 if (c
->state_callback
)
313 c
->state_callback(c
, c
->state_userdata
);
315 if (st
== PA_CONTEXT_FAILED
|| st
== PA_CONTEXT_TERMINATED
)
321 int pa_context_set_error(pa_context
*c
, int error
) {
322 pa_assert(error
>= 0);
323 pa_assert(error
< PA_ERR_MAX
);
331 void pa_context_fail(pa_context
*c
, int error
) {
333 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
335 pa_context_set_error(c
, error
);
336 pa_context_set_state(c
, PA_CONTEXT_FAILED
);
339 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
340 pa_context
*c
= userdata
;
345 pa_context_fail(c
, PA_ERR_CONNECTIONTERMINATED
);
348 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
349 pa_context
*c
= userdata
;
357 if (pa_pdispatch_run(c
->pdispatch
, packet
, creds
, c
) < 0)
358 pa_context_fail(c
, PA_ERR_PROTOCOL
);
363 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
) {
364 pa_context
*c
= userdata
;
369 pa_assert(chunk
->length
> 0);
371 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
375 if ((s
= pa_dynarray_get(c
->record_streams
, channel
))) {
377 if (chunk
->memblock
) {
378 pa_memblockq_seek(s
->record_memblockq
, offset
, seek
, TRUE
);
379 pa_memblockq_push_align(s
->record_memblockq
, chunk
);
381 pa_memblockq_seek(s
->record_memblockq
, offset
+chunk
->length
, seek
, TRUE
);
383 if (s
->read_callback
) {
386 if ((l
= pa_memblockq_get_length(s
->record_memblockq
)) > 0)
387 s
->read_callback(s
, l
, s
->read_userdata
);
394 int pa_context_handle_error(pa_context
*c
, uint32_t command
, pa_tagstruct
*t
, pa_bool_t fail
) {
397 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
399 if (command
== PA_COMMAND_ERROR
) {
402 if (pa_tagstruct_getu32(t
, &err
) < 0 ||
403 !pa_tagstruct_eof(t
)) {
404 pa_context_fail(c
, PA_ERR_PROTOCOL
);
408 } else if (command
== PA_COMMAND_TIMEOUT
)
409 err
= PA_ERR_TIMEOUT
;
411 pa_context_fail(c
, PA_ERR_PROTOCOL
);
416 pa_context_fail(c
, PA_ERR_PROTOCOL
);
420 if (err
>= PA_ERR_MAX
)
421 err
= PA_ERR_UNKNOWN
;
424 pa_context_fail(c
, (int) err
);
428 pa_context_set_error(c
, (int) err
);
433 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
434 pa_context
*c
= userdata
;
438 pa_assert(c
->state
== PA_CONTEXT_AUTHORIZING
|| c
->state
== PA_CONTEXT_SETTING_NAME
);
442 if (command
!= PA_COMMAND_REPLY
) {
443 pa_context_handle_error(c
, command
, t
, TRUE
);
448 case PA_CONTEXT_AUTHORIZING
: {
450 pa_bool_t shm_on_remote
= FALSE
;
452 if (pa_tagstruct_getu32(t
, &c
->version
) < 0 ||
453 !pa_tagstruct_eof(t
)) {
454 pa_context_fail(c
, PA_ERR_PROTOCOL
);
458 /* Minimum supported version */
459 if (c
->version
< 8) {
460 pa_context_fail(c
, PA_ERR_VERSION
);
464 /* Starting with protocol version 13 the MSB of the version
465 tag reflects if shm is available for this connection or
467 if (c
->version
>= 13) {
468 shm_on_remote
= !!(c
->version
& 0x80000000U
);
469 c
->version
&= 0x7FFFFFFFU
;
472 pa_log_debug("Protocol version: remote %u, local %u", c
->version
, PA_PROTOCOL_VERSION
);
474 /* Enable shared memory support if possible */
476 if (c
->version
< 10 || (c
->version
>= 13 && !shm_on_remote
))
481 /* Only enable SHM if both sides are owned by the same
482 * user. This is a security measure because otherwise
483 * data private to the user might leak. */
486 const pa_creds
*creds
;
487 if (!(creds
= pa_pdispatch_creds(pd
)) || getuid() != creds
->uid
)
492 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c
->do_shm
));
493 pa_pstream_enable_shm(c
->pstream
, c
->do_shm
);
495 reply
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
497 if (c
->version
>= 13) {
498 pa_init_proplist(c
->proplist
);
499 pa_tagstruct_put_proplist(reply
, c
->proplist
);
501 pa_tagstruct_puts(reply
, pa_proplist_gets(c
->proplist
, PA_PROP_APPLICATION_NAME
));
503 pa_pstream_send_tagstruct(c
->pstream
, reply
);
504 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
506 pa_context_set_state(c
, PA_CONTEXT_SETTING_NAME
);
510 case PA_CONTEXT_SETTING_NAME
:
512 if ((c
->version
>= 13 && (pa_tagstruct_getu32(t
, &c
->client_index
) < 0 ||
513 c
->client_index
== PA_INVALID_INDEX
)) ||
514 !pa_tagstruct_eof(t
)) {
515 pa_context_fail(c
, PA_ERR_PROTOCOL
);
519 pa_context_set_state(c
, PA_CONTEXT_READY
);
523 pa_assert_not_reached();
530 static void setup_context(pa_context
*c
, pa_iochannel
*io
) {
539 pa_assert(!c
->pstream
);
540 c
->pstream
= pa_pstream_new(c
->mainloop
, io
, c
->mempool
);
542 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
543 pa_pstream_set_recieve_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
544 pa_pstream_set_recieve_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
546 pa_assert(!c
->pdispatch
);
547 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, c
->use_rtclock
, command_table
, PA_COMMAND_MAX
);
549 if (!c
->conf
->cookie_valid
)
550 pa_log_info(_("No cookie loaded. Attempting to connect without."));
552 t
= pa_tagstruct_command(c
, PA_COMMAND_AUTH
, &tag
);
555 pa_mempool_is_shared(c
->mempool
) &&
558 pa_log_debug("SHM possible: %s", pa_yes_no(c
->do_shm
));
560 /* Starting with protocol version 13 we use the MSB of the version
561 * tag for informing the other side if we could do SHM or not */
562 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
| (c
->do_shm
? 0x80000000U
: 0));
563 pa_tagstruct_put_arbitrary(t
, c
->conf
->cookie
, sizeof(c
->conf
->cookie
));
569 if (pa_iochannel_creds_supported(io
))
570 pa_iochannel_creds_enable(io
);
572 ucred
.uid
= getuid();
573 ucred
.gid
= getgid();
575 pa_pstream_send_tagstruct_with_creds(c
->pstream
, t
, &ucred
);
578 pa_pstream_send_tagstruct(c
->pstream
, t
);
581 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
583 pa_context_set_state(c
, PA_CONTEXT_AUTHORIZING
);
588 #ifdef ENABLE_LEGACY_RUNTIME_DIR
589 static char *get_old_legacy_runtime_dir(void) {
593 if (!pa_get_user_name(u
, sizeof(u
)))
596 p
= pa_sprintf_malloc("/tmp/pulse-%s", u
);
598 if (stat(p
, &st
) < 0) {
603 if (st
.st_uid
!= getuid()) {
611 static char *get_very_old_legacy_runtime_dir(void) {
615 if (!pa_get_home_dir(h
, sizeof(h
)))
618 p
= pa_sprintf_malloc("%s/.pulse", h
);
620 if (stat(p
, &st
) < 0) {
625 if (st
.st_uid
!= getuid()) {
634 static pa_strlist
*prepend_per_user(pa_strlist
*l
) {
637 #ifdef ENABLE_LEGACY_RUNTIME_DIR
638 static char *legacy_dir
;
640 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
641 if ((legacy_dir
= get_very_old_legacy_runtime_dir())) {
642 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
643 l
= pa_strlist_prepend(l
, p
);
645 pa_xfree(legacy_dir
);
648 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
649 if ((legacy_dir
= get_old_legacy_runtime_dir())) {
650 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
651 l
= pa_strlist_prepend(l
, p
);
653 pa_xfree(legacy_dir
);
657 /* The per-user instance */
658 if ((ufn
= pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET
))) {
659 l
= pa_strlist_prepend(l
, ufn
);
668 static int context_autospawn(pa_context
*c
) {
672 pa_log_debug("Trying to autospawn...");
676 if (c
->spawn_api
.prefork
)
677 c
->spawn_api
.prefork();
679 if ((pid
= fork()) < 0) {
680 pa_log_error(_("fork(): %s"), pa_cstrerror(errno
));
681 pa_context_fail(c
, PA_ERR_INTERNAL
);
683 if (c
->spawn_api
.postfork
)
684 c
->spawn_api
.postfork();
690 const char *state
= NULL
;
692 const char * argv
[MAX_ARGS
+1];
695 if (c
->spawn_api
.atfork
)
696 c
->spawn_api
.atfork();
704 argv
[n
++] = c
->conf
->daemon_binary
;
705 argv
[n
++] = "--start";
707 while (n
< MAX_ARGS
) {
710 if (!(a
= pa_split_spaces(c
->conf
->extra_arguments
, &state
)))
718 execv(argv
[0], (char * const *) argv
);
725 if (c
->spawn_api
.postfork
)
726 c
->spawn_api
.postfork();
729 r
= waitpid(pid
, &status
, 0);
730 } while (r
< 0 && errno
== EINTR
);
733 pa_log(_("waitpid(): %s"), pa_cstrerror(errno
));
734 pa_context_fail(c
, PA_ERR_INTERNAL
);
736 } else if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
737 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
752 #endif /* OS_IS_WIN32 */
754 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
);
757 static void track_pulseaudio_on_dbus(pa_context
*c
, DBusBusType type
, pa_dbus_wrap_connection
**conn
) {
763 dbus_error_init(&error
);
765 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, c
->use_rtclock
, type
, &error
)) || dbus_error_is_set(&error
)) {
766 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
770 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
771 pa_log_warn("Failed to add filter function");
775 if (pa_dbus_add_matches(
776 pa_dbus_wrap_connection_get(*conn
), &error
,
777 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL
) < 0) {
779 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
787 pa_dbus_wrap_connection_free(*conn
);
791 dbus_error_free(&error
);
795 static int try_next_connection(pa_context
*c
) {
800 pa_assert(!c
->client
);
806 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
811 if (c
->do_autospawn
) {
813 if ((r
= context_autospawn(c
)) < 0)
816 /* Autospawn only once */
817 c
->do_autospawn
= FALSE
;
819 /* Connect only to per-user sockets this time */
820 c
->server_list
= prepend_per_user(c
->server_list
);
822 /* Retry connection */
828 if (c
->no_fail
&& !c
->server_specified
) {
830 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
832 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
835 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
840 pa_log_debug("Trying to connect to %s...", u
);
843 c
->server
= pa_xstrdup(u
);
845 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, c
->use_rtclock
, u
, PA_NATIVE_DEFAULT_PORT
)))
848 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
849 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
861 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
862 pa_context
*c
= userdata
;
863 int saved_errno
= errno
;
867 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
871 pa_socket_client_unref(client
);
875 /* Try the next item in the list */
876 if (saved_errno
== ECONNREFUSED
||
877 saved_errno
== ETIMEDOUT
||
878 saved_errno
== EHOSTUNREACH
) {
879 try_next_connection(c
);
883 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
887 setup_context(c
, io
);
894 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
895 pa_context
*c
= userdata
;
896 pa_bool_t is_session
;
902 if (c
->state
!= PA_CONTEXT_CONNECTING
)
908 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
910 is_session
= c
->session_bus
&& bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
911 pa_log_debug("Rock!! PulseAudio might be back on %s bus", is_session
? "session" : "system");
914 /* The user instance via PF_LOCAL */
915 c
->server_list
= prepend_per_user(c
->server_list
);
917 /* The system wide instance via PF_LOCAL */
918 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
921 try_next_connection(c
);
924 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
928 int pa_context_connect(
931 pa_context_flags_t flags
,
932 const pa_spawn_api
*api
) {
937 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
939 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
940 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
941 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
942 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
945 c
->conf
->autospawn
= FALSE
;
947 server
= c
->conf
->default_server
;
951 c
->no_fail
= !!(flags
& PA_CONTEXT_NOFAIL
);
952 c
->server_specified
= !!server
;
953 pa_assert(!c
->server_list
);
956 if (!(c
->server_list
= pa_strlist_parse(server
))) {
957 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
964 /* Prepend in reverse order */
966 /* Follow the X display */
967 if ((d
= getenv("DISPLAY"))) {
968 d
= pa_xstrndup(d
, strcspn(d
, ":"));
971 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
976 /* Add TCP/IP on the localhost */
977 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
978 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
980 /* The system wide instance via PF_LOCAL */
981 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
983 /* The user instance via PF_LOCAL */
984 c
->server_list
= prepend_per_user(c
->server_list
);
987 /* Set up autospawning */
988 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
991 pa_log_debug("Not doing autospawn since we are root.");
993 c
->do_autospawn
= TRUE
;
1000 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
1001 r
= try_next_connection(c
);
1004 pa_context_unref(c
);
1009 void pa_context_disconnect(pa_context
*c
) {
1011 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1013 if (pa_detect_fork())
1016 if (PA_CONTEXT_IS_GOOD(c
->state
))
1017 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
1020 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
1022 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1027 int pa_context_errno(pa_context
*c
) {
1029 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1034 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1036 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1038 if (pa_detect_fork())
1041 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1044 c
->state_callback
= cb
;
1045 c
->state_userdata
= userdata
;
1048 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1050 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1052 if (pa_detect_fork())
1055 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1058 c
->event_callback
= cb
;
1059 c
->event_userdata
= userdata
;
1062 int pa_context_is_pending(pa_context
*c
) {
1064 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1066 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1067 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1069 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1070 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1074 static void set_dispatch_callbacks(pa_operation
*o
);
1076 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1077 set_dispatch_callbacks(userdata
);
1080 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1081 set_dispatch_callbacks(userdata
);
1084 static void set_dispatch_callbacks(pa_operation
*o
) {
1088 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1089 pa_assert(o
->context
);
1090 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1091 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1093 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1094 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1096 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1097 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1101 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1102 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1108 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1109 cb(o
->context
, o
->userdata
);
1112 pa_operation_done(o
);
1113 pa_operation_unref(o
);
1117 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1121 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1123 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1124 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1125 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1127 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1128 set_dispatch_callbacks(pa_operation_ref(o
));
1133 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1134 pa_operation
*o
= userdata
;
1139 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1144 if (command
!= PA_COMMAND_REPLY
) {
1145 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1149 } else if (!pa_tagstruct_eof(t
)) {
1150 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1155 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1156 cb(o
->context
, success
, o
->userdata
);
1160 pa_operation_done(o
);
1161 pa_operation_unref(o
);
1164 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
) {
1170 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1172 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1173 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1175 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1177 t
= pa_tagstruct_command(c
, command
, &tag
);
1178 pa_pstream_send_tagstruct(c
->pstream
, t
);
1179 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1184 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1186 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1188 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1191 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1197 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1199 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1200 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1202 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1203 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1204 pa_tagstruct_puts(t
, name
);
1205 pa_pstream_send_tagstruct(c
->pstream
, t
);
1206 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
);
1211 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1217 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1219 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1220 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1222 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1223 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1224 pa_tagstruct_puts(t
, name
);
1225 pa_pstream_send_tagstruct(c
->pstream
, t
);
1226 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
);
1231 int pa_context_is_local(pa_context
*c
) {
1233 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1235 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1236 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1238 return !!c
->is_local
;
1241 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1245 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1248 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1249 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1251 if (c
->version
>= 13) {
1252 pa_proplist
*p
= pa_proplist_new();
1254 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1255 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1256 pa_proplist_free(p
);
1261 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1262 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1263 pa_tagstruct_puts(t
, name
);
1264 pa_pstream_send_tagstruct(c
->pstream
, t
);
1265 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
);
1271 const char* pa_get_library_version(void) {
1272 return PACKAGE_VERSION
;
1275 const char* pa_context_get_server(pa_context
*c
) {
1277 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1279 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1280 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1282 if (*c
->server
== '{') {
1283 char *e
= strchr(c
->server
+1, '}');
1284 return e
? e
+1 : c
->server
;
1290 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1291 return PA_PROTOCOL_VERSION
;
1294 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1296 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1298 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1299 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1304 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1310 t
= pa_tagstruct_new(NULL
, 0);
1311 pa_tagstruct_putu32(t
, command
);
1312 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1317 uint32_t pa_context_get_index(pa_context
*c
) {
1319 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1321 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1322 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1323 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1325 return c
->client_index
;
1328 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
) {
1334 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1336 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1337 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1338 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1339 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1341 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1343 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1344 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1345 pa_tagstruct_put_proplist(t
, p
);
1347 pa_pstream_send_tagstruct(c
->pstream
, t
);
1348 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
);
1350 /* Please note that we don't update c->proplist here, because we
1351 * don't export that field */
1356 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1360 const char * const *k
;
1363 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1365 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1366 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1367 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1368 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1370 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1372 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1374 for (k
= keys
; *k
; k
++)
1375 pa_tagstruct_puts(t
, *k
);
1377 pa_tagstruct_puts(t
, NULL
);
1379 pa_pstream_send_tagstruct(c
->pstream
, t
);
1380 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
);
1382 /* Please note that we don't update c->proplist here, because we
1383 * don't export that field */
1388 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1389 pa_context
*c
= userdata
;
1394 pa_assert(command
== PA_COMMAND_EXTENSION
);
1397 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1401 if (c
->version
< 15) {
1402 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1406 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1407 pa_tagstruct_gets(t
, &name
) < 0) {
1408 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1412 if (!strcmp(name
, "module-stream-restore"))
1413 pa_ext_stream_restore_command(c
, tag
, t
);
1415 pa_log(_("Received message for unknown extension '%s'"), name
);
1418 pa_context_unref(c
);
1422 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1423 pa_context
*c
= userdata
;
1424 pa_proplist
*pl
= NULL
;
1428 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1431 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1435 if (c
->version
< 15) {
1436 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1440 pl
= pa_proplist_new();
1442 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1443 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1444 !pa_tagstruct_eof(t
) || !event
) {
1445 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1449 if (c
->event_callback
)
1450 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1453 pa_context_unref(c
);
1456 pa_proplist_free(pl
);
1459 pa_time_event
* pa_context_rttime_new(pa_context
*c
, pa_usec_t usec
, pa_time_event_cb_t cb
, void *userdata
) {
1463 pa_assert(c
->mainloop
);
1465 if (usec
== PA_USEC_INVALID
)
1466 return c
->mainloop
->time_new(c
->mainloop
, NULL
, cb
, userdata
);
1468 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1470 return c
->mainloop
->time_new(c
->mainloop
, &tv
, cb
, userdata
);
1473 void pa_context_rttime_restart(pa_context
*c
, pa_time_event
*e
, pa_usec_t usec
) {
1477 pa_assert(c
->mainloop
);
1479 if (usec
== PA_USEC_INVALID
)
1480 c
->mainloop
->time_restart(e
, NULL
);
1482 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1483 c
->mainloop
->time_restart(e
, &tv
);