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
);
109 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
);
112 pa_context
*pa_context_new(pa_mainloop_api
*mainloop
, const char *name
) {
113 return pa_context_new_with_proplist(mainloop
, name
, NULL
);
116 static void reset_callbacks(pa_context
*c
) {
119 c
->state_callback
= NULL
;
120 c
->state_userdata
= NULL
;
122 c
->subscribe_callback
= NULL
;
123 c
->subscribe_userdata
= NULL
;
125 c
->event_callback
= NULL
;
126 c
->event_userdata
= NULL
;
128 c
->ext_stream_restore
.callback
= NULL
;
129 c
->ext_stream_restore
.userdata
= NULL
;
132 pa_context
*pa_context_new_with_proplist(pa_mainloop_api
*mainloop
, const char *name
, pa_proplist
*p
) {
137 if (pa_detect_fork())
142 c
= pa_xnew(pa_context
, 1);
145 c
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
148 pa_proplist_sets(c
->proplist
, PA_PROP_APPLICATION_NAME
, name
);
151 c
->system_bus
= c
->session_bus
= NULL
;
153 c
->mainloop
= mainloop
;
157 c
->playback_streams
= pa_dynarray_new();
158 c
->record_streams
= pa_dynarray_new();
159 c
->client_index
= PA_INVALID_INDEX
;
161 PA_LLIST_HEAD_INIT(pa_stream
, c
->streams
);
162 PA_LLIST_HEAD_INIT(pa_operation
, c
->operations
);
165 c
->state
= PA_CONTEXT_UNCONNECTED
;
172 c
->server_list
= NULL
;
177 c
->server_specified
= FALSE
;
179 c
->do_autospawn
= FALSE
;
180 memset(&c
->spawn_api
, 0, sizeof(c
->spawn_api
));
184 pa_check_signal_is_blocked(SIGPIPE
);
188 c
->conf
= pa_client_conf_new();
189 pa_client_conf_load(c
->conf
, NULL
);
191 pa_client_conf_from_x11(c
->conf
, NULL
);
193 pa_client_conf_env(c
->conf
);
195 if (!(c
->mempool
= pa_mempool_new(!c
->conf
->disable_shm
, c
->conf
->shm_size
))) {
197 if (!c
->conf
->disable_shm
)
198 c
->mempool
= pa_mempool_new(FALSE
, c
->conf
->shm_size
);
209 static void context_unlink(pa_context
*c
) {
214 s
= c
->streams
? pa_stream_ref(c
->streams
) : NULL
;
216 pa_stream
*n
= s
->next
? pa_stream_ref(s
->next
) : NULL
;
217 pa_stream_set_state(s
, c
->state
== PA_CONTEXT_FAILED
? PA_STREAM_FAILED
: PA_STREAM_TERMINATED
);
222 while (c
->operations
)
223 pa_operation_cancel(c
->operations
);
226 pa_pdispatch_unref(c
->pdispatch
);
231 pa_pstream_unlink(c
->pstream
);
232 pa_pstream_unref(c
->pstream
);
237 pa_socket_client_unref(c
->client
);
244 static void context_free(pa_context
*c
) {
251 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->system_bus
), filter_cb
, c
);
252 pa_dbus_wrap_connection_free(c
->system_bus
);
255 if (c
->session_bus
) {
256 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->session_bus
), filter_cb
, c
);
257 pa_dbus_wrap_connection_free(c
->session_bus
);
261 if (c
->record_streams
)
262 pa_dynarray_free(c
->record_streams
, NULL
, NULL
);
263 if (c
->playback_streams
)
264 pa_dynarray_free(c
->playback_streams
, NULL
, NULL
);
267 pa_mempool_free(c
->mempool
);
270 pa_client_conf_free(c
->conf
);
272 pa_strlist_free(c
->server_list
);
275 pa_proplist_free(c
->proplist
);
281 pa_context
* pa_context_ref(pa_context
*c
) {
283 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
289 void pa_context_unref(pa_context
*c
) {
291 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
293 if (PA_REFCNT_DEC(c
) <= 0)
297 void pa_context_set_state(pa_context
*c
, pa_context_state_t st
) {
299 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
308 if (c
->state_callback
)
309 c
->state_callback(c
, c
->state_userdata
);
311 if (st
== PA_CONTEXT_FAILED
|| st
== PA_CONTEXT_TERMINATED
)
317 int pa_context_set_error(pa_context
*c
, int error
) {
318 pa_assert(error
>= 0);
319 pa_assert(error
< PA_ERR_MAX
);
327 void pa_context_fail(pa_context
*c
, int error
) {
329 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
331 pa_context_set_error(c
, error
);
332 pa_context_set_state(c
, PA_CONTEXT_FAILED
);
335 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
336 pa_context
*c
= userdata
;
341 pa_context_fail(c
, PA_ERR_CONNECTIONTERMINATED
);
344 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
345 pa_context
*c
= userdata
;
353 if (pa_pdispatch_run(c
->pdispatch
, packet
, creds
, c
) < 0)
354 pa_context_fail(c
, PA_ERR_PROTOCOL
);
359 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
) {
360 pa_context
*c
= userdata
;
365 pa_assert(chunk
->length
> 0);
367 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
371 if ((s
= pa_dynarray_get(c
->record_streams
, channel
))) {
373 if (chunk
->memblock
) {
374 pa_memblockq_seek(s
->record_memblockq
, offset
, seek
, TRUE
);
375 pa_memblockq_push_align(s
->record_memblockq
, chunk
);
377 pa_memblockq_seek(s
->record_memblockq
, offset
+chunk
->length
, seek
, TRUE
);
379 if (s
->read_callback
) {
382 if ((l
= pa_memblockq_get_length(s
->record_memblockq
)) > 0)
383 s
->read_callback(s
, l
, s
->read_userdata
);
390 int pa_context_handle_error(pa_context
*c
, uint32_t command
, pa_tagstruct
*t
, pa_bool_t fail
) {
393 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
395 if (command
== PA_COMMAND_ERROR
) {
398 if (pa_tagstruct_getu32(t
, &err
) < 0 ||
399 !pa_tagstruct_eof(t
)) {
400 pa_context_fail(c
, PA_ERR_PROTOCOL
);
404 } else if (command
== PA_COMMAND_TIMEOUT
)
405 err
= PA_ERR_TIMEOUT
;
407 pa_context_fail(c
, PA_ERR_PROTOCOL
);
412 pa_context_fail(c
, PA_ERR_PROTOCOL
);
416 if (err
>= PA_ERR_MAX
)
417 err
= PA_ERR_UNKNOWN
;
420 pa_context_fail(c
, (int) err
);
424 pa_context_set_error(c
, (int) err
);
429 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
430 pa_context
*c
= userdata
;
434 pa_assert(c
->state
== PA_CONTEXT_AUTHORIZING
|| c
->state
== PA_CONTEXT_SETTING_NAME
);
438 if (command
!= PA_COMMAND_REPLY
) {
439 pa_context_handle_error(c
, command
, t
, TRUE
);
444 case PA_CONTEXT_AUTHORIZING
: {
446 pa_bool_t shm_on_remote
= FALSE
;
448 if (pa_tagstruct_getu32(t
, &c
->version
) < 0 ||
449 !pa_tagstruct_eof(t
)) {
450 pa_context_fail(c
, PA_ERR_PROTOCOL
);
454 /* Minimum supported version */
455 if (c
->version
< 8) {
456 pa_context_fail(c
, PA_ERR_VERSION
);
460 /* Starting with protocol version 13 the MSB of the version
461 tag reflects if shm is available for this connection or
463 if (c
->version
>= 13) {
464 shm_on_remote
= !!(c
->version
& 0x80000000U
);
465 c
->version
&= 0x7FFFFFFFU
;
468 pa_log_debug("Protocol version: remote %u, local %u", c
->version
, PA_PROTOCOL_VERSION
);
470 /* Enable shared memory support if possible */
472 if (c
->version
< 10 || (c
->version
>= 13 && !shm_on_remote
))
477 /* Only enable SHM if both sides are owned by the same
478 * user. This is a security measure because otherwise
479 * data private to the user might leak. */
482 const pa_creds
*creds
;
483 if (!(creds
= pa_pdispatch_creds(pd
)) || getuid() != creds
->uid
)
488 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c
->do_shm
));
489 pa_pstream_enable_shm(c
->pstream
, c
->do_shm
);
491 reply
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
493 if (c
->version
>= 13) {
494 pa_init_proplist(c
->proplist
);
495 pa_tagstruct_put_proplist(reply
, c
->proplist
);
497 pa_tagstruct_puts(reply
, pa_proplist_gets(c
->proplist
, PA_PROP_APPLICATION_NAME
));
499 pa_pstream_send_tagstruct(c
->pstream
, reply
);
500 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
502 pa_context_set_state(c
, PA_CONTEXT_SETTING_NAME
);
506 case PA_CONTEXT_SETTING_NAME
:
508 if ((c
->version
>= 13 && (pa_tagstruct_getu32(t
, &c
->client_index
) < 0 ||
509 c
->client_index
== PA_INVALID_INDEX
)) ||
510 !pa_tagstruct_eof(t
)) {
511 pa_context_fail(c
, PA_ERR_PROTOCOL
);
515 pa_context_set_state(c
, PA_CONTEXT_READY
);
519 pa_assert_not_reached();
526 static void setup_context(pa_context
*c
, pa_iochannel
*io
) {
535 pa_assert(!c
->pstream
);
536 c
->pstream
= pa_pstream_new(c
->mainloop
, io
, c
->mempool
);
538 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
539 pa_pstream_set_recieve_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
540 pa_pstream_set_recieve_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
542 pa_assert(!c
->pdispatch
);
543 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, command_table
, PA_COMMAND_MAX
);
545 if (!c
->conf
->cookie_valid
)
546 pa_log_info(_("No cookie loaded. Attempting to connect without."));
548 t
= pa_tagstruct_command(c
, PA_COMMAND_AUTH
, &tag
);
551 pa_mempool_is_shared(c
->mempool
) &&
554 pa_log_debug("SHM possible: %s", pa_yes_no(c
->do_shm
));
556 /* Starting with protocol version 13 we use the MSB of the version
557 * tag for informing the other side if we could do SHM or not */
558 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
| (c
->do_shm
? 0x80000000U
: 0));
559 pa_tagstruct_put_arbitrary(t
, c
->conf
->cookie
, sizeof(c
->conf
->cookie
));
565 if (pa_iochannel_creds_supported(io
))
566 pa_iochannel_creds_enable(io
);
568 ucred
.uid
= getuid();
569 ucred
.gid
= getgid();
571 pa_pstream_send_tagstruct_with_creds(c
->pstream
, t
, &ucred
);
574 pa_pstream_send_tagstruct(c
->pstream
, t
);
577 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
579 pa_context_set_state(c
, PA_CONTEXT_AUTHORIZING
);
584 #ifdef ENABLE_LEGACY_RUNTIME_DIR
585 static char *get_old_legacy_runtime_dir(void) {
589 if (!pa_get_user_name(u
, sizeof(u
)))
592 p
= pa_sprintf_malloc("/tmp/pulse-%s", u
);
594 if (stat(p
, &st
) < 0) {
599 if (st
.st_uid
!= getuid()) {
607 static char *get_very_old_legacy_runtime_dir(void) {
611 if (!pa_get_home_dir(h
, sizeof(h
)))
614 p
= pa_sprintf_malloc("%s/.pulse", h
);
616 if (stat(p
, &st
) < 0) {
621 if (st
.st_uid
!= getuid()) {
630 static pa_strlist
*prepend_per_user(pa_strlist
*l
) {
633 #ifdef ENABLE_LEGACY_RUNTIME_DIR
634 static char *legacy_dir
;
636 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
637 if ((legacy_dir
= get_very_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
);
644 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
645 if ((legacy_dir
= get_old_legacy_runtime_dir())) {
646 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
647 l
= pa_strlist_prepend(l
, p
);
649 pa_xfree(legacy_dir
);
653 /* The per-user instance */
654 if ((ufn
= pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET
))) {
655 l
= pa_strlist_prepend(l
, ufn
);
664 static int context_autospawn(pa_context
*c
) {
668 pa_log_debug("Trying to autospawn...");
672 if (c
->spawn_api
.prefork
)
673 c
->spawn_api
.prefork();
675 if ((pid
= fork()) < 0) {
676 pa_log_error(_("fork(): %s"), pa_cstrerror(errno
));
677 pa_context_fail(c
, PA_ERR_INTERNAL
);
679 if (c
->spawn_api
.postfork
)
680 c
->spawn_api
.postfork();
686 const char *state
= NULL
;
688 const char * argv
[MAX_ARGS
+1];
691 if (c
->spawn_api
.atfork
)
692 c
->spawn_api
.atfork();
700 argv
[n
++] = c
->conf
->daemon_binary
;
701 argv
[n
++] = "--start";
703 while (n
< MAX_ARGS
) {
706 if (!(a
= pa_split_spaces(c
->conf
->extra_arguments
, &state
)))
714 execv(argv
[0], (char * const *) argv
);
721 if (c
->spawn_api
.postfork
)
722 c
->spawn_api
.postfork();
725 r
= waitpid(pid
, &status
, 0);
726 } while (r
< 0 && errno
== EINTR
);
729 pa_log(_("waitpid(): %s"), pa_cstrerror(errno
));
730 pa_context_fail(c
, PA_ERR_INTERNAL
);
732 } else if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
733 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
748 #endif /* OS_IS_WIN32 */
750 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
);
753 static void track_pulseaudio_on_dbus(pa_context
*c
, DBusBusType type
, pa_dbus_wrap_connection
**conn
) {
759 dbus_error_init(&error
);
760 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, type
, &error
)) || dbus_error_is_set(&error
)) {
761 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
765 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
766 pa_log_warn("Failed to add filter function");
770 if (pa_dbus_add_matches(
771 pa_dbus_wrap_connection_get(*conn
), &error
,
772 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL
) < 0)
773 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
776 dbus_error_free(&error
);
780 static int try_next_connection(pa_context
*c
) {
785 pa_assert(!c
->client
);
791 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
796 if (c
->do_autospawn
) {
798 if ((r
= context_autospawn(c
)) < 0)
801 /* Autospawn only once */
802 c
->do_autospawn
= FALSE
;
804 /* Connect only to per-user sockets this time */
805 c
->server_list
= prepend_per_user(c
->server_list
);
807 /* Retry connection */
813 if (c
->no_fail
&& !c
->server_specified
) {
815 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
817 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
820 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
825 pa_log_debug("Trying to connect to %s...", u
);
828 c
->server
= pa_xstrdup(u
);
830 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, u
, PA_NATIVE_DEFAULT_PORT
)))
833 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
834 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
846 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
847 pa_context
*c
= userdata
;
848 int saved_errno
= errno
;
852 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
856 pa_socket_client_unref(client
);
860 /* Try the item in the list */
861 if (saved_errno
== ECONNREFUSED
||
862 saved_errno
== ETIMEDOUT
||
863 saved_errno
== EHOSTUNREACH
) {
864 try_next_connection(c
);
868 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
872 setup_context(c
, io
);
879 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
880 pa_context
*c
= userdata
;
881 pa_bool_t is_session
;
887 if (c
->state
!= PA_CONTEXT_CONNECTING
)
893 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
895 is_session
= bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
896 pa_log_debug("Rock!! PulseAudio is back on %s bus", is_session
? "session" : "system");
899 /* The user instance via PF_LOCAL */
900 c
->server_list
= prepend_per_user(c
->server_list
);
902 /* The system wide instance via PF_LOCAL */
903 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
905 try_next_connection(c
);
908 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
912 int pa_context_connect(
915 pa_context_flags_t flags
,
916 const pa_spawn_api
*api
) {
921 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
923 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
924 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
925 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
926 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
929 c
->conf
->autospawn
= FALSE
;
931 server
= c
->conf
->default_server
;
935 c
->no_fail
= flags
& PA_CONTEXT_NOFAIL
;
936 c
->server_specified
= !!server
;
937 pa_assert(!c
->server_list
);
940 if (!(c
->server_list
= pa_strlist_parse(server
))) {
941 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
948 /* Prepend in reverse order */
950 /* Follow the X display */
951 if ((d
= getenv("DISPLAY"))) {
954 if ((e
= strchr(d
, ':')))
958 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
963 /* Add TCP/IP on the localhost */
964 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
965 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
967 /* The system wide instance via PF_LOCAL */
968 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
970 /* The user instance via PF_LOCAL */
971 c
->server_list
= prepend_per_user(c
->server_list
);
974 /* Set up autospawning */
975 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
978 pa_log_debug("Not doing autospawn since we are root.");
980 c
->do_autospawn
= TRUE
;
987 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
988 r
= try_next_connection(c
);
996 void pa_context_disconnect(pa_context
*c
) {
998 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1000 if (pa_detect_fork())
1003 if (PA_CONTEXT_IS_GOOD(c
->state
))
1004 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
1007 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
1009 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1014 int pa_context_errno(pa_context
*c
) {
1016 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1021 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1023 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1025 if (pa_detect_fork())
1028 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1031 c
->state_callback
= cb
;
1032 c
->state_userdata
= userdata
;
1035 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1037 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1039 if (pa_detect_fork())
1042 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1045 c
->event_callback
= cb
;
1046 c
->event_userdata
= userdata
;
1049 int pa_context_is_pending(pa_context
*c
) {
1051 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1053 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1054 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1056 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1057 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1061 static void set_dispatch_callbacks(pa_operation
*o
);
1063 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1064 set_dispatch_callbacks(userdata
);
1067 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1068 set_dispatch_callbacks(userdata
);
1071 static void set_dispatch_callbacks(pa_operation
*o
) {
1075 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1076 pa_assert(o
->context
);
1077 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1078 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1080 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1081 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1083 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1084 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1088 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1089 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1095 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1096 cb(o
->context
, o
->userdata
);
1099 pa_operation_done(o
);
1100 pa_operation_unref(o
);
1104 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1108 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1110 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1111 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1112 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1114 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1115 set_dispatch_callbacks(pa_operation_ref(o
));
1120 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1121 pa_operation
*o
= userdata
;
1126 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1131 if (command
!= PA_COMMAND_REPLY
) {
1132 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1136 } else if (!pa_tagstruct_eof(t
)) {
1137 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1142 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1143 cb(o
->context
, success
, o
->userdata
);
1147 pa_operation_done(o
);
1148 pa_operation_unref(o
);
1151 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
) {
1157 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1159 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1160 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1162 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1164 t
= pa_tagstruct_command(c
, command
, &tag
);
1165 pa_pstream_send_tagstruct(c
->pstream
, t
);
1166 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1171 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1173 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1175 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1178 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1184 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1186 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1187 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1189 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1190 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1191 pa_tagstruct_puts(t
, name
);
1192 pa_pstream_send_tagstruct(c
->pstream
, t
);
1193 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
);
1198 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1204 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1206 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1207 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1209 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1210 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1211 pa_tagstruct_puts(t
, name
);
1212 pa_pstream_send_tagstruct(c
->pstream
, t
);
1213 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
);
1218 int pa_context_is_local(pa_context
*c
) {
1220 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1222 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1223 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1225 return !!c
->is_local
;
1228 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1232 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1235 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1236 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1238 if (c
->version
>= 13) {
1239 pa_proplist
*p
= pa_proplist_new();
1241 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1242 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1243 pa_proplist_free(p
);
1248 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1249 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1250 pa_tagstruct_puts(t
, name
);
1251 pa_pstream_send_tagstruct(c
->pstream
, t
);
1252 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
);
1258 const char* pa_get_library_version(void) {
1259 return PACKAGE_VERSION
;
1262 const char* pa_context_get_server(pa_context
*c
) {
1264 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1266 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1267 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1269 if (*c
->server
== '{') {
1270 char *e
= strchr(c
->server
+1, '}');
1271 return e
? e
+1 : c
->server
;
1277 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1278 return PA_PROTOCOL_VERSION
;
1281 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1283 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1285 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1286 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1291 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1297 t
= pa_tagstruct_new(NULL
, 0);
1298 pa_tagstruct_putu32(t
, command
);
1299 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1304 uint32_t pa_context_get_index(pa_context
*c
) {
1306 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1308 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1309 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1310 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1312 return c
->client_index
;
1315 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
) {
1321 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1323 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1324 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1325 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1326 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1328 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1330 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1331 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1332 pa_tagstruct_put_proplist(t
, p
);
1334 pa_pstream_send_tagstruct(c
->pstream
, t
);
1335 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
);
1337 /* Please note that we don't update c->proplist here, because we
1338 * don't export that field */
1343 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1347 const char * const *k
;
1350 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1352 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1353 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1354 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1355 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1357 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1359 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1361 for (k
= keys
; *k
; k
++)
1362 pa_tagstruct_puts(t
, *k
);
1364 pa_tagstruct_puts(t
, NULL
);
1366 pa_pstream_send_tagstruct(c
->pstream
, t
);
1367 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
);
1369 /* Please note that we don't update c->proplist here, because we
1370 * don't export that field */
1375 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1376 pa_context
*c
= userdata
;
1381 pa_assert(command
== PA_COMMAND_EXTENSION
);
1384 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1388 if (c
->version
< 15) {
1389 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1393 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1394 pa_tagstruct_gets(t
, &name
) < 0) {
1395 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1399 if (!strcmp(name
, "module-stream-restore"))
1400 pa_ext_stream_restore_command(c
, tag
, t
);
1402 pa_log(_("Received message for unknown extension '%s'"), name
);
1405 pa_context_unref(c
);
1409 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1410 pa_context
*c
= userdata
;
1411 pa_proplist
*pl
= NULL
;
1415 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1418 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1422 if (c
->version
< 15) {
1423 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1427 pl
= pa_proplist_new();
1429 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1430 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1431 !pa_tagstruct_eof(t
) || !event
) {
1432 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1436 if (c
->event_callback
)
1437 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1440 pa_context_unref(c
);
1443 pa_proplist_free(pl
);