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
104 static void context_free(pa_context
*c
);
105 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
);
107 pa_context
*pa_context_new(pa_mainloop_api
*mainloop
, const char *name
) {
108 return pa_context_new_with_proplist(mainloop
, name
, NULL
);
111 static void reset_callbacks(pa_context
*c
) {
114 c
->state_callback
= NULL
;
115 c
->state_userdata
= NULL
;
117 c
->subscribe_callback
= NULL
;
118 c
->subscribe_userdata
= NULL
;
120 c
->event_callback
= NULL
;
121 c
->event_userdata
= NULL
;
123 c
->ext_stream_restore
.callback
= NULL
;
124 c
->ext_stream_restore
.userdata
= NULL
;
127 pa_context
*pa_context_new_with_proplist(pa_mainloop_api
*mainloop
, const char *name
, pa_proplist
*p
) {
132 if (pa_detect_fork())
137 c
= pa_xnew(pa_context
, 1);
140 c
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
143 pa_proplist_sets(c
->proplist
, PA_PROP_APPLICATION_NAME
, name
);
146 c
->system_bus
= c
->session_bus
= NULL
;
147 c
->mainloop
= mainloop
;
151 c
->playback_streams
= pa_dynarray_new();
152 c
->record_streams
= pa_dynarray_new();
153 c
->client_index
= PA_INVALID_INDEX
;
155 PA_LLIST_HEAD_INIT(pa_stream
, c
->streams
);
156 PA_LLIST_HEAD_INIT(pa_operation
, c
->operations
);
159 c
->state
= PA_CONTEXT_UNCONNECTED
;
166 c
->server_list
= NULL
;
171 c
->do_autospawn
= FALSE
;
172 memset(&c
->spawn_api
, 0, sizeof(c
->spawn_api
));
176 pa_check_signal_is_blocked(SIGPIPE
);
180 c
->conf
= pa_client_conf_new();
182 pa_client_conf_from_x11(c
->conf
, NULL
);
184 pa_client_conf_load(c
->conf
, NULL
);
185 pa_client_conf_env(c
->conf
);
187 if (!(c
->mempool
= pa_mempool_new(!c
->conf
->disable_shm
, c
->conf
->shm_size
))) {
189 if (!c
->conf
->disable_shm
)
190 c
->mempool
= pa_mempool_new(FALSE
, c
->conf
->shm_size
);
201 static void context_unlink(pa_context
*c
) {
206 s
= c
->streams
? pa_stream_ref(c
->streams
) : NULL
;
208 pa_stream
*n
= s
->next
? pa_stream_ref(s
->next
) : NULL
;
209 pa_stream_set_state(s
, c
->state
== PA_CONTEXT_FAILED
? PA_STREAM_FAILED
: PA_STREAM_TERMINATED
);
214 while (c
->operations
)
215 pa_operation_cancel(c
->operations
);
218 pa_pdispatch_unref(c
->pdispatch
);
223 pa_pstream_unlink(c
->pstream
);
224 pa_pstream_unref(c
->pstream
);
229 pa_socket_client_unref(c
->client
);
236 static void context_free(pa_context
*c
) {
242 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->system_bus
), filter_cb
, c
);
243 pa_dbus_wrap_connection_free(c
->system_bus
);
246 if (c
->session_bus
) {
247 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->session_bus
), filter_cb
, c
);
248 pa_dbus_wrap_connection_free(c
->session_bus
);
251 if (c
->record_streams
)
252 pa_dynarray_free(c
->record_streams
, NULL
, NULL
);
253 if (c
->playback_streams
)
254 pa_dynarray_free(c
->playback_streams
, NULL
, NULL
);
257 pa_mempool_free(c
->mempool
);
260 pa_client_conf_free(c
->conf
);
262 pa_strlist_free(c
->server_list
);
265 pa_proplist_free(c
->proplist
);
271 pa_context
* pa_context_ref(pa_context
*c
) {
273 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
279 void pa_context_unref(pa_context
*c
) {
281 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
283 if (PA_REFCNT_DEC(c
) <= 0)
287 void pa_context_set_state(pa_context
*c
, pa_context_state_t st
) {
289 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
298 if (c
->state_callback
)
299 c
->state_callback(c
, c
->state_userdata
);
301 if (st
== PA_CONTEXT_FAILED
|| st
== PA_CONTEXT_TERMINATED
)
307 int pa_context_set_error(pa_context
*c
, int error
) {
308 pa_assert(error
>= 0);
309 pa_assert(error
< PA_ERR_MAX
);
317 void pa_context_fail(pa_context
*c
, int error
) {
319 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
321 pa_context_set_error(c
, error
);
322 pa_context_set_state(c
, PA_CONTEXT_FAILED
);
325 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
326 pa_context
*c
= userdata
;
331 pa_context_fail(c
, PA_ERR_CONNECTIONTERMINATED
);
334 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
335 pa_context
*c
= userdata
;
343 if (pa_pdispatch_run(c
->pdispatch
, packet
, creds
, c
) < 0)
344 pa_context_fail(c
, PA_ERR_PROTOCOL
);
349 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
) {
350 pa_context
*c
= userdata
;
355 pa_assert(chunk
->length
> 0);
357 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
361 if ((s
= pa_dynarray_get(c
->record_streams
, channel
))) {
363 if (chunk
->memblock
) {
364 pa_memblockq_seek(s
->record_memblockq
, offset
, seek
);
365 pa_memblockq_push_align(s
->record_memblockq
, chunk
);
367 pa_memblockq_seek(s
->record_memblockq
, offset
+chunk
->length
, seek
);
369 if (s
->read_callback
) {
372 if ((l
= pa_memblockq_get_length(s
->record_memblockq
)) > 0)
373 s
->read_callback(s
, l
, s
->read_userdata
);
380 int pa_context_handle_error(pa_context
*c
, uint32_t command
, pa_tagstruct
*t
, pa_bool_t fail
) {
383 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
385 if (command
== PA_COMMAND_ERROR
) {
388 if (pa_tagstruct_getu32(t
, &err
) < 0 ||
389 !pa_tagstruct_eof(t
)) {
390 pa_context_fail(c
, PA_ERR_PROTOCOL
);
394 } else if (command
== PA_COMMAND_TIMEOUT
)
395 err
= PA_ERR_TIMEOUT
;
397 pa_context_fail(c
, PA_ERR_PROTOCOL
);
402 pa_context_fail(c
, PA_ERR_PROTOCOL
);
406 if (err
>= PA_ERR_MAX
)
407 err
= PA_ERR_UNKNOWN
;
410 pa_context_fail(c
, (int) err
);
414 pa_context_set_error(c
, (int) err
);
419 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
420 pa_context
*c
= userdata
;
424 pa_assert(c
->state
== PA_CONTEXT_AUTHORIZING
|| c
->state
== PA_CONTEXT_SETTING_NAME
);
428 if (command
!= PA_COMMAND_REPLY
) {
429 pa_context_handle_error(c
, command
, t
, TRUE
);
434 case PA_CONTEXT_AUTHORIZING
: {
436 pa_bool_t shm_on_remote
= FALSE
;
438 if (pa_tagstruct_getu32(t
, &c
->version
) < 0 ||
439 !pa_tagstruct_eof(t
)) {
440 pa_context_fail(c
, PA_ERR_PROTOCOL
);
444 /* Minimum supported version */
445 if (c
->version
< 8) {
446 pa_context_fail(c
, PA_ERR_VERSION
);
450 /* Starting with protocol version 13 the MSB of the version
451 tag reflects if shm is available for this connection or
453 if (c
->version
>= 13) {
454 shm_on_remote
= !!(c
->version
& 0x80000000U
);
455 c
->version
&= 0x7FFFFFFFU
;
458 pa_log_debug("Protocol version: remote %u, local %u", c
->version
, PA_PROTOCOL_VERSION
);
460 /* Enable shared memory support if possible */
462 if (c
->version
< 10 || (c
->version
>= 13 && !shm_on_remote
))
467 /* Only enable SHM if both sides are owned by the same
468 * user. This is a security measure because otherwise
469 * data private to the user might leak. */
472 const pa_creds
*creds
;
473 if (!(creds
= pa_pdispatch_creds(pd
)) || getuid() != creds
->uid
)
478 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c
->do_shm
));
479 pa_pstream_enable_shm(c
->pstream
, c
->do_shm
);
481 reply
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
483 if (c
->version
>= 13) {
484 pa_init_proplist(c
->proplist
);
485 pa_tagstruct_put_proplist(reply
, c
->proplist
);
487 pa_tagstruct_puts(reply
, pa_proplist_gets(c
->proplist
, PA_PROP_APPLICATION_NAME
));
489 pa_pstream_send_tagstruct(c
->pstream
, reply
);
490 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
492 pa_context_set_state(c
, PA_CONTEXT_SETTING_NAME
);
496 case PA_CONTEXT_SETTING_NAME
:
498 if ((c
->version
>= 13 && (pa_tagstruct_getu32(t
, &c
->client_index
) < 0 ||
499 c
->client_index
== PA_INVALID_INDEX
)) ||
500 !pa_tagstruct_eof(t
)) {
501 pa_context_fail(c
, PA_ERR_PROTOCOL
);
505 pa_context_set_state(c
, PA_CONTEXT_READY
);
509 pa_assert_not_reached();
516 static void setup_context(pa_context
*c
, pa_iochannel
*io
) {
525 pa_assert(!c
->pstream
);
526 c
->pstream
= pa_pstream_new(c
->mainloop
, io
, c
->mempool
);
528 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
529 pa_pstream_set_recieve_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
530 pa_pstream_set_recieve_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
532 pa_assert(!c
->pdispatch
);
533 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, command_table
, PA_COMMAND_MAX
);
535 if (!c
->conf
->cookie_valid
)
536 pa_log_info(_("No cookie loaded. Attempting to connect without."));
538 t
= pa_tagstruct_command(c
, PA_COMMAND_AUTH
, &tag
);
541 pa_mempool_is_shared(c
->mempool
) &&
544 pa_log_debug("SHM possible: %s", pa_yes_no(c
->do_shm
));
546 /* Starting with protocol version 13 we use the MSB of the version
547 * tag for informing the other side if we could do SHM or not */
548 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
| (c
->do_shm
? 0x80000000U
: 0));
549 pa_tagstruct_put_arbitrary(t
, c
->conf
->cookie
, sizeof(c
->conf
->cookie
));
555 if (pa_iochannel_creds_supported(io
))
556 pa_iochannel_creds_enable(io
);
558 ucred
.uid
= getuid();
559 ucred
.gid
= getgid();
561 pa_pstream_send_tagstruct_with_creds(c
->pstream
, t
, &ucred
);
564 pa_pstream_send_tagstruct(c
->pstream
, t
);
567 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
569 pa_context_set_state(c
, PA_CONTEXT_AUTHORIZING
);
574 #ifdef ENABLE_LEGACY_RUNTIME_DIR
575 static char *get_old_legacy_runtime_dir(void) {
579 if (!pa_get_user_name(u
, sizeof(u
)))
582 p
= pa_sprintf_malloc("/tmp/pulse-%s", u
);
584 if (stat(p
, &st
) < 0) {
589 if (st
.st_uid
!= getuid()) {
597 static char *get_very_old_legacy_runtime_dir(void) {
601 if (!pa_get_home_dir(h
, sizeof(h
)))
604 p
= pa_sprintf_malloc("%s/.pulse", h
);
606 if (stat(p
, &st
) < 0) {
611 if (st
.st_uid
!= getuid()) {
620 static pa_strlist
*prepend_per_user(pa_strlist
*l
) {
623 #ifdef ENABLE_LEGACY_RUNTIME_DIR
624 static char *legacy_dir
;
626 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
627 if ((legacy_dir
= get_very_old_legacy_runtime_dir())) {
628 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
629 l
= pa_strlist_prepend(l
, p
);
631 pa_xfree(legacy_dir
);
634 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
635 if ((legacy_dir
= get_old_legacy_runtime_dir())) {
636 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
637 l
= pa_strlist_prepend(l
, p
);
639 pa_xfree(legacy_dir
);
643 /* The per-user instance */
644 if ((ufn
= pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET
))) {
645 l
= pa_strlist_prepend(l
, ufn
);
654 static int context_autospawn(pa_context
*c
) {
658 pa_log_debug("Trying to autospawn...");
662 if (c
->spawn_api
.prefork
)
663 c
->spawn_api
.prefork();
665 if ((pid
= fork()) < 0) {
666 pa_log_error(_("fork(): %s"), pa_cstrerror(errno
));
667 pa_context_fail(c
, PA_ERR_INTERNAL
);
669 if (c
->spawn_api
.postfork
)
670 c
->spawn_api
.postfork();
676 const char *state
= NULL
;
678 const char * argv
[MAX_ARGS
+1];
681 if (c
->spawn_api
.atfork
)
682 c
->spawn_api
.atfork();
690 argv
[n
++] = c
->conf
->daemon_binary
;
691 argv
[n
++] = "--start";
693 while (n
< MAX_ARGS
) {
696 if (!(a
= pa_split_spaces(c
->conf
->extra_arguments
, &state
)))
704 execv(argv
[0], (char * const *) argv
);
711 if (c
->spawn_api
.postfork
)
712 c
->spawn_api
.postfork();
715 r
= waitpid(pid
, &status
, 0);
716 } while (r
< 0 && errno
== EINTR
);
719 pa_log(_("waitpid(): %s"), pa_cstrerror(errno
));
720 pa_context_fail(c
, PA_ERR_INTERNAL
);
722 } else if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
723 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
738 #endif /* OS_IS_WIN32 */
740 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
);
742 static void track_pulseaudio_on_dbus(pa_context
*c
, DBusBusType type
, pa_dbus_wrap_connection
**conn
) {
748 dbus_error_init(&error
);
749 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, type
, &error
)) || dbus_error_is_set(&error
)) {
750 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
754 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
755 pa_log_warn("Failed to add filter function");
759 if (pa_dbus_add_matches(
760 pa_dbus_wrap_connection_get(*conn
), &error
,
761 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio',arg1=''", NULL
) < 0)
762 pa_log_warn("Unable to track org.pulseaudio: %s: %s", error
.name
, error
.message
);
765 dbus_error_free(&error
);
768 static int try_next_connection(pa_context
*c
) {
773 pa_assert(!c
->client
);
779 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
784 if (c
->do_autospawn
) {
786 if ((r
= context_autospawn(c
)) < 0)
789 /* Autospawn only once */
790 c
->do_autospawn
= FALSE
;
792 /* Connect only to per-user sockets this time */
793 c
->server_list
= prepend_per_user(c
->server_list
);
795 /* Retry connection */
802 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
804 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
806 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
811 pa_log_debug("Trying to connect to %s...", u
);
814 c
->server
= pa_xstrdup(u
);
816 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, u
, PA_NATIVE_DEFAULT_PORT
)))
819 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
820 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
832 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
833 pa_context
*c
= userdata
;
834 int saved_errno
= errno
;
838 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
842 pa_socket_client_unref(client
);
846 /* Try the item in the list */
847 if (saved_errno
== ECONNREFUSED
||
848 saved_errno
== ETIMEDOUT
||
849 saved_errno
== EHOSTUNREACH
) {
850 try_next_connection(c
);
854 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
858 setup_context(c
, io
);
864 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
865 pa_context
*c
= userdata
;
866 pa_bool_t is_session
;
872 if (c
->state
!= PA_CONTEXT_CONNECTING
)
875 is_session
= bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
876 pa_log_debug("Rock!! PulseAudio is baack on %s bus", is_session
? "session" : "system");
879 /* The user instance via PF_LOCAL */
880 c
->server_list
= prepend_per_user(c
->server_list
);
882 /* The system wide instance via PF_LOCAL */
883 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
886 try_next_connection(c
);
889 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
892 int pa_context_connect(
895 pa_context_flags_t flags
,
896 const pa_spawn_api
*api
) {
901 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
903 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
904 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
905 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
906 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
909 server
= c
->conf
->default_server
;
913 c
->no_fail
= flags
& PA_CONTEXT_NOFAIL
;
914 pa_assert(!c
->server_list
);
917 if (!(c
->server_list
= pa_strlist_parse(server
))) {
918 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
925 /* Prepend in reverse order */
927 /* Follow the X display */
928 if ((d
= getenv("DISPLAY"))) {
931 if ((e
= strchr(d
, ':')))
935 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
940 /* Add TCP/IP on the localhost */
941 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
942 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
944 /* The system wide instance via PF_LOCAL */
945 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
947 /* The user instance via PF_LOCAL */
948 c
->server_list
= prepend_per_user(c
->server_list
);
950 /* Set up autospawning */
951 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
954 pa_log_debug("Not doing autospawn since we are root.");
956 c
->do_autospawn
= TRUE
;
964 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
965 r
= try_next_connection(c
);
973 void pa_context_disconnect(pa_context
*c
) {
975 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
977 if (pa_detect_fork())
980 if (PA_CONTEXT_IS_GOOD(c
->state
))
981 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
984 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
986 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
991 int pa_context_errno(pa_context
*c
) {
993 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
998 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1000 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1002 if (pa_detect_fork())
1005 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1008 c
->state_callback
= cb
;
1009 c
->state_userdata
= userdata
;
1012 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1014 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1016 if (pa_detect_fork())
1019 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1022 c
->event_callback
= cb
;
1023 c
->event_userdata
= userdata
;
1026 int pa_context_is_pending(pa_context
*c
) {
1028 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1030 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1031 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1033 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1034 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1038 static void set_dispatch_callbacks(pa_operation
*o
);
1040 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1041 set_dispatch_callbacks(userdata
);
1044 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1045 set_dispatch_callbacks(userdata
);
1048 static void set_dispatch_callbacks(pa_operation
*o
) {
1052 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1053 pa_assert(o
->context
);
1054 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1055 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1057 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1058 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1060 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1061 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1065 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1066 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1072 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1073 cb(o
->context
, o
->userdata
);
1076 pa_operation_done(o
);
1077 pa_operation_unref(o
);
1081 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1085 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1087 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1088 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1089 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1091 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1092 set_dispatch_callbacks(pa_operation_ref(o
));
1097 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1098 pa_operation
*o
= userdata
;
1103 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1108 if (command
!= PA_COMMAND_REPLY
) {
1109 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1113 } else if (!pa_tagstruct_eof(t
)) {
1114 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1119 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1120 cb(o
->context
, success
, o
->userdata
);
1124 pa_operation_done(o
);
1125 pa_operation_unref(o
);
1128 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
) {
1134 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1136 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1137 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1139 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1141 t
= pa_tagstruct_command(c
, command
, &tag
);
1142 pa_pstream_send_tagstruct(c
->pstream
, t
);
1143 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1148 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1150 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1152 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1155 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1161 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1163 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1164 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1166 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1167 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1168 pa_tagstruct_puts(t
, name
);
1169 pa_pstream_send_tagstruct(c
->pstream
, t
);
1170 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
);
1175 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1181 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1183 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1184 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1186 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1187 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1188 pa_tagstruct_puts(t
, name
);
1189 pa_pstream_send_tagstruct(c
->pstream
, t
);
1190 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
);
1195 int pa_context_is_local(pa_context
*c
) {
1197 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1199 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1200 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1202 return !!c
->is_local
;
1205 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1209 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1212 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1213 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1215 if (c
->version
>= 13) {
1216 pa_proplist
*p
= pa_proplist_new();
1218 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1219 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1220 pa_proplist_free(p
);
1225 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1226 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1227 pa_tagstruct_puts(t
, name
);
1228 pa_pstream_send_tagstruct(c
->pstream
, t
);
1229 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
);
1235 const char* pa_get_library_version(void) {
1236 return PACKAGE_VERSION
;
1239 const char* pa_context_get_server(pa_context
*c
) {
1241 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1243 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1244 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1246 if (*c
->server
== '{') {
1247 char *e
= strchr(c
->server
+1, '}');
1248 return e
? e
+1 : c
->server
;
1254 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1255 return PA_PROTOCOL_VERSION
;
1258 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1260 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1262 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1263 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1268 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1274 t
= pa_tagstruct_new(NULL
, 0);
1275 pa_tagstruct_putu32(t
, command
);
1276 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1281 uint32_t pa_context_get_index(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
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1287 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1289 return c
->client_index
;
1292 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
) {
1298 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1300 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1301 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1302 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1303 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1305 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1307 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1308 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1309 pa_tagstruct_put_proplist(t
, p
);
1311 pa_pstream_send_tagstruct(c
->pstream
, t
);
1312 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
);
1314 /* Please note that we don't update c->proplist here, because we
1315 * don't export that field */
1320 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1324 const char * const *k
;
1327 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1329 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1330 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1331 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1332 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1334 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1336 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1338 for (k
= keys
; *k
; k
++)
1339 pa_tagstruct_puts(t
, *k
);
1341 pa_tagstruct_puts(t
, NULL
);
1343 pa_pstream_send_tagstruct(c
->pstream
, t
);
1344 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
);
1346 /* Please note that we don't update c->proplist here, because we
1347 * don't export that field */
1352 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1353 pa_context
*c
= userdata
;
1358 pa_assert(command
== PA_COMMAND_EXTENSION
);
1361 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1365 if (c
->version
< 15) {
1366 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1370 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1371 pa_tagstruct_gets(t
, &name
) < 0) {
1372 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1376 if (!strcmp(name
, "module-stream-restore"))
1377 pa_ext_stream_restore_command(c
, tag
, t
);
1379 pa_log(_("Received message for unknown extension '%s'"), name
);
1382 pa_context_unref(c
);
1386 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1387 pa_context
*c
= userdata
;
1388 pa_proplist
*pl
= NULL
;
1392 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1395 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1399 if (c
->version
< 15) {
1400 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1404 pl
= pa_proplist_new();
1406 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1407 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1408 !pa_tagstruct_eof(t
) || !event
) {
1409 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1413 if (c
->event_callback
)
1414 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1417 pa_context_unref(c
);
1420 pa_proplist_free(pl
);