treewide: add error checking to spa_json_builder_close

There could have been a write error or allocation error while building
the json file that we can detect in spa_json_builder_close().

Error out instead of silently using a truncated JSON.

Use spa_autofree for the memory to make cleanup easier.
This commit is contained in:
Wim Taymans 2026-05-13 18:14:44 +02:00
parent 6d1c242433
commit 4f975d0071
41 changed files with 240 additions and 194 deletions

View file

@ -17,6 +17,7 @@
#include <spa/utils/defs.h>
#include <spa/utils/ansi.h>
#include <spa/utils/json.h>
#include <spa/utils/cleanup.h>
#ifdef __cplusplus
extern "C" {
@ -108,10 +109,16 @@ SPA_API_JSON_BUILDER int spa_json_builder_membuf(struct spa_json_builder *b,
return spa_json_builder_file(b, f, flags | SPA_JSON_BUILDER_FLAG_CLOSE);
}
SPA_API_JSON_BUILDER void spa_json_builder_close(struct spa_json_builder *b)
SPA_API_JSON_BUILDER int spa_json_builder_close(struct spa_json_builder *b)
{
if (b->flags & SPA_JSON_BUILDER_FLAG_CLOSE)
fclose(b->f);
int res = 0;
if (b->flags & SPA_JSON_BUILDER_FLAG_CLOSE) {
if (ferror(b->f))
res = -EIO;
if (fclose(b->f) != 0 && res == 0)
res = -errno;
}
return res;
}
SPA_API_JSON_BUILDER int spa_json_builder_encode_string(struct spa_json_builder *b,
@ -422,16 +429,18 @@ void spa_json_builder_array_valuef(struct spa_json_builder *b, bool recurse, con
SPA_API_JSON_BUILDER char *spa_json_builder_reformat(const char *json, uint32_t flags)
{
struct spa_json_builder b;
char *mem;
spa_autofree char *mem = NULL;
size_t size;
int res;
if ((res = spa_json_builder_memstream(&b, &mem, &size, flags)) < 0) {
errno = -res;
return NULL;
}
if ((res = spa_json_builder_memstream(&b, &mem, &size, flags)) < 0)
goto error;
spa_json_builder_array_value(&b, true, json);
spa_json_builder_close(&b);
return mem;
if ((res = spa_json_builder_close(&b)) < 0)
goto error;
return spa_steal_ptr(mem);
error:
errno = -res;
return NULL;
}
/**

View file

@ -4,6 +4,7 @@
#include <unistd.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -299,7 +300,7 @@ static int load_state(struct maap *maap)
static int save_state(struct maap *maap)
{
struct spa_json_builder b;
char *ptr;
spa_autofree char *ptr = NULL;
size_t size;
char key[512];
uint32_t count;
@ -317,10 +318,10 @@ static int save_state(struct maap *maap)
spa_json_builder_object_uint(&b, "count", maap->count);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "]");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
count = pw_properties_set(maap->props, "maap.addresses", ptr);
free(ptr);
if (count > 0) {
snprintf(key, sizeof(key), "maap.%s", maap->server->ifname);

View file

@ -15,6 +15,7 @@
#include <dbus/dbus.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/string.h>
#include <spa/utils/result.h>
#include <spa/utils/json-builder.h>
@ -118,7 +119,7 @@ static const struct pw_impl_module_events tunnelmodule_events = {
static int load_jack_tunnel(struct impl *impl)
{
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res = 0;
@ -131,13 +132,13 @@ static int load_jack_tunnel(struct impl *impl)
if (impl->properties != NULL)
pw_properties_serialize_dict(b.f, &impl->properties->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
goto done;
pw_log_info("loading module args:'%s'", args);
impl->jack_tunnel = pw_context_load_module(impl->context,
"libpipewire-module-jack-tunnel",
args, NULL);
free(args);
if (impl->jack_tunnel == NULL) {
res = -errno;

View file

@ -8,6 +8,7 @@
#include <errno.h>
#include <limits.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/result.h>
#include <spa/utils/json-builder.h>
#include <spa/param/audio/raw.h>
@ -164,7 +165,7 @@ static int enhance_properties(struct pw_properties *props, const char *key, ...)
{
struct spa_json_builder b;
spa_autoptr(pw_properties) p = NULL;
char *args = NULL;
spa_autofree char *args = NULL;
const char *str;
size_t size;
va_list varargs;
@ -192,10 +193,10 @@ static int enhance_properties(struct pw_properties *props, const char *key, ...)
return res;
}
pw_properties_serialize_dict(b.f, &p->dict, PW_PROPERTIES_FLAG_ENCLOSE);
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
pw_properties_set(props, key, args);
free(args);
return 0;
}
@ -203,7 +204,7 @@ static int create_eq_filter(struct impl *impl, const char *filename)
{
struct spa_json_builder b;
const char* str;
char *args = NULL;
spa_autofree char *args = NULL;
size_t size;
int32_t res = 0;
@ -237,13 +238,13 @@ static int create_eq_filter(struct impl *impl, const char *filename)
spa_json_builder_pop(&b, "}");
pw_properties_serialize_dict(b.f, &impl->props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
pw_log_info("loading new module-filter-chain with args: %s", args);
impl->eq_module = pw_context_load_module(impl->context,
"libpipewire-module-filter-chain",
args, NULL);
free(args);
if (!impl->eq_module) {
pw_log_error("Can't load module: %m");

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/string.h>
#include <spa/debug/types.h>
#include <spa/param/audio/format.h>
@ -704,7 +705,7 @@ static int add_int(struct format_info *info, const char *k, struct spa_pod *para
case SPA_CHOICE_Enum:
{
struct spa_json_builder b;
char *ptr;
spa_autofree char *ptr = NULL;
size_t size;
int res;
@ -715,10 +716,10 @@ static int add_int(struct format_info *info, const char *k, struct spa_pod *para
for (i = 1; i < n_values; i++)
spa_json_builder_array_int(&b, values[i]);
spa_json_builder_pop(&b, "]");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
pw_properties_set(info->props, k, ptr);
free(ptr);
break;
}
default:

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -54,7 +55,7 @@ static int module_always_sink_load(struct module *module)
{
struct module_always_sink_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
const char *str;
size_t size;
int res;
@ -66,12 +67,12 @@ static int module_always_sink_load(struct module *module)
if ((str = pw_properties_get(module->props, "sink_name")) != NULL)
spa_json_builder_object_string(&b, "sink.name", str);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-fallback-sink",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -4,6 +4,7 @@
/* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/json.h>
#include <spa/utils/json-builder.h>
@ -171,7 +172,7 @@ static int module_combine_sink_load(struct module *module)
struct spa_json_builder b;
uint32_t i;
int res;
char *args;
spa_autofree char *args = NULL;
size_t size;
data->core = pw_context_connect(module->impl->context, NULL, 0);
@ -217,12 +218,12 @@ static int module_combine_sink_load(struct module *module)
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "]");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-combine-stream",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -4,6 +4,7 @@
/* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -104,7 +105,7 @@ static int module_echo_cancel_load(struct module *module)
{
struct module_echo_cancel_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -134,12 +135,12 @@ static int module_echo_cancel_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->playback_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-echo-cancel",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;
@ -198,7 +199,7 @@ static int rename_geometry(struct pw_properties *props, const char *pa_key, cons
{
const char *str;
int i = 0, len, res;
char *args;
spa_autofree char *args = NULL;
size_t size;
struct spa_json_builder b;
@ -231,10 +232,10 @@ static int rename_geometry(struct pw_properties *props, const char *pa_key, cons
i++;
}
spa_json_builder_pop(&b, "]");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
pw_properties_set(props, pw_key, args);
free(args);
pw_properties_set(props, pa_key, NULL);
return 0;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -88,7 +89,7 @@ static int module_jackdbus_detect_load(struct module *module)
{
struct module_jackdbus_detect_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -109,12 +110,12 @@ static int module_jackdbus_detect_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->sink_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-jackdbus-detect",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <spa/param/audio/format-utils.h>
@ -92,7 +93,7 @@ static int module_ladspa_sink_load(struct module *module)
{
struct module_ladspa_sink_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
const char *str, *plugin, *label;
size_t size;
int res;
@ -159,12 +160,12 @@ static int module_ladspa_sink_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->playback_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-filter-chain",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <spa/param/audio/format-utils.h>
@ -92,7 +93,7 @@ static int module_ladspa_source_load(struct module *module)
{
struct module_ladspa_source_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
const char *str, *plugin, *label;
size_t size;
int res;
@ -159,12 +160,12 @@ static int module_ladspa_source_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->playback_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-filter-chain",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -4,6 +4,7 @@
/* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -87,7 +88,7 @@ static int module_loopback_load(struct module *module)
{
struct module_loopback_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -108,12 +109,12 @@ static int module_loopback_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->playback_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-loopback",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -87,7 +88,7 @@ static int module_native_protocol_tcp_prepare(struct module * const module)
struct pw_properties * const props = module->props;
const char *port, *listen, *auth;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -111,10 +112,10 @@ static int module_native_protocol_tcp_prepare(struct module * const module)
spa_json_builder_object_string(&b, "client.access", "unrestricted");
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "]");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
pw_properties_set(props, "pulse.tcp", args);
free(args);
d->module = module;

View file

@ -7,6 +7,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
#include <spa/param/audio/format-utils.h>
@ -84,7 +85,7 @@ static int module_pipe_sink_load(struct module *module)
{
struct module_pipesink_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -100,14 +101,13 @@ static int module_pipe_sink_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->stream_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-pipe-tunnel",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -7,6 +7,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
#include <spa/param/audio/format-utils.h>
@ -82,7 +83,7 @@ static int module_pipe_source_load(struct module *module)
{
struct module_pipesrc_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -98,14 +99,13 @@ static int module_pipe_source_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->stream_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-pipe-tunnel",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -61,7 +62,7 @@ static int module_raop_discover_load(struct module *module)
{
struct module_raop_discover_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -72,14 +73,13 @@ static int module_raop_discover_load(struct module *module)
if (data->latency_msec > 0)
spa_json_builder_object_uint(&b, "raop.latency.ms", data->latency_msec);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-raop-discover",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -3,6 +3,7 @@
/* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -83,7 +84,7 @@ static int module_remap_sink_load(struct module *module)
{
struct module_remap_sink_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -104,12 +105,12 @@ static int module_remap_sink_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->playback_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-loopback",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -3,6 +3,7 @@
/* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -83,7 +84,7 @@ static int module_remap_source_load(struct module *module)
{
struct module_remap_source_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -104,12 +105,12 @@ static int module_remap_source_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->playback_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-loopback",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -3,6 +3,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Sanchayan Maity <sanchayan@asymptotic.io> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -82,7 +83,7 @@ static int module_roc_sink_input_load(struct module *module)
{
struct module_roc_sink_input_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -98,14 +99,13 @@ static int module_roc_sink_input_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->source_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-roc-source",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -3,6 +3,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Sanchayan Maity <sanchayan@asymptotic.io> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -78,7 +79,7 @@ static int module_roc_sink_load(struct module *module)
{
struct module_roc_sink_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -94,14 +95,13 @@ static int module_roc_sink_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->sink_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-roc-sink",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -3,6 +3,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Sanchayan Maity <sanchayan@asymptotic.io> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -82,7 +83,7 @@ static int module_roc_source_load(struct module *module)
{
struct module_roc_source_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -98,14 +99,13 @@ static int module_roc_source_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->source_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-roc-source",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -70,7 +71,7 @@ static int module_rtp_recv_load(struct module *module)
{
struct module_rtp_recv_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -97,14 +98,13 @@ static int module_rtp_recv_load(struct module *module)
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "]");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-rtp-sap",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -107,7 +108,7 @@ static int module_rtp_send_load(struct module *module)
{
struct module_rtp_send_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -123,12 +124,12 @@ static int module_rtp_send_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->stream_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-rtp-sink",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;
@ -156,12 +157,12 @@ static int module_rtp_send_load(struct module *module)
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "]");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->sap = pw_context_load_module(module->impl->context,
"libpipewire-module-rtp-sap",
args, NULL);
free(args);
if (data->sap == NULL)
return -errno;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/json-builder.h>
#include <pipewire/impl.h>
#include <pipewire/pipewire.h>
@ -85,7 +86,7 @@ static int module_simple_protocol_tcp_load(struct module *module)
struct module_simple_protocol_tcp_data *data = module->user_data;
struct impl *impl = module->impl;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -95,12 +96,12 @@ static int module_simple_protocol_tcp_load(struct module *module)
spa_json_builder_array_push(&b, "{");
pw_properties_serialize_dict(b.f, &data->module_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(impl->context,
"libpipewire-module-protocol-simple",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;
@ -187,7 +188,7 @@ static int module_simple_protocol_tcp_prepare(struct module * const module)
{
struct spa_json_builder ab;
char *addr;
spa_autofree char *addr = NULL;
size_t addr_size;
if ((res = spa_json_builder_memstream(&ab, &addr, &addr_size, 0)) < 0)
@ -197,10 +198,10 @@ static int module_simple_protocol_tcp_prepare(struct module * const module)
spa_json_builder_array_stringf(&ab, "tcp:%s%s%s",
listen ? listen : "", listen ? ":" : "", port);
spa_json_builder_pop(&ab, "]");
spa_json_builder_close(&ab);
if ((res = spa_json_builder_close(&ab)) < 0)
goto out;
pw_properties_set(module_props, "server.address", addr);
free(addr);
}
d->module = module;

View file

@ -71,6 +71,7 @@ enum {
#include <stdlib.h>
#include <string.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/defs.h>
#include <spa/utils/dict.h>
#include <spa/utils/string.h>
@ -272,7 +273,7 @@ static int do_extension_stream_restore_write(struct module *module, struct clien
struct volume vol;
bool mute = false;
uint32_t i;
char *ptr;
spa_autofree char *ptr = NULL;
size_t size;
char key[1024];
@ -319,7 +320,8 @@ static int do_extension_stream_restore_write(struct module *module, struct clien
(client->default_sink == NULL || !spa_streq(device_name, client->default_sink)))
spa_json_builder_object_string(&b, "target-node", device_name);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((bres = spa_json_builder_close(&b)) < 0)
return bres;
}
if (key_from_name(name, key, sizeof(key)) >= 0) {
pw_log_debug("%s -> %s: %s", name, key, ptr);
@ -328,7 +330,6 @@ static int do_extension_stream_restore_write(struct module *module, struct clien
PW_ID_CORE, key, "Spa:String:JSON", "%s", ptr)) < 0)
pw_log_warn("failed to set metadata %s = %s, %s", key, ptr, strerror(-res));
}
free(ptr);
}
return reply_simple_ack(client, tag);

View file

@ -3,6 +3,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Pauli Virtanen <pav@iki.fi> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <spa/utils/string.h>
@ -144,21 +145,21 @@ static void manager_added(void *data, struct pw_manager_object *o)
{
struct spa_json_builder b;
char *val;
spa_autofree char *val = NULL;
size_t val_size;
if (spa_json_builder_memstream(&b, &val, &val_size, 0) >= 0) {
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "name", name);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if (spa_json_builder_close(&b) < 0)
return;
pw_manager_set_metadata(d->manager, d->metadata_default,
PW_ID_CORE,
pw_manager_object_is_sink(o) ? METADATA_CONFIG_DEFAULT_SINK
: METADATA_CONFIG_DEFAULT_SOURCE,
"Spa:String:JSON", "%s", val);
free(val);
}
}
}

View file

@ -3,6 +3,7 @@
/* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
@ -86,7 +87,7 @@ static int module_tunnel_sink_load(struct module *module)
{
struct module_tunnel_sink_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -102,12 +103,12 @@ static int module_tunnel_sink_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->stream_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-pulse-tunnel",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -3,6 +3,7 @@
/* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
@ -86,7 +87,7 @@ static int module_tunnel_source_load(struct module *module)
{
struct module_tunnel_source_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -102,12 +103,12 @@ static int module_tunnel_source_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->stream_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-pulse-tunnel",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -3,6 +3,7 @@
/* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -78,7 +79,7 @@ static int module_virtual_sink_load(struct module *module)
{
struct module_virtual_sink_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -99,12 +100,12 @@ static int module_virtual_sink_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->playback_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-loopback",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -4,6 +4,7 @@
/* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -81,7 +82,7 @@ static int module_virtual_source_load(struct module *module)
{
struct module_virtual_source_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -102,12 +103,12 @@ static int module_virtual_source_load(struct module *module)
pw_properties_serialize_dict(b.f, &data->playback_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-loopback",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -65,7 +66,7 @@ static int module_x11_bell_load(struct module *module)
{
struct module_x11_bell_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
const char *str;
size_t size;
int res;
@ -83,12 +84,12 @@ static int module_x11_bell_load(struct module *module)
if ((str = pw_properties_get(module->props, "xauthority")) != NULL)
spa_json_builder_object_string(&b, "x11.xauthority", str);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-x11-bell",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/json-builder.h>
#include <pipewire/pipewire.h>
@ -64,7 +65,7 @@ static int module_zeroconf_discover_load(struct module *module)
{
struct module_zeroconf_discover_data *data = module->user_data;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res;
@ -75,14 +76,13 @@ static int module_zeroconf_discover_load(struct module *module)
if (data->latency_msec > 0)
spa_json_builder_object_uint(&b, "pulse.latency", data->latency_msec);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-zeroconf-discover",
args, NULL);
free(args);
if (data->mod == NULL)
return -errno;

View file

@ -4825,7 +4825,7 @@ static int do_set_default(struct client *client, uint32_t command, uint32_t tag,
}
struct spa_json_builder b;
char *val;
spa_autofree char *val = NULL;
size_t val_size;
if ((res = spa_json_builder_memstream(&b, &val, &val_size, 0)) < 0)
@ -4834,13 +4834,13 @@ static int do_set_default(struct client *client, uint32_t command, uint32_t tag,
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "name", name);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_manager_set_metadata(manager, client->metadata_default,
PW_ID_CORE,
sink ? METADATA_CONFIG_DEFAULT_SINK : METADATA_CONFIG_DEFAULT_SOURCE,
"Spa:String:JSON", "%s", val);
free(val);
} else {
res = pw_manager_set_metadata(manager, client->metadata_default,
PW_ID_CORE,

View file

@ -19,6 +19,7 @@
#include "config.h"
#include <spa/utils/cleanup.h>
#include <spa/utils/result.h>
#include <spa/utils/string.h>
#include <spa/utils/json-builder.h>
@ -962,7 +963,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
struct impl *impl;
struct server *s;
struct spa_json_builder b;
char *str;
spa_autofree char *str = NULL;
size_t size;
int res;
struct spa_dict_item it[1];
@ -1017,14 +1018,13 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
ipv4 ? "" : "[", ip, ipv4 ? "" : "]", port);
}
spa_json_builder_pop(&b, "]");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
goto error_free;
pw_log_info("listening on %s", str);
it[0] = SPA_DICT_ITEM_INIT("server.address", str);
pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(it));
free(str);
return 0;
error_free:

View file

@ -12,6 +12,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/result.h>
#include <spa/utils/string.h>
#include <spa/utils/json-builder.h>
@ -233,7 +234,7 @@ static int create_stream(struct impl *impl, struct pw_properties *props,
struct tunnel *t)
{
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res = 0;
struct pw_impl_module *mod;
@ -246,13 +247,13 @@ static int create_stream(struct impl *impl, struct pw_properties *props,
spa_json_builder_array_push(&b, "{");
pw_properties_serialize_dict(b.f, &props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
goto done;
pw_log_info("loading module args:'%s'", args);
mod = pw_context_load_module(impl->context,
"libpipewire-module-raop-sink",
args, NULL);
free(args);
if (mod == NULL) {
res = -errno;

View file

@ -1257,7 +1257,7 @@ static int session_load_source(struct session *session, struct pw_properties *pr
struct impl *impl = session->impl;
struct pw_context *context = pw_impl_module_get_context(impl->module);
struct spa_json_builder b;
char *args = NULL;
spa_autofree char *args = NULL;
size_t size;
const char *str, *media;
int res;
@ -1323,15 +1323,14 @@ static int session_load_source(struct session *session, struct pw_properties *pr
pw_properties_serialize_dict(b.f, &props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
pw_log_info("loading new RTP source");
session->module = pw_context_load_module(context,
"libpipewire-module-rtp-source",
args, NULL);
free(args);
if (session->module == NULL) {
pw_log_error("Can't load module: %m");
return -errno;
@ -1344,7 +1343,6 @@ static int session_load_source(struct session *session, struct pw_properties *pr
return 0;
error:
spa_json_builder_close(&b);
free(args);
return res;
}

View file

@ -18,6 +18,7 @@
#include <spa/utils/hook.h>
#include <spa/utils/result.h>
#include <spa/utils/ringbuffer.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/defs.h>
#include <spa/utils/dll.h>
#include <spa/utils/json.h>
@ -426,10 +427,11 @@ static int send_client_hello(struct client *client)
struct impl *impl = client->impl;
struct spa_json_builder b;
int res;
char *mem;
spa_autofree char *mem = NULL;
size_t size;
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "client/hello");
spa_json_builder_object_push(&b, "payload", "{");
@ -447,10 +449,10 @@ static int send_client_hello(struct client *client)
add_playerv1_support(client, &b);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(client->conn, mem, size);
free(mem);
return pw_websocket_connection_send_text(client->conn, mem, size);
return res;
}
@ -459,10 +461,11 @@ static int send_client_state(struct client *client)
{
struct spa_json_builder b;
int res;
char *mem;
spa_autofree char *mem = NULL;
size_t size;
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "client/state");
spa_json_builder_object_push(&b, "payload", "{");
@ -473,10 +476,10 @@ static int send_client_state(struct client *client)
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(client->conn, mem, size);
free(mem);
return pw_websocket_connection_send_text(client->conn, mem, size);
return res;
}
@ -498,17 +501,18 @@ static int send_client_time(struct client *client)
now = get_time_us(client);
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "client/time");
spa_json_builder_object_push(&b, "payload", "{");
spa_json_builder_object_uint(&b, "client_transmitted", now);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(client->conn, mem, size);
free(mem);
return pw_websocket_connection_send_text(client->conn, mem, size);
return res;
}
@ -528,21 +532,22 @@ static int send_client_goodbye(struct client *client, const char *reason)
{
struct spa_json_builder b;
int res;
char *mem;
spa_autofree char *mem = NULL;
size_t size;
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "client/goodbye");
spa_json_builder_object_push(&b, "payload", "{");
spa_json_builder_object_string(&b, "reason", reason);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(client->conn, mem, size);
pw_websocket_connection_disconnect(client->conn, true);
free(mem);
return res;
}

View file

@ -18,6 +18,7 @@
#include <spa/utils/hook.h>
#include <spa/utils/result.h>
#include <spa/utils/ringbuffer.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/defs.h>
#include <spa/utils/dll.h>
#include <spa/utils/json.h>
@ -427,7 +428,8 @@ static int send_server_hello(struct client *c)
size_t size;
char *mem;
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "server/hello");
spa_json_builder_object_push(&b, "payload", "{");
@ -443,10 +445,10 @@ static int send_server_hello(struct client *c)
spa_json_builder_object_string(&b, "connection_reason", "discovery");
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return pw_websocket_connection_send_text(c->conn, mem, size);
return res;
}
@ -461,7 +463,8 @@ static int send_server_state(struct client *c)
if (!SPA_FLAG_IS_SET(c->supported_roles, ROLE_METADATA))
return 0;
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "server/state");
spa_json_builder_object_push(&b, "payload", "{");
@ -470,10 +473,10 @@ static int send_server_state(struct client *c)
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return pw_websocket_connection_send_text(c->conn, mem, size);
return res;
}
@ -487,7 +490,8 @@ static int send_server_time(struct client *c, uint64_t t1, uint64_t t2)
t3 = get_time_us(c);
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "server/time");
spa_json_builder_object_push(&b, "payload", "{");
@ -496,10 +500,10 @@ static int send_server_time(struct client *c, uint64_t t1, uint64_t t2)
spa_json_builder_object_uint(&b, "server_transmitted", t3);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return pw_websocket_connection_send_text(c->conn, mem, size);
return res;
}
@ -511,7 +515,8 @@ static int send_server_command(struct client *c, int command, int value)
char *mem;
int res;
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "server/command");
spa_json_builder_object_push(&b, "payload", "{");
@ -526,10 +531,10 @@ static int send_server_command(struct client *c, int command, int value)
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return pw_websocket_connection_send_text(c->conn, mem, size);
return res;
}
#endif
@ -572,7 +577,8 @@ static int send_stream_start(struct client *c)
return -ENOTSUP;
}
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "stream/start");
spa_json_builder_object_push(&b, "payload", "{");
@ -585,10 +591,10 @@ static int send_stream_start(struct client *c)
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return pw_websocket_connection_send_text(c->conn, mem, size);
return res;
}
@ -600,7 +606,8 @@ static int send_stream_end(struct client *c)
size_t size;
char *mem;
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "stream/end");
spa_json_builder_object_push(&b, "payload", "{");
@ -610,10 +617,10 @@ static int send_stream_end(struct client *c)
spa_json_builder_pop(&b, "]");
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
res = pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return pw_websocket_connection_send_text(c->conn, mem, size);
return res;
}
#endif
@ -623,10 +630,11 @@ static int send_group_update(struct client *c, bool playing)
struct impl *impl = c->impl;
struct spa_json_builder b;
int res;
char *mem;
spa_autofree char *mem = NULL;
size_t size;
spa_json_builder_memstream(&b, &mem, &size, 0);
if ((res = spa_json_builder_memstream(&b, &mem, &size, 0)) < 0)
return res;
spa_json_builder_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "group/update");
spa_json_builder_object_push(&b, "payload", "{");
@ -635,13 +643,12 @@ static int send_group_update(struct client *c, bool playing)
spa_json_builder_object_string(&b, "group_name", pw_properties_get(impl->props, "sendspin.group-name"));
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
return res;
c->playing = playing;
res = pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return res;
return pw_websocket_connection_send_text(c->conn, mem, size);
}
/* {"codec":"pcm","sample_rate":44100,"channels":2,"bit_depth":16} */

View file

@ -19,6 +19,7 @@
#include <net/if.h>
#include <ifaddrs.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/result.h>
#include <spa/utils/string.h>
#include <spa/utils/json-builder.h>
@ -533,7 +534,7 @@ static int create_stream(struct impl *impl, struct pw_properties *props,
struct tunnel *t)
{
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
int res = 0;
struct pw_impl_module *mod;
@ -567,13 +568,13 @@ static int create_stream(struct impl *impl, struct pw_properties *props,
spa_json_builder_array_push(&b, "{");
pw_properties_serialize_dict(b.f, &props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
goto done;
pw_log_info("loading module args:'%s'", args);
mod = pw_context_load_module(impl->context,
"libpipewire-module-protocol-simple",
args, NULL);
free(args);
if (mod == NULL) {
res = -errno;

View file

@ -12,6 +12,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/result.h>
#include <spa/utils/string.h>
#include <spa/utils/json-builder.h>
@ -243,7 +244,7 @@ static void on_zeroconf_added(void *data, const void *user_data, const struct sp
struct tunnel_info tinfo;
const struct spa_dict_item *it;
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
struct pw_impl_module *mod;
struct pw_properties *props = NULL;
@ -337,13 +338,13 @@ static void on_zeroconf_added(void *data, const void *user_data, const struct sp
spa_json_builder_object_push(&b, "stream.props", "{");
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if (spa_json_builder_close(&b) < 0)
goto done;
pw_log_info("loading module args:'%s'", args);
mod = pw_context_load_module(impl->context,
"libpipewire-module-pulse-tunnel",
args, NULL);
free(args);
if (mod == NULL) {
pw_log_error("Can't load module: %m");

View file

@ -11,6 +11,7 @@
#include <math.h>
#include <locale.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/result.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format-utils.h>
@ -94,7 +95,7 @@ int main(int argc, char *argv[])
const char *opt_remote = NULL, *remote_name;
char cname[256];
struct spa_json_builder b;
char *args;
spa_autofree char *args = NULL;
size_t size;
static const struct option long_options[] = {
{ "help", no_argument, NULL, 'h' },
@ -251,14 +252,14 @@ int main(int argc, char *argv[])
pw_properties_serialize_dict(b.f, &data.playback_props->dict, 0);
spa_json_builder_pop(&b, "}");
spa_json_builder_pop(&b, "}");
spa_json_builder_close(&b);
if ((res = spa_json_builder_close(&b)) < 0)
goto exit;
pw_log_info("loading module with %s", args);
data.module = pw_context_load_module(data.context,
"libpipewire-module-loopback", args,
NULL);
free(args);
if (data.module == NULL) {
fprintf(stderr, "can't load module: %m\n");