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>
58 #include <pulsecore/winsock.h>
59 #include <pulsecore/core-error.h>
61 #include <pulsecore/native-common.h>
62 #include <pulsecore/pdispatch.h>
63 #include <pulsecore/pstream.h>
64 #include <pulsecore/dynarray.h>
65 #include <pulsecore/socket-client.h>
66 #include <pulsecore/pstream-util.h>
67 #include <pulsecore/core-util.h>
68 #include <pulsecore/log.h>
69 #include <pulsecore/socket-util.h>
70 #include <pulsecore/creds.h>
71 #include <pulsecore/macro.h>
72 #include <pulsecore/proplist-util.h>
76 #include "client-conf.h"
77 #include "fork-detect.h"
80 #include "client-conf-x11.h"
85 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
87 static const pa_pdispatch_cb_t command_table
[PA_COMMAND_MAX
] = {
88 [PA_COMMAND_REQUEST
] = pa_command_request
,
89 [PA_COMMAND_OVERFLOW
] = pa_command_overflow_or_underflow
,
90 [PA_COMMAND_UNDERFLOW
] = pa_command_overflow_or_underflow
,
91 [PA_COMMAND_PLAYBACK_STREAM_KILLED
] = pa_command_stream_killed
,
92 [PA_COMMAND_RECORD_STREAM_KILLED
] = pa_command_stream_killed
,
93 [PA_COMMAND_PLAYBACK_STREAM_MOVED
] = pa_command_stream_moved
,
94 [PA_COMMAND_RECORD_STREAM_MOVED
] = pa_command_stream_moved
,
95 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
] = pa_command_stream_suspended
,
96 [PA_COMMAND_RECORD_STREAM_SUSPENDED
] = pa_command_stream_suspended
,
97 [PA_COMMAND_STARTED
] = pa_command_stream_started
,
98 [PA_COMMAND_SUBSCRIBE_EVENT
] = pa_command_subscribe_event
,
99 [PA_COMMAND_EXTENSION
] = pa_command_extension
,
100 [PA_COMMAND_PLAYBACK_STREAM_EVENT
] = pa_command_stream_event
,
101 [PA_COMMAND_RECORD_STREAM_EVENT
] = pa_command_stream_event
,
102 [PA_COMMAND_CLIENT_EVENT
] = pa_command_client_event
,
103 [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
,
104 [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
106 static void context_free(pa_context
*c
);
107 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
);
109 pa_context
*pa_context_new(pa_mainloop_api
*mainloop
, const char *name
) {
110 return pa_context_new_with_proplist(mainloop
, name
, NULL
);
113 static void reset_callbacks(pa_context
*c
) {
116 c
->state_callback
= NULL
;
117 c
->state_userdata
= NULL
;
119 c
->subscribe_callback
= NULL
;
120 c
->subscribe_userdata
= NULL
;
122 c
->event_callback
= NULL
;
123 c
->event_userdata
= NULL
;
125 c
->ext_stream_restore
.callback
= NULL
;
126 c
->ext_stream_restore
.userdata
= NULL
;
129 pa_context
*pa_context_new_with_proplist(pa_mainloop_api
*mainloop
, const char *name
, pa_proplist
*p
) {
134 if (pa_detect_fork())
139 c
= pa_xnew(pa_context
, 1);
142 c
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
145 pa_proplist_sets(c
->proplist
, PA_PROP_APPLICATION_NAME
, name
);
148 c
->system_bus
= c
->session_bus
= NULL
;
149 c
->mainloop
= mainloop
;
153 c
->playback_streams
= pa_dynarray_new();
154 c
->record_streams
= pa_dynarray_new();
155 c
->client_index
= PA_INVALID_INDEX
;
157 PA_LLIST_HEAD_INIT(pa_stream
, c
->streams
);
158 PA_LLIST_HEAD_INIT(pa_operation
, c
->operations
);
161 c
->state
= PA_CONTEXT_UNCONNECTED
;
168 c
->server_list
= NULL
;
173 c
->do_autospawn
= FALSE
;
174 memset(&c
->spawn_api
, 0, sizeof(c
->spawn_api
));
178 pa_check_signal_is_blocked(SIGPIPE
);
182 c
->conf
= pa_client_conf_new();
184 pa_client_conf_from_x11(c
->conf
, NULL
);
186 pa_client_conf_load(c
->conf
, NULL
);
187 pa_client_conf_env(c
->conf
);
189 if (!(c
->mempool
= pa_mempool_new(!c
->conf
->disable_shm
, c
->conf
->shm_size
))) {
191 if (!c
->conf
->disable_shm
)
192 c
->mempool
= pa_mempool_new(FALSE
, c
->conf
->shm_size
);
203 static void context_unlink(pa_context
*c
) {
208 s
= c
->streams
? pa_stream_ref(c
->streams
) : NULL
;
210 pa_stream
*n
= s
->next
? pa_stream_ref(s
->next
) : NULL
;
211 pa_stream_set_state(s
, c
->state
== PA_CONTEXT_FAILED
? PA_STREAM_FAILED
: PA_STREAM_TERMINATED
);
216 while (c
->operations
)
217 pa_operation_cancel(c
->operations
);
220 pa_pdispatch_unref(c
->pdispatch
);
225 pa_pstream_unlink(c
->pstream
);
226 pa_pstream_unref(c
->pstream
);
231 pa_socket_client_unref(c
->client
);
238 static void context_free(pa_context
*c
) {
244 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->system_bus
), filter_cb
, c
);
245 pa_dbus_wrap_connection_free(c
->system_bus
);
248 if (c
->session_bus
) {
249 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->session_bus
), filter_cb
, c
);
250 pa_dbus_wrap_connection_free(c
->session_bus
);
253 if (c
->record_streams
)
254 pa_dynarray_free(c
->record_streams
, NULL
, NULL
);
255 if (c
->playback_streams
)
256 pa_dynarray_free(c
->playback_streams
, NULL
, NULL
);
259 pa_mempool_free(c
->mempool
);
262 pa_client_conf_free(c
->conf
);
264 pa_strlist_free(c
->server_list
);
267 pa_proplist_free(c
->proplist
);
273 pa_context
* pa_context_ref(pa_context
*c
) {
275 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
281 void pa_context_unref(pa_context
*c
) {
283 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
285 if (PA_REFCNT_DEC(c
) <= 0)
289 void pa_context_set_state(pa_context
*c
, pa_context_state_t st
) {
291 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
300 if (c
->state_callback
)
301 c
->state_callback(c
, c
->state_userdata
);
303 if (st
== PA_CONTEXT_FAILED
|| st
== PA_CONTEXT_TERMINATED
)
309 int pa_context_set_error(pa_context
*c
, int error
) {
310 pa_assert(error
>= 0);
311 pa_assert(error
< PA_ERR_MAX
);
319 void pa_context_fail(pa_context
*c
, int error
) {
321 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
323 pa_context_set_error(c
, error
);
324 pa_context_set_state(c
, PA_CONTEXT_FAILED
);
327 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
328 pa_context
*c
= userdata
;
333 pa_context_fail(c
, PA_ERR_CONNECTIONTERMINATED
);
336 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
337 pa_context
*c
= userdata
;
345 if (pa_pdispatch_run(c
->pdispatch
, packet
, creds
, c
) < 0)
346 pa_context_fail(c
, PA_ERR_PROTOCOL
);
351 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
) {
352 pa_context
*c
= userdata
;
357 pa_assert(chunk
->length
> 0);
359 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
363 if ((s
= pa_dynarray_get(c
->record_streams
, channel
))) {
365 if (chunk
->memblock
) {
366 pa_memblockq_seek(s
->record_memblockq
, offset
, seek
);
367 pa_memblockq_push_align(s
->record_memblockq
, chunk
);
369 pa_memblockq_seek(s
->record_memblockq
, offset
+chunk
->length
, seek
);
371 if (s
->read_callback
) {
374 if ((l
= pa_memblockq_get_length(s
->record_memblockq
)) > 0)
375 s
->read_callback(s
, l
, s
->read_userdata
);
382 int pa_context_handle_error(pa_context
*c
, uint32_t command
, pa_tagstruct
*t
, pa_bool_t fail
) {
385 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
387 if (command
== PA_COMMAND_ERROR
) {
390 if (pa_tagstruct_getu32(t
, &err
) < 0 ||
391 !pa_tagstruct_eof(t
)) {
392 pa_context_fail(c
, PA_ERR_PROTOCOL
);
396 } else if (command
== PA_COMMAND_TIMEOUT
)
397 err
= PA_ERR_TIMEOUT
;
399 pa_context_fail(c
, PA_ERR_PROTOCOL
);
404 pa_context_fail(c
, PA_ERR_PROTOCOL
);
408 if (err
>= PA_ERR_MAX
)
409 err
= PA_ERR_UNKNOWN
;
412 pa_context_fail(c
, (int) err
);
416 pa_context_set_error(c
, (int) err
);
421 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
422 pa_context
*c
= userdata
;
426 pa_assert(c
->state
== PA_CONTEXT_AUTHORIZING
|| c
->state
== PA_CONTEXT_SETTING_NAME
);
430 if (command
!= PA_COMMAND_REPLY
) {
431 pa_context_handle_error(c
, command
, t
, TRUE
);
436 case PA_CONTEXT_AUTHORIZING
: {
438 pa_bool_t shm_on_remote
= FALSE
;
440 if (pa_tagstruct_getu32(t
, &c
->version
) < 0 ||
441 !pa_tagstruct_eof(t
)) {
442 pa_context_fail(c
, PA_ERR_PROTOCOL
);
446 /* Minimum supported version */
447 if (c
->version
< 8) {
448 pa_context_fail(c
, PA_ERR_VERSION
);
452 /* Starting with protocol version 13 the MSB of the version
453 tag reflects if shm is available for this connection or
455 if (c
->version
>= 13) {
456 shm_on_remote
= !!(c
->version
& 0x80000000U
);
457 c
->version
&= 0x7FFFFFFFU
;
460 pa_log_debug("Protocol version: remote %u, local %u", c
->version
, PA_PROTOCOL_VERSION
);
462 /* Enable shared memory support if possible */
464 if (c
->version
< 10 || (c
->version
>= 13 && !shm_on_remote
))
469 /* Only enable SHM if both sides are owned by the same
470 * user. This is a security measure because otherwise
471 * data private to the user might leak. */
474 const pa_creds
*creds
;
475 if (!(creds
= pa_pdispatch_creds(pd
)) || getuid() != creds
->uid
)
480 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c
->do_shm
));
481 pa_pstream_enable_shm(c
->pstream
, c
->do_shm
);
483 reply
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
485 if (c
->version
>= 13) {
486 pa_init_proplist(c
->proplist
);
487 pa_tagstruct_put_proplist(reply
, c
->proplist
);
489 pa_tagstruct_puts(reply
, pa_proplist_gets(c
->proplist
, PA_PROP_APPLICATION_NAME
));
491 pa_pstream_send_tagstruct(c
->pstream
, reply
);
492 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
494 pa_context_set_state(c
, PA_CONTEXT_SETTING_NAME
);
498 case PA_CONTEXT_SETTING_NAME
:
500 if ((c
->version
>= 13 && (pa_tagstruct_getu32(t
, &c
->client_index
) < 0 ||
501 c
->client_index
== PA_INVALID_INDEX
)) ||
502 !pa_tagstruct_eof(t
)) {
503 pa_context_fail(c
, PA_ERR_PROTOCOL
);
507 pa_context_set_state(c
, PA_CONTEXT_READY
);
511 pa_assert_not_reached();
518 static void setup_context(pa_context
*c
, pa_iochannel
*io
) {
527 pa_assert(!c
->pstream
);
528 c
->pstream
= pa_pstream_new(c
->mainloop
, io
, c
->mempool
);
530 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
531 pa_pstream_set_recieve_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
532 pa_pstream_set_recieve_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
534 pa_assert(!c
->pdispatch
);
535 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, command_table
, PA_COMMAND_MAX
);
537 if (!c
->conf
->cookie_valid
)
538 pa_log_info(_("No cookie loaded. Attempting to connect without."));
540 t
= pa_tagstruct_command(c
, PA_COMMAND_AUTH
, &tag
);
543 pa_mempool_is_shared(c
->mempool
) &&
546 pa_log_debug("SHM possible: %s", pa_yes_no(c
->do_shm
));
548 /* Starting with protocol version 13 we use the MSB of the version
549 * tag for informing the other side if we could do SHM or not */
550 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
| (c
->do_shm
? 0x80000000U
: 0));
551 pa_tagstruct_put_arbitrary(t
, c
->conf
->cookie
, sizeof(c
->conf
->cookie
));
557 if (pa_iochannel_creds_supported(io
))
558 pa_iochannel_creds_enable(io
);
560 ucred
.uid
= getuid();
561 ucred
.gid
= getgid();
563 pa_pstream_send_tagstruct_with_creds(c
->pstream
, t
, &ucred
);
566 pa_pstream_send_tagstruct(c
->pstream
, t
);
569 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
571 pa_context_set_state(c
, PA_CONTEXT_AUTHORIZING
);
576 #ifdef ENABLE_LEGACY_RUNTIME_DIR
577 static char *get_old_legacy_runtime_dir(void) {
581 if (!pa_get_user_name(u
, sizeof(u
)))
584 p
= pa_sprintf_malloc("/tmp/pulse-%s", u
);
586 if (stat(p
, &st
) < 0) {
591 if (st
.st_uid
!= getuid()) {
599 static char *get_very_old_legacy_runtime_dir(void) {
603 if (!pa_get_home_dir(h
, sizeof(h
)))
606 p
= pa_sprintf_malloc("%s/.pulse", h
);
608 if (stat(p
, &st
) < 0) {
613 if (st
.st_uid
!= getuid()) {
622 static pa_strlist
*prepend_per_user(pa_strlist
*l
) {
625 #ifdef ENABLE_LEGACY_RUNTIME_DIR
626 static char *legacy_dir
;
628 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
629 if ((legacy_dir
= get_very_old_legacy_runtime_dir())) {
630 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
631 l
= pa_strlist_prepend(l
, p
);
633 pa_xfree(legacy_dir
);
636 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
637 if ((legacy_dir
= get_old_legacy_runtime_dir())) {
638 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
639 l
= pa_strlist_prepend(l
, p
);
641 pa_xfree(legacy_dir
);
645 /* The per-user instance */
646 if ((ufn
= pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET
))) {
647 l
= pa_strlist_prepend(l
, ufn
);
656 static int context_autospawn(pa_context
*c
) {
660 pa_log_debug("Trying to autospawn...");
664 if (c
->spawn_api
.prefork
)
665 c
->spawn_api
.prefork();
667 if ((pid
= fork()) < 0) {
668 pa_log_error(_("fork(): %s"), pa_cstrerror(errno
));
669 pa_context_fail(c
, PA_ERR_INTERNAL
);
671 if (c
->spawn_api
.postfork
)
672 c
->spawn_api
.postfork();
678 const char *state
= NULL
;
680 const char * argv
[MAX_ARGS
+1];
683 if (c
->spawn_api
.atfork
)
684 c
->spawn_api
.atfork();
692 argv
[n
++] = c
->conf
->daemon_binary
;
693 argv
[n
++] = "--start";
695 while (n
< MAX_ARGS
) {
698 if (!(a
= pa_split_spaces(c
->conf
->extra_arguments
, &state
)))
706 execv(argv
[0], (char * const *) argv
);
713 if (c
->spawn_api
.postfork
)
714 c
->spawn_api
.postfork();
717 r
= waitpid(pid
, &status
, 0);
718 } while (r
< 0 && errno
== EINTR
);
721 pa_log(_("waitpid(): %s"), pa_cstrerror(errno
));
722 pa_context_fail(c
, PA_ERR_INTERNAL
);
724 } else if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
725 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
740 #endif /* OS_IS_WIN32 */
742 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
);
744 static void track_pulseaudio_on_dbus(pa_context
*c
, DBusBusType type
, pa_dbus_wrap_connection
**conn
) {
750 dbus_error_init(&error
);
751 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, type
, &error
)) || dbus_error_is_set(&error
)) {
752 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
756 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
757 pa_log_warn("Failed to add filter function");
761 if (pa_dbus_add_matches(
762 pa_dbus_wrap_connection_get(*conn
), &error
,
763 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio',arg1=''", NULL
) < 0)
764 pa_log_warn("Unable to track org.pulseaudio: %s: %s", error
.name
, error
.message
);
767 dbus_error_free(&error
);
770 static int try_next_connection(pa_context
*c
) {
775 pa_assert(!c
->client
);
781 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
786 if (c
->do_autospawn
) {
788 if ((r
= context_autospawn(c
)) < 0)
791 /* Autospawn only once */
792 c
->do_autospawn
= FALSE
;
794 /* Connect only to per-user sockets this time */
795 c
->server_list
= prepend_per_user(c
->server_list
);
797 /* Retry connection */
804 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
806 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
808 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
813 pa_log_debug("Trying to connect to %s...", u
);
816 c
->server
= pa_xstrdup(u
);
818 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, u
, PA_NATIVE_DEFAULT_PORT
)))
821 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
822 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
834 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
835 pa_context
*c
= userdata
;
836 int saved_errno
= errno
;
840 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
844 pa_socket_client_unref(client
);
848 /* Try the item in the list */
849 if (saved_errno
== ECONNREFUSED
||
850 saved_errno
== ETIMEDOUT
||
851 saved_errno
== EHOSTUNREACH
) {
852 try_next_connection(c
);
856 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
860 setup_context(c
, io
);
866 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
867 pa_context
*c
= userdata
;
868 pa_bool_t is_session
;
874 if (c
->state
!= PA_CONTEXT_CONNECTING
)
877 is_session
= bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
878 pa_log_debug("Rock!! PulseAudio is baack on %s bus", is_session
? "session" : "system");
881 /* The user instance via PF_LOCAL */
882 c
->server_list
= prepend_per_user(c
->server_list
);
884 /* The system wide instance via PF_LOCAL */
885 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
888 try_next_connection(c
);
891 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
894 int pa_context_connect(
897 pa_context_flags_t flags
,
898 const pa_spawn_api
*api
) {
903 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
905 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
906 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
907 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
908 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
911 server
= c
->conf
->default_server
;
915 c
->no_fail
= flags
& PA_CONTEXT_NOFAIL
;
916 pa_assert(!c
->server_list
);
919 if (!(c
->server_list
= pa_strlist_parse(server
))) {
920 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
927 /* Prepend in reverse order */
929 /* Follow the X display */
930 if ((d
= getenv("DISPLAY"))) {
933 if ((e
= strchr(d
, ':')))
937 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
942 /* Add TCP/IP on the localhost */
943 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
944 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
946 /* The system wide instance via PF_LOCAL */
947 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
949 /* The user instance via PF_LOCAL */
950 c
->server_list
= prepend_per_user(c
->server_list
);
952 /* Set up autospawning */
953 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
956 pa_log_debug("Not doing autospawn since we are root.");
958 c
->do_autospawn
= TRUE
;
966 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
967 r
= try_next_connection(c
);
975 void pa_context_disconnect(pa_context
*c
) {
977 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
979 if (pa_detect_fork())
982 if (PA_CONTEXT_IS_GOOD(c
->state
))
983 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
986 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
988 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
993 int pa_context_errno(pa_context
*c
) {
995 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1000 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1002 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1004 if (pa_detect_fork())
1007 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1010 c
->state_callback
= cb
;
1011 c
->state_userdata
= userdata
;
1014 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1016 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1018 if (pa_detect_fork())
1021 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1024 c
->event_callback
= cb
;
1025 c
->event_userdata
= userdata
;
1028 int pa_context_is_pending(pa_context
*c
) {
1030 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1032 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1033 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1035 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1036 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1040 static void set_dispatch_callbacks(pa_operation
*o
);
1042 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1043 set_dispatch_callbacks(userdata
);
1046 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1047 set_dispatch_callbacks(userdata
);
1050 static void set_dispatch_callbacks(pa_operation
*o
) {
1054 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1055 pa_assert(o
->context
);
1056 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1057 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1059 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1060 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1062 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1063 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1067 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1068 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1074 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1075 cb(o
->context
, o
->userdata
);
1078 pa_operation_done(o
);
1079 pa_operation_unref(o
);
1083 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1087 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1089 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1090 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1091 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1093 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1094 set_dispatch_callbacks(pa_operation_ref(o
));
1099 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1100 pa_operation
*o
= userdata
;
1105 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1110 if (command
!= PA_COMMAND_REPLY
) {
1111 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1115 } else if (!pa_tagstruct_eof(t
)) {
1116 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1121 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1122 cb(o
->context
, success
, o
->userdata
);
1126 pa_operation_done(o
);
1127 pa_operation_unref(o
);
1130 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
) {
1136 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1138 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1139 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1141 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1143 t
= pa_tagstruct_command(c
, command
, &tag
);
1144 pa_pstream_send_tagstruct(c
->pstream
, t
);
1145 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1150 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1152 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1154 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1157 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1163 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1165 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1166 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1168 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1169 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1170 pa_tagstruct_puts(t
, name
);
1171 pa_pstream_send_tagstruct(c
->pstream
, t
);
1172 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
);
1177 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1183 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1185 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1186 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1188 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1189 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1190 pa_tagstruct_puts(t
, name
);
1191 pa_pstream_send_tagstruct(c
->pstream
, t
);
1192 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
);
1197 int pa_context_is_local(pa_context
*c
) {
1199 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1201 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1202 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1204 return !!c
->is_local
;
1207 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1211 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1214 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1215 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1217 if (c
->version
>= 13) {
1218 pa_proplist
*p
= pa_proplist_new();
1220 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1221 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1222 pa_proplist_free(p
);
1227 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1228 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1229 pa_tagstruct_puts(t
, name
);
1230 pa_pstream_send_tagstruct(c
->pstream
, t
);
1231 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
);
1237 const char* pa_get_library_version(void) {
1238 return PACKAGE_VERSION
;
1241 const char* pa_context_get_server(pa_context
*c
) {
1243 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1245 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1246 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1248 if (*c
->server
== '{') {
1249 char *e
= strchr(c
->server
+1, '}');
1250 return e
? e
+1 : c
->server
;
1256 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1257 return PA_PROTOCOL_VERSION
;
1260 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1262 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1264 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1265 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1270 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1276 t
= pa_tagstruct_new(NULL
, 0);
1277 pa_tagstruct_putu32(t
, command
);
1278 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1283 uint32_t pa_context_get_index(pa_context
*c
) {
1285 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1287 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1288 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1289 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1291 return c
->client_index
;
1294 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
) {
1300 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1302 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1303 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1304 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1305 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1307 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1309 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1310 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1311 pa_tagstruct_put_proplist(t
, p
);
1313 pa_pstream_send_tagstruct(c
->pstream
, t
);
1314 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
);
1316 /* Please note that we don't update c->proplist here, because we
1317 * don't export that field */
1322 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1326 const char * const *k
;
1329 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1331 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1332 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1333 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1334 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1336 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1338 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1340 for (k
= keys
; *k
; k
++)
1341 pa_tagstruct_puts(t
, *k
);
1343 pa_tagstruct_puts(t
, NULL
);
1345 pa_pstream_send_tagstruct(c
->pstream
, t
);
1346 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
);
1348 /* Please note that we don't update c->proplist here, because we
1349 * don't export that field */
1354 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1355 pa_context
*c
= userdata
;
1360 pa_assert(command
== PA_COMMAND_EXTENSION
);
1363 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1367 if (c
->version
< 15) {
1368 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1372 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1373 pa_tagstruct_gets(t
, &name
) < 0) {
1374 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1378 if (!strcmp(name
, "module-stream-restore"))
1379 pa_ext_stream_restore_command(c
, tag
, t
);
1381 pa_log(_("Received message for unknown extension '%s'"), name
);
1384 pa_context_unref(c
);
1388 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1389 pa_context
*c
= userdata
;
1390 pa_proplist
*pl
= NULL
;
1394 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1397 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1401 if (c
->version
< 15) {
1402 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1406 pl
= pa_proplist_new();
1408 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1409 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1410 !pa_tagstruct_eof(t
) || !event
) {
1411 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1415 if (c
->event_callback
)
1416 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1419 pa_context_unref(c
);
1422 pa_proplist_free(pl
);