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_SESSION
, &c
->session_bus
);
817 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_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
= c
->session_bus
&& 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
);
906 try_next_connection(c
);
909 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
913 int pa_context_connect(
916 pa_context_flags_t flags
,
917 const pa_spawn_api
*api
) {
922 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
924 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
925 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
926 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
927 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
930 c
->conf
->autospawn
= FALSE
;
932 server
= c
->conf
->default_server
;
936 c
->no_fail
= flags
& PA_CONTEXT_NOFAIL
;
937 c
->server_specified
= !!server
;
938 pa_assert(!c
->server_list
);
941 if (!(c
->server_list
= pa_strlist_parse(server
))) {
942 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
949 /* Prepend in reverse order */
951 /* Follow the X display */
952 if ((d
= getenv("DISPLAY"))) {
955 if ((e
= strchr(d
, ':')))
959 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
964 /* Add TCP/IP on the localhost */
965 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
966 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
968 /* The system wide instance via PF_LOCAL */
969 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
971 /* The user instance via PF_LOCAL */
972 c
->server_list
= prepend_per_user(c
->server_list
);
975 /* Set up autospawning */
976 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
979 pa_log_debug("Not doing autospawn since we are root.");
981 c
->do_autospawn
= TRUE
;
988 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
989 r
= try_next_connection(c
);
997 void pa_context_disconnect(pa_context
*c
) {
999 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1001 if (pa_detect_fork())
1004 if (PA_CONTEXT_IS_GOOD(c
->state
))
1005 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
1008 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
1010 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1015 int pa_context_errno(pa_context
*c
) {
1017 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1022 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1024 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1026 if (pa_detect_fork())
1029 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1032 c
->state_callback
= cb
;
1033 c
->state_userdata
= userdata
;
1036 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1038 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1040 if (pa_detect_fork())
1043 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1046 c
->event_callback
= cb
;
1047 c
->event_userdata
= userdata
;
1050 int pa_context_is_pending(pa_context
*c
) {
1052 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1054 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1055 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1057 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1058 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1062 static void set_dispatch_callbacks(pa_operation
*o
);
1064 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1065 set_dispatch_callbacks(userdata
);
1068 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1069 set_dispatch_callbacks(userdata
);
1072 static void set_dispatch_callbacks(pa_operation
*o
) {
1076 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1077 pa_assert(o
->context
);
1078 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1079 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1081 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1082 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1084 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1085 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1089 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1090 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1096 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1097 cb(o
->context
, o
->userdata
);
1100 pa_operation_done(o
);
1101 pa_operation_unref(o
);
1105 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1109 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1111 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1112 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1113 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1115 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1116 set_dispatch_callbacks(pa_operation_ref(o
));
1121 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1122 pa_operation
*o
= userdata
;
1127 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1132 if (command
!= PA_COMMAND_REPLY
) {
1133 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1137 } else if (!pa_tagstruct_eof(t
)) {
1138 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1143 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1144 cb(o
->context
, success
, o
->userdata
);
1148 pa_operation_done(o
);
1149 pa_operation_unref(o
);
1152 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
) {
1158 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1160 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1161 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1163 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1165 t
= pa_tagstruct_command(c
, command
, &tag
);
1166 pa_pstream_send_tagstruct(c
->pstream
, t
);
1167 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1172 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1174 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1176 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1179 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1185 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1187 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1188 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1190 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1191 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1192 pa_tagstruct_puts(t
, name
);
1193 pa_pstream_send_tagstruct(c
->pstream
, t
);
1194 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
);
1199 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1205 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1207 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1208 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1210 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1211 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1212 pa_tagstruct_puts(t
, name
);
1213 pa_pstream_send_tagstruct(c
->pstream
, t
);
1214 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
);
1219 int pa_context_is_local(pa_context
*c
) {
1221 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1223 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1224 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1226 return !!c
->is_local
;
1229 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1233 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1236 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1237 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1239 if (c
->version
>= 13) {
1240 pa_proplist
*p
= pa_proplist_new();
1242 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1243 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1244 pa_proplist_free(p
);
1249 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1250 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1251 pa_tagstruct_puts(t
, name
);
1252 pa_pstream_send_tagstruct(c
->pstream
, t
);
1253 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
);
1259 const char* pa_get_library_version(void) {
1260 return PACKAGE_VERSION
;
1263 const char* pa_context_get_server(pa_context
*c
) {
1265 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1267 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1268 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1270 if (*c
->server
== '{') {
1271 char *e
= strchr(c
->server
+1, '}');
1272 return e
? e
+1 : c
->server
;
1278 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1279 return PA_PROTOCOL_VERSION
;
1282 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1284 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1286 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1287 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1292 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1298 t
= pa_tagstruct_new(NULL
, 0);
1299 pa_tagstruct_putu32(t
, command
);
1300 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1305 uint32_t pa_context_get_index(pa_context
*c
) {
1307 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1309 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1310 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1311 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1313 return c
->client_index
;
1316 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
) {
1322 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1324 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1325 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1326 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1327 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1329 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1331 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1332 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1333 pa_tagstruct_put_proplist(t
, p
);
1335 pa_pstream_send_tagstruct(c
->pstream
, t
);
1336 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
);
1338 /* Please note that we don't update c->proplist here, because we
1339 * don't export that field */
1344 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1348 const char * const *k
;
1351 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1353 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1354 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1355 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1356 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1358 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1360 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1362 for (k
= keys
; *k
; k
++)
1363 pa_tagstruct_puts(t
, *k
);
1365 pa_tagstruct_puts(t
, NULL
);
1367 pa_pstream_send_tagstruct(c
->pstream
, t
);
1368 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
);
1370 /* Please note that we don't update c->proplist here, because we
1371 * don't export that field */
1376 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1377 pa_context
*c
= userdata
;
1382 pa_assert(command
== PA_COMMAND_EXTENSION
);
1385 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1389 if (c
->version
< 15) {
1390 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1394 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1395 pa_tagstruct_gets(t
, &name
) < 0) {
1396 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1400 if (!strcmp(name
, "module-stream-restore"))
1401 pa_ext_stream_restore_command(c
, tag
, t
);
1403 pa_log(_("Received message for unknown extension '%s'"), name
);
1406 pa_context_unref(c
);
1410 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1411 pa_context
*c
= userdata
;
1412 pa_proplist
*pl
= NULL
;
1416 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1419 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1423 if (c
->version
< 15) {
1424 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1428 pl
= pa_proplist_new();
1430 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1431 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1432 !pa_tagstruct_eof(t
) || !event
) {
1433 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1437 if (c
->event_callback
)
1438 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1441 pa_context_unref(c
);
1444 pa_proplist_free(pl
);