#include <sys/stat.h>
#include <errno.h>
#include <signal.h>
-#include <limits.h>
-#include <locale.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include <pulse/version.h>
#include <pulse/xmalloc.h>
-#include <pulse/utf8.h>
#include <pulse/util.h>
-#include <pulse/i18n.h>
#include <pulse/mainloop.h>
#include <pulse/timeval.h>
+#include <pulse/fork-detect.h>
+#include <pulse/client-conf.h>
+#ifdef HAVE_X11
+#include <pulse/client-conf-x11.h>
+#endif
-#include <pulsecore/winsock.h>
#include <pulsecore/core-error.h>
-
+#include <pulsecore/i18n.h>
#include <pulsecore/native-common.h>
#include <pulsecore/pdispatch.h>
#include <pulsecore/pstream.h>
-#include <pulsecore/dynarray.h>
+#include <pulsecore/hashmap.h>
#include <pulsecore/socket-client.h>
#include <pulsecore/pstream-util.h>
#include <pulsecore/core-rtclock.h>
#include <pulsecore/core-util.h>
#include <pulsecore/log.h>
-#include <pulsecore/socket-util.h>
+#include <pulsecore/socket.h>
#include <pulsecore/creds.h>
#include <pulsecore/macro.h>
#include <pulsecore/proplist-util.h>
#include "internal.h"
-
-#include "client-conf.h"
-#include "fork-detect.h"
-
-#ifdef HAVE_X11
-#include "client-conf-x11.h"
-#endif
-
#include "context.h"
void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
c->event_callback = NULL;
c->event_userdata = NULL;
+ c->ext_device_manager.callback = NULL;
+ c->ext_device_manager.userdata = NULL;
+
+ c->ext_device_restore.callback = NULL;
+ c->ext_device_restore.userdata = NULL;
+
c->ext_stream_restore.callback = NULL;
c->ext_stream_restore.userdata = NULL;
}
pa_init_i18n();
- c = pa_xnew(pa_context, 1);
+ c = pa_xnew0(pa_context, 1);
PA_REFCNT_INIT(c);
c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
c->system_bus = c->session_bus = NULL;
#endif
c->mainloop = mainloop;
- c->client = NULL;
- c->pstream = NULL;
- c->pdispatch = NULL;
- c->playback_streams = pa_dynarray_new();
- c->record_streams = pa_dynarray_new();
+ c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
c->client_index = PA_INVALID_INDEX;
c->use_rtclock = pa_mainloop_is_our_api(mainloop);
c->error = PA_OK;
c->state = PA_CONTEXT_UNCONNECTED;
- c->ctag = 0;
- c->csyncid = 0;
reset_callbacks(c);
- c->is_local = FALSE;
- c->server_list = NULL;
- c->server = NULL;
-
- c->do_shm = FALSE;
-
- c->server_specified = FALSE;
- c->no_fail = FALSE;
- c->do_autospawn = FALSE;
- memset(&c->spawn_api, 0, sizeof(c->spawn_api));
-
#ifndef MSG_NOSIGNAL
#ifdef SIGPIPE
pa_check_signal_is_blocked(SIGPIPE);
#endif
c->conf = pa_client_conf_new();
- pa_client_conf_load(c->conf, NULL);
+ pa_client_conf_load(c->conf);
#ifdef HAVE_X11
- pa_client_conf_from_x11(c->conf, NULL);
+ pa_client_conf_from_x11(c->conf);
#endif
pa_client_conf_env(c->conf);
if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm, c->conf->shm_size))) {
if (!c->conf->disable_shm)
- c->mempool = pa_mempool_new(FALSE, c->conf->shm_size);
+ c->mempool = pa_mempool_new(false, c->conf->shm_size);
if (!c->mempool) {
context_free(c);
#ifdef HAVE_DBUS
if (c->system_bus) {
- dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->system_bus), filter_cb, c);
+ if (c->filter_added)
+ dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->system_bus), filter_cb, c);
pa_dbus_wrap_connection_free(c->system_bus);
}
if (c->session_bus) {
- dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->session_bus), filter_cb, c);
+ if (c->filter_added)
+ dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->session_bus), filter_cb, c);
pa_dbus_wrap_connection_free(c->session_bus);
}
#endif
if (c->record_streams)
- pa_dynarray_free(c->record_streams, NULL, NULL);
+ pa_hashmap_free(c->record_streams);
if (c->playback_streams)
- pa_dynarray_free(c->playback_streams, NULL, NULL);
+ pa_hashmap_free(c->playback_streams);
if (c->mempool)
pa_mempool_free(c->mempool);
pa_context_ref(c);
- if ((s = pa_dynarray_get(c->record_streams, channel))) {
+ if ((s = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(channel)))) {
if (chunk->memblock) {
- pa_memblockq_seek(s->record_memblockq, offset, seek, TRUE);
+ pa_memblockq_seek(s->record_memblockq, offset, seek, true);
pa_memblockq_push_align(s->record_memblockq, chunk);
} else
- pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek, TRUE);
+ pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek, true);
if (s->read_callback) {
size_t l;
pa_context_unref(c);
}
-int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, pa_bool_t fail) {
+int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, bool fail) {
uint32_t err;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
pa_context_ref(c);
if (command != PA_COMMAND_REPLY) {
- pa_context_handle_error(c, command, t, TRUE);
+ pa_context_handle_error(c, command, t, true);
goto finish;
}
switch(c->state) {
case PA_CONTEXT_AUTHORIZING: {
pa_tagstruct *reply;
- pa_bool_t shm_on_remote = FALSE;
+ bool shm_on_remote = false;
if (pa_tagstruct_getu32(t, &c->version) < 0 ||
!pa_tagstruct_eof(t)) {
/* Enable shared memory support if possible */
if (c->do_shm)
if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
- c->do_shm = FALSE;
+ c->do_shm = false;
if (c->do_shm) {
#ifdef HAVE_CREDS
const pa_creds *creds;
if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
- c->do_shm = FALSE;
+ c->do_shm = false;
#endif
}
}
static void setup_context(pa_context *c, pa_iochannel *io) {
+ uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
pa_tagstruct *t;
uint32_t tag;
c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
- pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
- pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
+ pa_pstream_set_receive_packet_callback(c->pstream, pstream_packet_callback, c);
+ pa_pstream_set_receive_memblock_callback(c->pstream, pstream_memblock_callback, c);
pa_assert(!c->pdispatch);
c->pdispatch = pa_pdispatch_new(c->mainloop, c->use_rtclock, command_table, PA_COMMAND_MAX);
- if (!c->conf->cookie_valid)
+ if (pa_client_conf_load_cookie(c->conf, cookie, sizeof(cookie)) < 0)
pa_log_info(_("No cookie loaded. Attempting to connect without."));
t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
/* Starting with protocol version 13 we use the MSB of the version
* tag for informing the other side if we could do SHM or not */
pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0));
- pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
+ pa_tagstruct_put_arbitrary(t, cookie, sizeof(cookie));
#ifdef HAVE_CREDS
{
pa_context_unref(c);
}
-#ifdef ENABLE_LEGACY_RUNTIME_DIR
-static char *get_old_legacy_runtime_dir(void) {
- char *p, u[128];
- struct stat st;
-
- if (!pa_get_user_name(u, sizeof(u)))
- return NULL;
-
- p = pa_sprintf_malloc("/tmp/pulse-%s", u);
-
- if (stat(p, &st) < 0) {
- pa_xfree(p);
- return NULL;
- }
-
- if (st.st_uid != getuid()) {
- pa_xfree(p);
- return NULL;
- }
-
- return p;
-}
-
-static char *get_very_old_legacy_runtime_dir(void) {
- char *p, h[128];
- struct stat st;
-
- if (!pa_get_home_dir(h, sizeof(h)))
- return NULL;
-
- p = pa_sprintf_malloc("%s/.pulse", h);
-
- if (stat(p, &st) < 0) {
- pa_xfree(p);
- return NULL;
- }
-
- if (st.st_uid != getuid()) {
- pa_xfree(p);
- return NULL;
- }
-
- return p;
-}
-#endif
-
static pa_strlist *prepend_per_user(pa_strlist *l) {
char *ufn;
-#ifdef ENABLE_LEGACY_RUNTIME_DIR
- static char *legacy_dir;
-
- /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
- if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
- char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
- l = pa_strlist_prepend(l, p);
- pa_xfree(p);
- pa_xfree(legacy_dir);
- }
-
- /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
- if ((legacy_dir = get_old_legacy_runtime_dir())) {
- char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
- l = pa_strlist_prepend(l, p);
- pa_xfree(p);
- pa_xfree(legacy_dir);
- }
-#endif
-
/* The per-user instance */
if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
l = pa_strlist_prepend(l, ufn);
goto fail;
}
+#ifdef SA_NOCLDWAIT
if ((sa.sa_flags & SA_NOCLDWAIT) || sa.sa_handler == SIG_IGN) {
+#else
+ if (sa.sa_handler == SIG_IGN) {
+#endif
pa_log_debug("Process disabled waitpid(), cannot autospawn.");
pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
goto fail;
pa_log_warn("Failed to add filter function");
goto fail;
}
+ c->filter_added = true;
if (pa_dbus_add_matches(
pa_dbus_wrap_connection_get(*conn), &error,
goto finish;
/* Autospawn only once */
- c->do_autospawn = FALSE;
+ c->do_autospawn = false;
/* Connect only to per-user sockets this time */
c->server_list = prepend_per_user(c->server_list);
#ifdef HAVE_DBUS
static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) {
pa_context *c = userdata;
- pa_bool_t is_session;
+ bool is_session;
pa_assert(bus);
pa_assert(message);
PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
if (server)
- c->conf->autospawn = FALSE;
+ c->conf->autospawn = false;
else
server = c->conf->default_server;
/* Prepend in reverse order */
/* Follow the X display */
- if ((d = getenv("DISPLAY"))) {
- d = pa_xstrndup(d, strcspn(d, ":"));
+ if (c->conf->auto_connect_display) {
+ if ((d = getenv("DISPLAY"))) {
+ d = pa_xstrndup(d, strcspn(d, ":"));
- if (*d)
- c->server_list = pa_strlist_prepend(c->server_list, d);
+ if (*d)
+ c->server_list = pa_strlist_prepend(c->server_list, d);
- pa_xfree(d);
+ pa_xfree(d);
+ }
}
/* Add TCP/IP on the localhost */
- c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
- c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
+ if (c->conf->auto_connect_localhost) {
+ c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
+ c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
+ }
/* The system wide instance via PF_LOCAL */
c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
/* Set up autospawning */
if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
+#ifdef HAVE_GETUID
if (getuid() == 0)
pa_log_debug("Not doing autospawn since we are root.");
else {
- c->do_autospawn = TRUE;
+ c->do_autospawn = true;
if (api)
c->spawn_api = *api;
}
+#endif
}
pa_context_set_state(c, PA_CONTEXT_CONNECTING);
goto finish;
if (command != PA_COMMAND_REPLY) {
- if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+ if (pa_context_handle_error(o->context, command, t, false) < 0)
goto finish;
success = 0;
}
const char* pa_get_library_version(void) {
- return PACKAGE_VERSION;
+ return pa_get_headers_version();
}
const char* pa_context_get_server(pa_context *c) {
goto finish;
}
- if (!strcmp(name, "module-stream-restore"))
+ if (pa_streq(name, "module-device-manager"))
+ pa_ext_device_manager_command(c, tag, t);
+ else if (pa_streq(name, "module-device-restore"))
+ pa_ext_device_restore_command(c, tag, t);
+ else if (pa_streq(name, "module-stream-restore"))
pa_ext_stream_restore_command(c, tag, t);
else
pa_log(_("Received message for unknown extension '%s'"), name);
pa_context_unref(c);
}
-
void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_proplist *pl = NULL;
struct timeval tv;
pa_assert(c);
+ pa_assert(PA_REFCNT_VALUE(c) >= 1);
pa_assert(c->mainloop);
if (usec == PA_USEC_INVALID)
struct timeval tv;
pa_assert(c);
+ pa_assert(PA_REFCNT_VALUE(c) >= 1);
pa_assert(c->mainloop);
if (usec == PA_USEC_INVALID)
c->mainloop->time_restart(e, &tv);
}
}
+
+size_t pa_context_get_tile_size(pa_context *c, const pa_sample_spec *ss) {
+ size_t fs, mbs;
+
+ pa_assert(c);
+ pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+ PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, (size_t) -1);
+ PA_CHECK_VALIDITY_RETURN_ANY(c, !ss || pa_sample_spec_valid(ss), PA_ERR_INVALID, (size_t) -1);
+
+ fs = ss ? pa_frame_size(ss) : 1;
+ mbs = PA_ROUND_DOWN(pa_mempool_block_size_max(c->mempool), fs);
+ return PA_MAX(mbs, fs);
+}
+
+int pa_context_load_cookie_from_file(pa_context *c, const char *cookie_file_path) {
+ pa_assert(c);
+ pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+ PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
+ PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
+ PA_CHECK_VALIDITY(c, !cookie_file_path || *cookie_file_path, PA_ERR_INVALID);
+
+ pa_client_conf_set_cookie_file_from_application(c->conf, cookie_file_path);
+
+ return 0;
+}