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>
57 #include <pulse/mainloop.h>
58 #include <pulse/timeval.h>
60 #include <pulsecore/winsock.h>
61 #include <pulsecore/core-error.h>
63 #include <pulsecore/native-common.h>
64 #include <pulsecore/pdispatch.h>
65 #include <pulsecore/pstream.h>
66 #include <pulsecore/dynarray.h>
67 #include <pulsecore/socket-client.h>
68 #include <pulsecore/pstream-util.h>
69 #include <pulsecore/core-rtclock.h>
70 #include <pulsecore/core-util.h>
71 #include <pulsecore/log.h>
72 #include <pulsecore/socket-util.h>
73 #include <pulsecore/creds.h>
74 #include <pulsecore/macro.h>
75 #include <pulsecore/proplist-util.h>
79 #include "client-conf.h"
80 #include "fork-detect.h"
83 #include "client-conf-x11.h"
88 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
90 static const pa_pdispatch_cb_t command_table
[PA_COMMAND_MAX
] = {
91 [PA_COMMAND_REQUEST
] = pa_command_request
,
92 [PA_COMMAND_OVERFLOW
] = pa_command_overflow_or_underflow
,
93 [PA_COMMAND_UNDERFLOW
] = pa_command_overflow_or_underflow
,
94 [PA_COMMAND_PLAYBACK_STREAM_KILLED
] = pa_command_stream_killed
,
95 [PA_COMMAND_RECORD_STREAM_KILLED
] = pa_command_stream_killed
,
96 [PA_COMMAND_PLAYBACK_STREAM_MOVED
] = pa_command_stream_moved
,
97 [PA_COMMAND_RECORD_STREAM_MOVED
] = pa_command_stream_moved
,
98 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
] = pa_command_stream_suspended
,
99 [PA_COMMAND_RECORD_STREAM_SUSPENDED
] = pa_command_stream_suspended
,
100 [PA_COMMAND_STARTED
] = pa_command_stream_started
,
101 [PA_COMMAND_SUBSCRIBE_EVENT
] = pa_command_subscribe_event
,
102 [PA_COMMAND_EXTENSION
] = pa_command_extension
,
103 [PA_COMMAND_PLAYBACK_STREAM_EVENT
] = pa_command_stream_event
,
104 [PA_COMMAND_RECORD_STREAM_EVENT
] = pa_command_stream_event
,
105 [PA_COMMAND_CLIENT_EVENT
] = pa_command_client_event
,
106 [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
,
107 [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
109 static void context_free(pa_context
*c
);
112 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
);
115 pa_context
*pa_context_new(pa_mainloop_api
*mainloop
, const char *name
) {
116 return pa_context_new_with_proplist(mainloop
, name
, NULL
);
119 static void reset_callbacks(pa_context
*c
) {
122 c
->state_callback
= NULL
;
123 c
->state_userdata
= NULL
;
125 c
->subscribe_callback
= NULL
;
126 c
->subscribe_userdata
= NULL
;
128 c
->event_callback
= NULL
;
129 c
->event_userdata
= NULL
;
131 c
->ext_stream_restore
.callback
= NULL
;
132 c
->ext_stream_restore
.userdata
= NULL
;
135 pa_context
*pa_context_new_with_proplist(pa_mainloop_api
*mainloop
, const char *name
, pa_proplist
*p
) {
140 if (pa_detect_fork())
145 c
= pa_xnew(pa_context
, 1);
148 c
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
151 pa_proplist_sets(c
->proplist
, PA_PROP_APPLICATION_NAME
, name
);
154 c
->system_bus
= c
->session_bus
= NULL
;
156 c
->mainloop
= mainloop
;
160 c
->playback_streams
= pa_dynarray_new();
161 c
->record_streams
= pa_dynarray_new();
162 c
->client_index
= PA_INVALID_INDEX
;
164 PA_LLIST_HEAD_INIT(pa_stream
, c
->streams
);
165 PA_LLIST_HEAD_INIT(pa_operation
, c
->operations
);
168 c
->state
= PA_CONTEXT_UNCONNECTED
;
175 c
->server_list
= NULL
;
180 c
->server_specified
= FALSE
;
182 c
->do_autospawn
= FALSE
;
183 memset(&c
->spawn_api
, 0, sizeof(c
->spawn_api
));
187 pa_check_signal_is_blocked(SIGPIPE
);
191 c
->conf
= pa_client_conf_new();
192 pa_client_conf_load(c
->conf
, NULL
);
194 pa_client_conf_from_x11(c
->conf
, NULL
);
196 pa_client_conf_env(c
->conf
);
198 if (!(c
->mempool
= pa_mempool_new(!c
->conf
->disable_shm
, c
->conf
->shm_size
))) {
200 if (!c
->conf
->disable_shm
)
201 c
->mempool
= pa_mempool_new(FALSE
, c
->conf
->shm_size
);
212 static void context_unlink(pa_context
*c
) {
217 s
= c
->streams
? pa_stream_ref(c
->streams
) : NULL
;
219 pa_stream
*n
= s
->next
? pa_stream_ref(s
->next
) : NULL
;
220 pa_stream_set_state(s
, c
->state
== PA_CONTEXT_FAILED
? PA_STREAM_FAILED
: PA_STREAM_TERMINATED
);
225 while (c
->operations
)
226 pa_operation_cancel(c
->operations
);
229 pa_pdispatch_unref(c
->pdispatch
);
234 pa_pstream_unlink(c
->pstream
);
235 pa_pstream_unref(c
->pstream
);
240 pa_socket_client_unref(c
->client
);
247 static void context_free(pa_context
*c
) {
254 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->system_bus
), filter_cb
, c
);
255 pa_dbus_wrap_connection_free(c
->system_bus
);
258 if (c
->session_bus
) {
259 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->session_bus
), filter_cb
, c
);
260 pa_dbus_wrap_connection_free(c
->session_bus
);
264 if (c
->record_streams
)
265 pa_dynarray_free(c
->record_streams
, NULL
, NULL
);
266 if (c
->playback_streams
)
267 pa_dynarray_free(c
->playback_streams
, NULL
, NULL
);
270 pa_mempool_free(c
->mempool
);
273 pa_client_conf_free(c
->conf
);
275 pa_strlist_free(c
->server_list
);
278 pa_proplist_free(c
->proplist
);
284 pa_context
* pa_context_ref(pa_context
*c
) {
286 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
292 void pa_context_unref(pa_context
*c
) {
294 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
296 if (PA_REFCNT_DEC(c
) <= 0)
300 void pa_context_set_state(pa_context
*c
, pa_context_state_t st
) {
302 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
311 if (c
->state_callback
)
312 c
->state_callback(c
, c
->state_userdata
);
314 if (st
== PA_CONTEXT_FAILED
|| st
== PA_CONTEXT_TERMINATED
)
320 int pa_context_set_error(pa_context
*c
, int error
) {
321 pa_assert(error
>= 0);
322 pa_assert(error
< PA_ERR_MAX
);
330 void pa_context_fail(pa_context
*c
, int error
) {
332 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
334 pa_context_set_error(c
, error
);
335 pa_context_set_state(c
, PA_CONTEXT_FAILED
);
338 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
339 pa_context
*c
= userdata
;
344 pa_context_fail(c
, PA_ERR_CONNECTIONTERMINATED
);
347 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
348 pa_context
*c
= userdata
;
356 if (pa_pdispatch_run(c
->pdispatch
, packet
, creds
, c
) < 0)
357 pa_context_fail(c
, PA_ERR_PROTOCOL
);
362 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
) {
363 pa_context
*c
= userdata
;
368 pa_assert(chunk
->length
> 0);
370 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
374 if ((s
= pa_dynarray_get(c
->record_streams
, channel
))) {
376 if (chunk
->memblock
) {
377 pa_memblockq_seek(s
->record_memblockq
, offset
, seek
, TRUE
);
378 pa_memblockq_push_align(s
->record_memblockq
, chunk
);
380 pa_memblockq_seek(s
->record_memblockq
, offset
+chunk
->length
, seek
, TRUE
);
382 if (s
->read_callback
) {
385 if ((l
= pa_memblockq_get_length(s
->record_memblockq
)) > 0)
386 s
->read_callback(s
, l
, s
->read_userdata
);
393 int pa_context_handle_error(pa_context
*c
, uint32_t command
, pa_tagstruct
*t
, pa_bool_t fail
) {
396 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
398 if (command
== PA_COMMAND_ERROR
) {
401 if (pa_tagstruct_getu32(t
, &err
) < 0 ||
402 !pa_tagstruct_eof(t
)) {
403 pa_context_fail(c
, PA_ERR_PROTOCOL
);
407 } else if (command
== PA_COMMAND_TIMEOUT
)
408 err
= PA_ERR_TIMEOUT
;
410 pa_context_fail(c
, PA_ERR_PROTOCOL
);
415 pa_context_fail(c
, PA_ERR_PROTOCOL
);
419 if (err
>= PA_ERR_MAX
)
420 err
= PA_ERR_UNKNOWN
;
423 pa_context_fail(c
, (int) err
);
427 pa_context_set_error(c
, (int) err
);
432 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
433 pa_context
*c
= userdata
;
437 pa_assert(c
->state
== PA_CONTEXT_AUTHORIZING
|| c
->state
== PA_CONTEXT_SETTING_NAME
);
441 if (command
!= PA_COMMAND_REPLY
) {
442 pa_context_handle_error(c
, command
, t
, TRUE
);
447 case PA_CONTEXT_AUTHORIZING
: {
449 pa_bool_t shm_on_remote
= FALSE
;
451 if (pa_tagstruct_getu32(t
, &c
->version
) < 0 ||
452 !pa_tagstruct_eof(t
)) {
453 pa_context_fail(c
, PA_ERR_PROTOCOL
);
457 /* Minimum supported version */
458 if (c
->version
< 8) {
459 pa_context_fail(c
, PA_ERR_VERSION
);
463 /* Starting with protocol version 13 the MSB of the version
464 tag reflects if shm is available for this connection or
466 if (c
->version
>= 13) {
467 shm_on_remote
= !!(c
->version
& 0x80000000U
);
468 c
->version
&= 0x7FFFFFFFU
;
471 pa_log_debug("Protocol version: remote %u, local %u", c
->version
, PA_PROTOCOL_VERSION
);
473 /* Enable shared memory support if possible */
475 if (c
->version
< 10 || (c
->version
>= 13 && !shm_on_remote
))
480 /* Only enable SHM if both sides are owned by the same
481 * user. This is a security measure because otherwise
482 * data private to the user might leak. */
485 const pa_creds
*creds
;
486 if (!(creds
= pa_pdispatch_creds(pd
)) || getuid() != creds
->uid
)
491 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c
->do_shm
));
492 pa_pstream_enable_shm(c
->pstream
, c
->do_shm
);
494 reply
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
496 if (c
->version
>= 13) {
497 pa_init_proplist(c
->proplist
);
498 pa_tagstruct_put_proplist(reply
, c
->proplist
);
500 pa_tagstruct_puts(reply
, pa_proplist_gets(c
->proplist
, PA_PROP_APPLICATION_NAME
));
502 pa_pstream_send_tagstruct(c
->pstream
, reply
);
503 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
505 pa_context_set_state(c
, PA_CONTEXT_SETTING_NAME
);
509 case PA_CONTEXT_SETTING_NAME
:
511 if ((c
->version
>= 13 && (pa_tagstruct_getu32(t
, &c
->client_index
) < 0 ||
512 c
->client_index
== PA_INVALID_INDEX
)) ||
513 !pa_tagstruct_eof(t
)) {
514 pa_context_fail(c
, PA_ERR_PROTOCOL
);
518 pa_context_set_state(c
, PA_CONTEXT_READY
);
522 pa_assert_not_reached();
529 static void setup_context(pa_context
*c
, pa_iochannel
*io
) {
538 pa_assert(!c
->pstream
);
539 c
->pstream
= pa_pstream_new(c
->mainloop
, io
, c
->mempool
);
541 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
542 pa_pstream_set_recieve_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
543 pa_pstream_set_recieve_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
545 pa_assert(!c
->pdispatch
);
546 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, c
->use_rtclock
, command_table
, PA_COMMAND_MAX
);
548 if (!c
->conf
->cookie_valid
)
549 pa_log_info(_("No cookie loaded. Attempting to connect without."));
551 t
= pa_tagstruct_command(c
, PA_COMMAND_AUTH
, &tag
);
554 pa_mempool_is_shared(c
->mempool
) &&
557 pa_log_debug("SHM possible: %s", pa_yes_no(c
->do_shm
));
559 /* Starting with protocol version 13 we use the MSB of the version
560 * tag for informing the other side if we could do SHM or not */
561 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
| (c
->do_shm
? 0x80000000U
: 0));
562 pa_tagstruct_put_arbitrary(t
, c
->conf
->cookie
, sizeof(c
->conf
->cookie
));
568 if (pa_iochannel_creds_supported(io
))
569 pa_iochannel_creds_enable(io
);
571 ucred
.uid
= getuid();
572 ucred
.gid
= getgid();
574 pa_pstream_send_tagstruct_with_creds(c
->pstream
, t
, &ucred
);
577 pa_pstream_send_tagstruct(c
->pstream
, t
);
580 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
582 pa_context_set_state(c
, PA_CONTEXT_AUTHORIZING
);
587 #ifdef ENABLE_LEGACY_RUNTIME_DIR
588 static char *get_old_legacy_runtime_dir(void) {
592 if (!pa_get_user_name(u
, sizeof(u
)))
595 p
= pa_sprintf_malloc("/tmp/pulse-%s", u
);
597 if (stat(p
, &st
) < 0) {
602 if (st
.st_uid
!= getuid()) {
610 static char *get_very_old_legacy_runtime_dir(void) {
614 if (!pa_get_home_dir(h
, sizeof(h
)))
617 p
= pa_sprintf_malloc("%s/.pulse", h
);
619 if (stat(p
, &st
) < 0) {
624 if (st
.st_uid
!= getuid()) {
633 static pa_strlist
*prepend_per_user(pa_strlist
*l
) {
636 #ifdef ENABLE_LEGACY_RUNTIME_DIR
637 static char *legacy_dir
;
639 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
640 if ((legacy_dir
= get_very_old_legacy_runtime_dir())) {
641 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
642 l
= pa_strlist_prepend(l
, p
);
644 pa_xfree(legacy_dir
);
647 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
648 if ((legacy_dir
= get_old_legacy_runtime_dir())) {
649 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
650 l
= pa_strlist_prepend(l
, p
);
652 pa_xfree(legacy_dir
);
656 /* The per-user instance */
657 if ((ufn
= pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET
))) {
658 l
= pa_strlist_prepend(l
, ufn
);
667 static int context_autospawn(pa_context
*c
) {
671 pa_log_debug("Trying to autospawn...");
675 if (c
->spawn_api
.prefork
)
676 c
->spawn_api
.prefork();
678 if ((pid
= fork()) < 0) {
679 pa_log_error(_("fork(): %s"), pa_cstrerror(errno
));
680 pa_context_fail(c
, PA_ERR_INTERNAL
);
682 if (c
->spawn_api
.postfork
)
683 c
->spawn_api
.postfork();
689 const char *state
= NULL
;
691 const char * argv
[MAX_ARGS
+1];
694 if (c
->spawn_api
.atfork
)
695 c
->spawn_api
.atfork();
703 argv
[n
++] = c
->conf
->daemon_binary
;
704 argv
[n
++] = "--start";
706 while (n
< MAX_ARGS
) {
709 if (!(a
= pa_split_spaces(c
->conf
->extra_arguments
, &state
)))
717 execv(argv
[0], (char * const *) argv
);
724 if (c
->spawn_api
.postfork
)
725 c
->spawn_api
.postfork();
728 r
= waitpid(pid
, &status
, 0);
729 } while (r
< 0 && errno
== EINTR
);
732 pa_log(_("waitpid(): %s"), pa_cstrerror(errno
));
733 pa_context_fail(c
, PA_ERR_INTERNAL
);
735 } else if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
736 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
751 #endif /* OS_IS_WIN32 */
753 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
);
756 static void track_pulseaudio_on_dbus(pa_context
*c
, DBusBusType type
, pa_dbus_wrap_connection
**conn
) {
762 dbus_error_init(&error
);
763 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, c
->use_rtclock
, type
, &error
)) || dbus_error_is_set(&error
)) {
764 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
768 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
769 pa_log_warn("Failed to add filter function");
773 if (pa_dbus_add_matches(
774 pa_dbus_wrap_connection_get(*conn
), &error
,
775 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL
) < 0)
776 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
779 dbus_error_free(&error
);
783 static int try_next_connection(pa_context
*c
) {
788 pa_assert(!c
->client
);
794 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
799 if (c
->do_autospawn
) {
801 if ((r
= context_autospawn(c
)) < 0)
804 /* Autospawn only once */
805 c
->do_autospawn
= FALSE
;
807 /* Connect only to per-user sockets this time */
808 c
->server_list
= prepend_per_user(c
->server_list
);
810 /* Retry connection */
816 if (c
->no_fail
&& !c
->server_specified
) {
818 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
820 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
823 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
828 pa_log_debug("Trying to connect to %s...", u
);
831 c
->server
= pa_xstrdup(u
);
833 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, c
->use_rtclock
, u
, PA_NATIVE_DEFAULT_PORT
)))
836 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
837 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
849 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
850 pa_context
*c
= userdata
;
851 int saved_errno
= errno
;
855 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
859 pa_socket_client_unref(client
);
863 /* Try the item in the list */
864 if (saved_errno
== ECONNREFUSED
||
865 saved_errno
== ETIMEDOUT
||
866 saved_errno
== EHOSTUNREACH
) {
867 try_next_connection(c
);
871 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
875 setup_context(c
, io
);
882 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
883 pa_context
*c
= userdata
;
884 pa_bool_t is_session
;
890 if (c
->state
!= PA_CONTEXT_CONNECTING
)
896 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
898 is_session
= c
->session_bus
&& bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
899 pa_log_debug("Rock!! PulseAudio is back on %s bus", is_session
? "session" : "system");
902 /* The user instance via PF_LOCAL */
903 c
->server_list
= prepend_per_user(c
->server_list
);
905 /* The system wide instance via PF_LOCAL */
906 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
909 try_next_connection(c
);
912 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
916 int pa_context_connect(
919 pa_context_flags_t flags
,
920 const pa_spawn_api
*api
) {
925 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
927 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
928 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
929 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
930 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
933 c
->conf
->autospawn
= FALSE
;
935 server
= c
->conf
->default_server
;
939 c
->no_fail
= flags
& PA_CONTEXT_NOFAIL
;
940 c
->server_specified
= !!server
;
941 pa_assert(!c
->server_list
);
944 if (!(c
->server_list
= pa_strlist_parse(server
))) {
945 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
952 /* Prepend in reverse order */
954 /* Follow the X display */
955 if ((d
= getenv("DISPLAY"))) {
958 if ((e
= strchr(d
, ':')))
962 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
967 /* Add TCP/IP on the localhost */
968 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
969 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
971 /* The system wide instance via PF_LOCAL */
972 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
974 /* The user instance via PF_LOCAL */
975 c
->server_list
= prepend_per_user(c
->server_list
);
978 /* Set up autospawning */
979 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
982 pa_log_debug("Not doing autospawn since we are root.");
984 c
->do_autospawn
= TRUE
;
991 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
992 r
= try_next_connection(c
);
1000 void pa_context_disconnect(pa_context
*c
) {
1002 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1004 if (pa_detect_fork())
1007 if (PA_CONTEXT_IS_GOOD(c
->state
))
1008 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
1011 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
1013 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1018 int pa_context_errno(pa_context
*c
) {
1020 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1025 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1027 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1029 if (pa_detect_fork())
1032 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1035 c
->state_callback
= cb
;
1036 c
->state_userdata
= userdata
;
1039 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1041 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1043 if (pa_detect_fork())
1046 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1049 c
->event_callback
= cb
;
1050 c
->event_userdata
= userdata
;
1053 int pa_context_is_pending(pa_context
*c
) {
1055 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1057 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1058 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1060 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1061 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1065 static void set_dispatch_callbacks(pa_operation
*o
);
1067 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1068 set_dispatch_callbacks(userdata
);
1071 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1072 set_dispatch_callbacks(userdata
);
1075 static void set_dispatch_callbacks(pa_operation
*o
) {
1079 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1080 pa_assert(o
->context
);
1081 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1082 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1084 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1085 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1087 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1088 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1092 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1093 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1099 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1100 cb(o
->context
, o
->userdata
);
1103 pa_operation_done(o
);
1104 pa_operation_unref(o
);
1108 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1112 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1114 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1115 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1116 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1118 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1119 set_dispatch_callbacks(pa_operation_ref(o
));
1124 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1125 pa_operation
*o
= userdata
;
1130 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1135 if (command
!= PA_COMMAND_REPLY
) {
1136 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1140 } else if (!pa_tagstruct_eof(t
)) {
1141 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1146 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1147 cb(o
->context
, success
, o
->userdata
);
1151 pa_operation_done(o
);
1152 pa_operation_unref(o
);
1155 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
) {
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
, cb
, userdata
);
1168 t
= pa_tagstruct_command(c
, command
, &tag
);
1169 pa_pstream_send_tagstruct(c
->pstream
, t
);
1170 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1175 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1177 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1179 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1182 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1188 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1190 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1191 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1193 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1194 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1195 pa_tagstruct_puts(t
, name
);
1196 pa_pstream_send_tagstruct(c
->pstream
, t
);
1197 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
);
1202 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1208 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1210 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1211 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1213 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1214 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1215 pa_tagstruct_puts(t
, name
);
1216 pa_pstream_send_tagstruct(c
->pstream
, t
);
1217 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
);
1222 int pa_context_is_local(pa_context
*c
) {
1224 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1226 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1227 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1229 return !!c
->is_local
;
1232 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1236 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1239 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1240 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1242 if (c
->version
>= 13) {
1243 pa_proplist
*p
= pa_proplist_new();
1245 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1246 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1247 pa_proplist_free(p
);
1252 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1253 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1254 pa_tagstruct_puts(t
, name
);
1255 pa_pstream_send_tagstruct(c
->pstream
, t
);
1256 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
);
1262 const char* pa_get_library_version(void) {
1263 return PACKAGE_VERSION
;
1266 const char* pa_context_get_server(pa_context
*c
) {
1268 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1270 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1271 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1273 if (*c
->server
== '{') {
1274 char *e
= strchr(c
->server
+1, '}');
1275 return e
? e
+1 : c
->server
;
1281 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1282 return PA_PROTOCOL_VERSION
;
1285 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1287 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1289 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1290 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1295 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1301 t
= pa_tagstruct_new(NULL
, 0);
1302 pa_tagstruct_putu32(t
, command
);
1303 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1308 uint32_t pa_context_get_index(pa_context
*c
) {
1310 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1312 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1313 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1314 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1316 return c
->client_index
;
1319 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
) {
1325 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1327 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1328 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1329 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1330 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1332 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1334 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1335 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1336 pa_tagstruct_put_proplist(t
, p
);
1338 pa_pstream_send_tagstruct(c
->pstream
, t
);
1339 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
);
1341 /* Please note that we don't update c->proplist here, because we
1342 * don't export that field */
1347 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1351 const char * const *k
;
1354 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1356 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1357 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1358 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1359 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1361 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1363 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1365 for (k
= keys
; *k
; k
++)
1366 pa_tagstruct_puts(t
, *k
);
1368 pa_tagstruct_puts(t
, NULL
);
1370 pa_pstream_send_tagstruct(c
->pstream
, t
);
1371 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
);
1373 /* Please note that we don't update c->proplist here, because we
1374 * don't export that field */
1379 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1380 pa_context
*c
= userdata
;
1385 pa_assert(command
== PA_COMMAND_EXTENSION
);
1388 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1392 if (c
->version
< 15) {
1393 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1397 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1398 pa_tagstruct_gets(t
, &name
) < 0) {
1399 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1403 if (!strcmp(name
, "module-stream-restore"))
1404 pa_ext_stream_restore_command(c
, tag
, t
);
1406 pa_log(_("Received message for unknown extension '%s'"), name
);
1409 pa_context_unref(c
);
1413 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1414 pa_context
*c
= userdata
;
1415 pa_proplist
*pl
= NULL
;
1419 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1422 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1426 if (c
->version
< 15) {
1427 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1431 pl
= pa_proplist_new();
1433 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1434 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1435 !pa_tagstruct_eof(t
) || !event
) {
1436 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1440 if (c
->event_callback
)
1441 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1444 pa_context_unref(c
);
1447 pa_proplist_free(pl
);
1450 pa_time_event
* pa_context_rttime_new(pa_context
*c
, pa_usec_t usec
, pa_time_event_cb_t cb
, void *userdata
) {
1454 pa_assert(c
->mainloop
);
1456 if (usec
== PA_USEC_INVALID
)
1457 return c
->mainloop
->time_new(c
->mainloop
, NULL
, cb
, userdata
);
1459 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1461 return c
->mainloop
->time_new(c
->mainloop
, &tv
, cb
, userdata
);
1464 void pa_context_rttime_restart(pa_context
*c
, pa_time_event
*e
, pa_usec_t usec
) {
1468 pa_assert(c
->mainloop
);
1470 if (usec
== PA_USEC_INVALID
)
1471 c
->mainloop
->time_restart(e
, NULL
);
1473 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1474 c
->mainloop
->time_restart(e
, &tv
);