#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
-#include <sys/wait.h>
#include <signal.h>
+#include <limits.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include "winsock.h"
#include "polyplib-internal.h"
#include "polyplib-context.h"
#define AUTOSPAWN_LOCK "autospawn.lock"
-
-
static const struct pa_pdispatch_command command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_REQUEST] = { pa_command_request },
[PA_COMMAND_PLAYBACK_STREAM_KILLED] = { pa_command_stream_killed },
assert(c);
if (c->autospawn_lock_fd >= 0) {
- pa_unlock_lockfile(c->autospawn_lock_fd);
+ char lf[PATH_MAX];
+ pa_runtime_path(AUTOSPAWN_LOCK, lf, sizeof(lf));
+
+ pa_unlock_lockfile(lf, c->autospawn_lock_fd);
c->autospawn_lock_fd = -1;
}
-
}
struct pa_context *pa_context_new(struct pa_mainloop_api *mainloop, const char *name) {
c->memblock_stat = pa_memblock_stat_new();
c->local = -1;
c->server_list = NULL;
+ c->server = NULL;
c->autospawn_lock_fd = -1;
memset(&c->spawn_api, 0, sizeof(c->spawn_api));
c->do_autospawn = 0;
-
+
+#ifdef SIGPIPE
pa_check_signal_is_blocked(SIGPIPE);
+#endif
c->conf = pa_client_conf_new();
pa_client_conf_load(c->conf, NULL);
pa_strlist_free(c->server_list);
pa_xfree(c->name);
+ pa_xfree(c->server);
pa_xfree(c);
}
pa_context_ref(c);
if ((s = pa_dynarray_get(c->record_streams, channel))) {
- if (s->read_callback) {
- s->read_callback(s, (uint8_t*) chunk->memblock->data + chunk->index, chunk->length, s->read_userdata);
- s->counter += chunk->length;
+ pa_mcalign_push(s->mcalign, chunk);
+
+ for (;;) {
+ struct pa_memchunk t;
+
+ if (pa_mcalign_pop(s->mcalign, &t) < 0)
+ break;
+
+ if (s->read_callback) {
+ s->read_callback(s, (uint8_t*) t.memblock->data + t.index, t.length, s->read_userdata);
+ s->counter += chunk->length;
+ }
+
+ pa_memblock_unref(t.memblock);
}
}
static void on_connection(struct pa_socket_client *client, struct pa_iochannel*io, void *userdata);
+#ifndef OS_IS_WIN32
+
static int context_connect_spawn(struct pa_context *c) {
pid_t pid;
int status, r;
return -1;
}
+#endif /* OS_IS_WIN32 */
+
static int try_next_connection(struct pa_context *c) {
char *u = NULL;
int r = -1;
if (!u) {
+#ifndef OS_IS_WIN32
if (c->do_autospawn) {
r = context_connect_spawn(c);
goto finish;
}
+#endif
pa_context_fail(c, PA_ERROR_CONNECTIONREFUSED);
goto finish;
}
-/* pa_log(__FILE__": Trying to connect to %s...\n", u); */
-
+ pa_log_debug(__FILE__": Trying to connect to %s...\n", u);
+
+ pa_xfree(c->server);
+ c->server = pa_xstrdup(u);
+
if (!(c->client = pa_socket_client_new_string(c->mainloop, u, PA_NATIVE_DEFAULT_PORT)))
continue;
assert(client && c && c->state == PA_CONTEXT_CONNECTING);
pa_context_ref(c);
-
+
pa_socket_client_unref(client);
c->client = NULL;
if (!server)
server = c->conf->default_server;
-
pa_context_ref(c);
assert(!c->server_list);
/* Prepend in reverse order */
- if ((d = getenv("DISPLAY")))
- c->server_list = pa_strlist_prepend(c->server_list, d);
+ if ((d = getenv("DISPLAY"))) {
+ char *e;
+ d = pa_xstrdup(d);
+ if ((e = strchr(d, ':')))
+ *e = 0;
+
+ if (*d)
+ c->server_list = pa_strlist_prepend(c->server_list, d);
+
+ pa_xfree(d);
+ }
c->server_list = pa_strlist_prepend(c->server_list, "tcp6:localhost");
c->server_list = pa_strlist_prepend(c->server_list, "localhost");
c->server_list = pa_strlist_prepend(c->server_list, pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET, ufn, sizeof(ufn)));
- /* Wrap the connection attempts in a single transaction for sane autospwan locking */
+ /* Wrap the connection attempts in a single transaction for sane autospawn locking */
if (spawn && c->conf->autospawn) {
char lf[PATH_MAX];
pa_runtime_path(AUTOSPAWN_LOCK, lf, sizeof(lf));
+ pa_make_secure_parent_dir(lf);
assert(c->autospawn_lock_fd <= 0);
c->autospawn_lock_fd = pa_lock_lockfile(lf);
/* pa_log("pstream: %i\n", pa_pstream_is_pending(c->pstream)); */
/* pa_log("pdispatch: %i\n", pa_pdispatch_is_pending(c->pdispatch)); */
- return (c->pstream && pa_pstream_is_pending(c->pstream)) || (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) || c->client;
+ return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
+ (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
+ c->client;
}
static void set_dispatch_callbacks(struct pa_operation *o);
return PACKAGE_VERSION;
}
+const char* pa_context_get_server(struct pa_context *c) {
+
+ if (!c->server)
+ return NULL;
+
+ if (*c->server == '{') {
+ char *e = strchr(c->server+1, '}');
+ return e ? e+1 : c->server;
+ }
+
+ return c->server;
+}