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
);
764 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, c
->use_rtclock
, type
, &error
)) || dbus_error_is_set(&error
)) {
765 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
769 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
770 pa_log_warn("Failed to add filter function");
774 if (pa_dbus_add_matches(
775 pa_dbus_wrap_connection_get(*conn
), &error
,
776 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL
) < 0)
777 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
780 dbus_error_free(&error
);
784 static int try_next_connection(pa_context
*c
) {
789 pa_assert(!c
->client
);
795 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
800 if (c
->do_autospawn
) {
802 if ((r
= context_autospawn(c
)) < 0)
805 /* Autospawn only once */
806 c
->do_autospawn
= FALSE
;
808 /* Connect only to per-user sockets this time */
809 c
->server_list
= prepend_per_user(c
->server_list
);
811 /* Retry connection */
817 if (c
->no_fail
&& !c
->server_specified
) {
819 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
821 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
824 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
829 pa_log_debug("Trying to connect to %s...", u
);
832 c
->server
= pa_xstrdup(u
);
834 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, c
->use_rtclock
, u
, PA_NATIVE_DEFAULT_PORT
)))
837 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
838 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
850 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
851 pa_context
*c
= userdata
;
852 int saved_errno
= errno
;
856 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
860 pa_socket_client_unref(client
);
864 /* Try the item in the list */
865 if (saved_errno
== ECONNREFUSED
||
866 saved_errno
== ETIMEDOUT
||
867 saved_errno
== EHOSTUNREACH
) {
868 try_next_connection(c
);
872 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
876 setup_context(c
, io
);
883 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
884 pa_context
*c
= userdata
;
885 pa_bool_t is_session
;
891 if (c
->state
!= PA_CONTEXT_CONNECTING
)
897 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
899 is_session
= c
->session_bus
&& bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
900 pa_log_debug("Rock!! PulseAudio is back on %s bus", is_session
? "session" : "system");
903 /* The user instance via PF_LOCAL */
904 c
->server_list
= prepend_per_user(c
->server_list
);
906 /* The system wide instance via PF_LOCAL */
907 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
910 try_next_connection(c
);
913 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
917 int pa_context_connect(
920 pa_context_flags_t flags
,
921 const pa_spawn_api
*api
) {
926 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
928 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
929 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
930 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
931 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
934 c
->conf
->autospawn
= FALSE
;
936 server
= c
->conf
->default_server
;
940 c
->no_fail
= flags
& PA_CONTEXT_NOFAIL
;
941 c
->server_specified
= !!server
;
942 pa_assert(!c
->server_list
);
945 if (!(c
->server_list
= pa_strlist_parse(server
))) {
946 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
953 /* Prepend in reverse order */
955 /* Follow the X display */
956 if ((d
= getenv("DISPLAY"))) {
959 if ((e
= strchr(d
, ':')))
963 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
968 /* Add TCP/IP on the localhost */
969 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
970 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
972 /* The system wide instance via PF_LOCAL */
973 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
975 /* The user instance via PF_LOCAL */
976 c
->server_list
= prepend_per_user(c
->server_list
);
979 /* Set up autospawning */
980 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
983 pa_log_debug("Not doing autospawn since we are root.");
985 c
->do_autospawn
= TRUE
;
992 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
993 r
= try_next_connection(c
);
1001 void pa_context_disconnect(pa_context
*c
) {
1003 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1005 if (pa_detect_fork())
1008 if (PA_CONTEXT_IS_GOOD(c
->state
))
1009 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
1012 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
1014 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1019 int pa_context_errno(pa_context
*c
) {
1021 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1026 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1028 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1030 if (pa_detect_fork())
1033 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1036 c
->state_callback
= cb
;
1037 c
->state_userdata
= userdata
;
1040 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1042 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1044 if (pa_detect_fork())
1047 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1050 c
->event_callback
= cb
;
1051 c
->event_userdata
= userdata
;
1054 int pa_context_is_pending(pa_context
*c
) {
1056 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1058 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1059 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1061 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1062 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1066 static void set_dispatch_callbacks(pa_operation
*o
);
1068 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1069 set_dispatch_callbacks(userdata
);
1072 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1073 set_dispatch_callbacks(userdata
);
1076 static void set_dispatch_callbacks(pa_operation
*o
) {
1080 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1081 pa_assert(o
->context
);
1082 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1083 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1085 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1086 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1088 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1089 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1093 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1094 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1100 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1101 cb(o
->context
, o
->userdata
);
1104 pa_operation_done(o
);
1105 pa_operation_unref(o
);
1109 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1113 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1115 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1116 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1117 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1119 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1120 set_dispatch_callbacks(pa_operation_ref(o
));
1125 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1126 pa_operation
*o
= userdata
;
1131 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1136 if (command
!= PA_COMMAND_REPLY
) {
1137 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1141 } else if (!pa_tagstruct_eof(t
)) {
1142 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1147 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1148 cb(o
->context
, success
, o
->userdata
);
1152 pa_operation_done(o
);
1153 pa_operation_unref(o
);
1156 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
) {
1162 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1164 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1165 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1167 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1169 t
= pa_tagstruct_command(c
, command
, &tag
);
1170 pa_pstream_send_tagstruct(c
->pstream
, t
);
1171 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1176 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1178 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1180 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1183 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1189 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1191 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1192 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1194 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1195 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1196 pa_tagstruct_puts(t
, name
);
1197 pa_pstream_send_tagstruct(c
->pstream
, t
);
1198 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
);
1203 pa_operation
* pa_context_set_default_source(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_SOURCE
, &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 int pa_context_is_local(pa_context
*c
) {
1225 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1227 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1228 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1230 return !!c
->is_local
;
1233 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1237 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1240 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1241 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1243 if (c
->version
>= 13) {
1244 pa_proplist
*p
= pa_proplist_new();
1246 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1247 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1248 pa_proplist_free(p
);
1253 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1254 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1255 pa_tagstruct_puts(t
, name
);
1256 pa_pstream_send_tagstruct(c
->pstream
, t
);
1257 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
);
1263 const char* pa_get_library_version(void) {
1264 return PACKAGE_VERSION
;
1267 const char* pa_context_get_server(pa_context
*c
) {
1269 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1271 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1272 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1274 if (*c
->server
== '{') {
1275 char *e
= strchr(c
->server
+1, '}');
1276 return e
? e
+1 : c
->server
;
1282 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1283 return PA_PROTOCOL_VERSION
;
1286 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1288 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1290 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1291 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1296 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1302 t
= pa_tagstruct_new(NULL
, 0);
1303 pa_tagstruct_putu32(t
, command
);
1304 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1309 uint32_t pa_context_get_index(pa_context
*c
) {
1311 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1313 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1314 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1315 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1317 return c
->client_index
;
1320 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
) {
1326 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1328 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1329 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1330 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1331 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1333 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1335 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1336 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1337 pa_tagstruct_put_proplist(t
, p
);
1339 pa_pstream_send_tagstruct(c
->pstream
, t
);
1340 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
);
1342 /* Please note that we don't update c->proplist here, because we
1343 * don't export that field */
1348 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1352 const char * const *k
;
1355 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1357 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1358 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1359 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1360 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1362 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1364 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1366 for (k
= keys
; *k
; k
++)
1367 pa_tagstruct_puts(t
, *k
);
1369 pa_tagstruct_puts(t
, NULL
);
1371 pa_pstream_send_tagstruct(c
->pstream
, t
);
1372 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
);
1374 /* Please note that we don't update c->proplist here, because we
1375 * don't export that field */
1380 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1381 pa_context
*c
= userdata
;
1386 pa_assert(command
== PA_COMMAND_EXTENSION
);
1389 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1393 if (c
->version
< 15) {
1394 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1398 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1399 pa_tagstruct_gets(t
, &name
) < 0) {
1400 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1404 if (!strcmp(name
, "module-stream-restore"))
1405 pa_ext_stream_restore_command(c
, tag
, t
);
1407 pa_log(_("Received message for unknown extension '%s'"), name
);
1410 pa_context_unref(c
);
1414 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1415 pa_context
*c
= userdata
;
1416 pa_proplist
*pl
= NULL
;
1420 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1423 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1427 if (c
->version
< 15) {
1428 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1432 pl
= pa_proplist_new();
1434 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1435 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1436 !pa_tagstruct_eof(t
) || !event
) {
1437 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1441 if (c
->event_callback
)
1442 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1445 pa_context_unref(c
);
1448 pa_proplist_free(pl
);
1451 pa_time_event
* pa_context_rttime_new(pa_context
*c
, pa_usec_t usec
, pa_time_event_cb_t cb
, void *userdata
) {
1455 pa_assert(c
->mainloop
);
1457 if (usec
== PA_USEC_INVALID
)
1458 return c
->mainloop
->time_new(c
->mainloop
, NULL
, cb
, userdata
);
1460 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1462 return c
->mainloop
->time_new(c
->mainloop
, &tv
, cb
, userdata
);
1465 void pa_context_rttime_restart(pa_context
*c
, pa_time_event
*e
, pa_usec_t usec
) {
1469 pa_assert(c
->mainloop
);
1471 if (usec
== PA_USEC_INVALID
)
1472 c
->mainloop
->time_restart(e
, NULL
);
1474 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1475 c
->mainloop
->time_restart(e
, &tv
);