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.Server',arg1=''", NULL
) < 0)
764 pa_log_warn("Unable to track org.pulseaudio.Server: %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
)
880 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
882 is_session
= bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
883 pa_log_debug("Rock!! PulseAudio is back on %s bus", is_session
? "session" : "system");
886 /* The user instance via PF_LOCAL */
887 c
->server_list
= prepend_per_user(c
->server_list
);
889 /* The system wide instance via PF_LOCAL */
890 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
892 try_next_connection(c
);
895 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
898 int pa_context_connect(
901 pa_context_flags_t flags
,
902 const pa_spawn_api
*api
) {
907 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
909 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
910 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
911 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
912 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
915 server
= c
->conf
->default_server
;
919 c
->no_fail
= flags
& PA_CONTEXT_NOFAIL
;
920 pa_assert(!c
->server_list
);
923 if (!(c
->server_list
= pa_strlist_parse(server
))) {
924 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
931 /* Prepend in reverse order */
933 /* Follow the X display */
934 if ((d
= getenv("DISPLAY"))) {
937 if ((e
= strchr(d
, ':')))
941 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
946 /* Add TCP/IP on the localhost */
947 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
948 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
950 /* The system wide instance via PF_LOCAL */
951 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
953 /* The user instance via PF_LOCAL */
954 c
->server_list
= prepend_per_user(c
->server_list
);
956 /* Set up autospawning */
957 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
960 pa_log_debug("Not doing autospawn since we are root.");
962 c
->do_autospawn
= TRUE
;
970 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
971 r
= try_next_connection(c
);
979 void pa_context_disconnect(pa_context
*c
) {
981 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
983 if (pa_detect_fork())
986 if (PA_CONTEXT_IS_GOOD(c
->state
))
987 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
990 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
992 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
997 int pa_context_errno(pa_context
*c
) {
999 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1004 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1006 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1008 if (pa_detect_fork())
1011 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1014 c
->state_callback
= cb
;
1015 c
->state_userdata
= userdata
;
1018 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1020 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1022 if (pa_detect_fork())
1025 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1028 c
->event_callback
= cb
;
1029 c
->event_userdata
= userdata
;
1032 int pa_context_is_pending(pa_context
*c
) {
1034 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1036 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1037 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1039 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1040 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1044 static void set_dispatch_callbacks(pa_operation
*o
);
1046 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1047 set_dispatch_callbacks(userdata
);
1050 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1051 set_dispatch_callbacks(userdata
);
1054 static void set_dispatch_callbacks(pa_operation
*o
) {
1058 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1059 pa_assert(o
->context
);
1060 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1061 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1063 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1064 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1066 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1067 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1071 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1072 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1078 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1079 cb(o
->context
, o
->userdata
);
1082 pa_operation_done(o
);
1083 pa_operation_unref(o
);
1087 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1091 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1093 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1094 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1095 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1097 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1098 set_dispatch_callbacks(pa_operation_ref(o
));
1103 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1104 pa_operation
*o
= userdata
;
1109 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1114 if (command
!= PA_COMMAND_REPLY
) {
1115 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1119 } else if (!pa_tagstruct_eof(t
)) {
1120 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1125 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1126 cb(o
->context
, success
, o
->userdata
);
1130 pa_operation_done(o
);
1131 pa_operation_unref(o
);
1134 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
) {
1140 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1142 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1143 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1145 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1147 t
= pa_tagstruct_command(c
, command
, &tag
);
1148 pa_pstream_send_tagstruct(c
->pstream
, t
);
1149 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1154 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1156 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1158 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1161 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1167 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1169 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1170 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1172 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1173 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1174 pa_tagstruct_puts(t
, name
);
1175 pa_pstream_send_tagstruct(c
->pstream
, t
);
1176 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
);
1181 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1187 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1189 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1190 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1192 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1193 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1194 pa_tagstruct_puts(t
, name
);
1195 pa_pstream_send_tagstruct(c
->pstream
, t
);
1196 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
);
1201 int pa_context_is_local(pa_context
*c
) {
1203 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1205 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1206 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1208 return !!c
->is_local
;
1211 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1215 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1218 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1219 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1221 if (c
->version
>= 13) {
1222 pa_proplist
*p
= pa_proplist_new();
1224 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1225 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1226 pa_proplist_free(p
);
1231 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1232 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1233 pa_tagstruct_puts(t
, name
);
1234 pa_pstream_send_tagstruct(c
->pstream
, t
);
1235 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
);
1241 const char* pa_get_library_version(void) {
1242 return PACKAGE_VERSION
;
1245 const char* pa_context_get_server(pa_context
*c
) {
1247 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1249 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1250 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1252 if (*c
->server
== '{') {
1253 char *e
= strchr(c
->server
+1, '}');
1254 return e
? e
+1 : c
->server
;
1260 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1261 return PA_PROTOCOL_VERSION
;
1264 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1266 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1268 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1269 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1274 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1280 t
= pa_tagstruct_new(NULL
, 0);
1281 pa_tagstruct_putu32(t
, command
);
1282 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1287 uint32_t pa_context_get_index(pa_context
*c
) {
1289 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1291 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1292 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1293 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1295 return c
->client_index
;
1298 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
) {
1304 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1306 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1307 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1308 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1309 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1311 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1313 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1314 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1315 pa_tagstruct_put_proplist(t
, p
);
1317 pa_pstream_send_tagstruct(c
->pstream
, t
);
1318 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
);
1320 /* Please note that we don't update c->proplist here, because we
1321 * don't export that field */
1326 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1330 const char * const *k
;
1333 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1335 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1336 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1337 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1338 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1340 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1342 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1344 for (k
= keys
; *k
; k
++)
1345 pa_tagstruct_puts(t
, *k
);
1347 pa_tagstruct_puts(t
, NULL
);
1349 pa_pstream_send_tagstruct(c
->pstream
, t
);
1350 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
);
1352 /* Please note that we don't update c->proplist here, because we
1353 * don't export that field */
1358 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1359 pa_context
*c
= userdata
;
1364 pa_assert(command
== PA_COMMAND_EXTENSION
);
1367 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1371 if (c
->version
< 15) {
1372 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1376 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1377 pa_tagstruct_gets(t
, &name
) < 0) {
1378 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1382 if (!strcmp(name
, "module-stream-restore"))
1383 pa_ext_stream_restore_command(c
, tag
, t
);
1385 pa_log(_("Received message for unknown extension '%s'"), name
);
1388 pa_context_unref(c
);
1392 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1393 pa_context
*c
= userdata
;
1394 pa_proplist
*pl
= NULL
;
1398 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1401 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1405 if (c
->version
< 15) {
1406 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1410 pl
= pa_proplist_new();
1412 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1413 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1414 !pa_tagstruct_eof(t
) || !event
) {
1415 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1419 if (c
->event_callback
)
1420 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1423 pa_context_unref(c
);
1426 pa_proplist_free(pl
);