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/defs.h>
#include <spa/utils/ansi.h> #include <spa/utils/ansi.h>
#include <spa/utils/json.h> #include <spa/utils/json.h>
#include <spa/utils/cleanup.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { 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); 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) int res = 0;
fclose(b->f); 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, 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) SPA_API_JSON_BUILDER char *spa_json_builder_reformat(const char *json, uint32_t flags)
{ {
struct spa_json_builder b; struct spa_json_builder b;
char *mem; spa_autofree char *mem = NULL;
size_t size; size_t size;
int res; int res;
if ((res = spa_json_builder_memstream(&b, &mem, &size, flags)) < 0) { if ((res = spa_json_builder_memstream(&b, &mem, &size, flags)) < 0)
errno = -res; goto error;
return NULL;
}
spa_json_builder_array_value(&b, true, json); spa_json_builder_array_value(&b, true, json);
spa_json_builder_close(&b); if ((res = spa_json_builder_close(&b)) < 0)
return mem; goto error;
return spa_steal_ptr(mem);
error:
errno = -res;
return NULL;
} }
/** /**

View file

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

View file

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

View file

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

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/string.h> #include <spa/utils/string.h>
#include <spa/debug/types.h> #include <spa/debug/types.h>
#include <spa/param/audio/format.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: case SPA_CHOICE_Enum:
{ {
struct spa_json_builder b; struct spa_json_builder b;
char *ptr; spa_autofree char *ptr = NULL;
size_t size; size_t size;
int res; 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++) for (i = 1; i < n_values; i++)
spa_json_builder_array_int(&b, values[i]); spa_json_builder_array_int(&b, values[i]);
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(info->props, k, ptr); pw_properties_set(info->props, k, ptr);
free(ptr);
break; break;
} }
default: default:

View file

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

View file

@ -4,6 +4,7 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
#include <spa/param/audio/format-utils.h> #include <spa/param/audio/format-utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/json.h> #include <spa/utils/json.h>
#include <spa/utils/json-builder.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; struct spa_json_builder b;
uint32_t i; uint32_t i;
int res; int res;
char *args; spa_autofree char *args = NULL;
size_t size; size_t size;
data->core = pw_context_connect(module->impl->context, NULL, 0); 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_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, data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-combine-stream", "libpipewire-module-combine-stream",
args, NULL); args, NULL);
free(args);
if (data->mod == NULL) if (data->mod == NULL)
return -errno; return -errno;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */ /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/json-builder.h> #include <spa/utils/json-builder.h>
#include <pipewire/pipewire.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; struct pw_properties * const props = module->props;
const char *port, *listen, *auth; const char *port, *listen, *auth;
struct spa_json_builder b; struct spa_json_builder b;
char *args; spa_autofree char *args = NULL;
size_t size; size_t size;
int res; 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_object_string(&b, "client.access", "unrestricted");
spa_json_builder_pop(&b, "}"); 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;
pw_properties_set(props, "pulse.tcp", args); pw_properties_set(props, "pulse.tcp", args);
free(args);
d->module = module; d->module = module;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> */ /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h> #include <spa/utils/hook.h>
#include <spa/utils/json-builder.h> #include <spa/utils/json-builder.h>
#include <pipewire/pipewire.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 module_rtp_recv_data *data = module->user_data;
struct spa_json_builder b; struct spa_json_builder b;
char *args; spa_autofree char *args = NULL;
size_t size; size_t size;
int res; 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_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, data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-rtp-sap", "libpipewire-module-rtp-sap",
args, NULL); args, NULL);
free(args);
if (data->mod == NULL) if (data->mod == NULL)
return -errno; return -errno;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,6 +2,7 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */ /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h> #include <spa/utils/hook.h>
#include <spa/utils/json-builder.h> #include <spa/utils/json-builder.h>
#include <pipewire/pipewire.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 module_zeroconf_discover_data *data = module->user_data;
struct spa_json_builder b; struct spa_json_builder b;
char *args; spa_autofree char *args = NULL;
size_t size; size_t size;
int res; int res;
@ -75,14 +76,13 @@ static int module_zeroconf_discover_load(struct module *module)
if (data->latency_msec > 0) if (data->latency_msec > 0)
spa_json_builder_object_uint(&b, "pulse.latency", data->latency_msec); spa_json_builder_object_uint(&b, "pulse.latency", data->latency_msec);
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, data->mod = pw_context_load_module(module->impl->context,
"libpipewire-module-zeroconf-discover", "libpipewire-module-zeroconf-discover",
args, NULL); args, NULL);
free(args);
if (data->mod == NULL) if (data->mod == NULL)
return -errno; 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; struct spa_json_builder b;
char *val; spa_autofree char *val = NULL;
size_t val_size; size_t val_size;
if ((res = spa_json_builder_memstream(&b, &val, &val_size, 0)) < 0) 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_array_push(&b, "{");
spa_json_builder_object_string(&b, "name", name); spa_json_builder_object_string(&b, "name", 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;
res = pw_manager_set_metadata(manager, client->metadata_default, res = pw_manager_set_metadata(manager, client->metadata_default,
PW_ID_CORE, PW_ID_CORE,
sink ? METADATA_CONFIG_DEFAULT_SINK : METADATA_CONFIG_DEFAULT_SOURCE, sink ? METADATA_CONFIG_DEFAULT_SINK : METADATA_CONFIG_DEFAULT_SOURCE,
"Spa:String:JSON", "%s", val); "Spa:String:JSON", "%s", val);
free(val);
} else { } else {
res = pw_manager_set_metadata(manager, client->metadata_default, res = pw_manager_set_metadata(manager, client->metadata_default,
PW_ID_CORE, PW_ID_CORE,

View file

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

View file

@ -12,6 +12,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/result.h> #include <spa/utils/result.h>
#include <spa/utils/string.h> #include <spa/utils/string.h>
#include <spa/utils/json-builder.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 tunnel *t)
{ {
struct spa_json_builder b; struct spa_json_builder b;
char *args; spa_autofree char *args = NULL;
size_t size; size_t size;
int res = 0; int res = 0;
struct pw_impl_module *mod; 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, "{"); spa_json_builder_array_push(&b, "{");
pw_properties_serialize_dict(b.f, &props->dict, 0); 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)
goto done;
pw_log_info("loading module args:'%s'", args); pw_log_info("loading module args:'%s'", args);
mod = pw_context_load_module(impl->context, mod = pw_context_load_module(impl->context,
"libpipewire-module-raop-sink", "libpipewire-module-raop-sink",
args, NULL); args, NULL);
free(args);
if (mod == NULL) { if (mod == NULL) {
res = -errno; 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 impl *impl = session->impl;
struct pw_context *context = pw_impl_module_get_context(impl->module); struct pw_context *context = pw_impl_module_get_context(impl->module);
struct spa_json_builder b; struct spa_json_builder b;
char *args = NULL; spa_autofree char *args = NULL;
size_t size; size_t size;
const char *str, *media; const char *str, *media;
int res; 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); pw_properties_serialize_dict(b.f, &props->dict, 0);
spa_json_builder_pop(&b, "}"); 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;
pw_log_info("loading new RTP source"); pw_log_info("loading new RTP source");
session->module = pw_context_load_module(context, session->module = pw_context_load_module(context,
"libpipewire-module-rtp-source", "libpipewire-module-rtp-source",
args, NULL); args, NULL);
free(args);
if (session->module == NULL) { if (session->module == NULL) {
pw_log_error("Can't load module: %m"); pw_log_error("Can't load module: %m");
return -errno; return -errno;
@ -1344,7 +1343,6 @@ static int session_load_source(struct session *session, struct pw_properties *pr
return 0; return 0;
error: error:
spa_json_builder_close(&b); spa_json_builder_close(&b);
free(args);
return res; return res;
} }

View file

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

View file

@ -18,6 +18,7 @@
#include <spa/utils/hook.h> #include <spa/utils/hook.h>
#include <spa/utils/result.h> #include <spa/utils/result.h>
#include <spa/utils/ringbuffer.h> #include <spa/utils/ringbuffer.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/defs.h> #include <spa/utils/defs.h>
#include <spa/utils/dll.h> #include <spa/utils/dll.h>
#include <spa/utils/json.h> #include <spa/utils/json.h>
@ -427,7 +428,8 @@ static int send_server_hello(struct client *c)
size_t size; size_t size;
char *mem; 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_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "server/hello"); spa_json_builder_object_string(&b, "type", "server/hello");
spa_json_builder_object_push(&b, "payload", "{"); 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_object_string(&b, "connection_reason", "discovery");
spa_json_builder_pop(&b, "}"); 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); return pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return res; return res;
} }
@ -461,7 +463,8 @@ static int send_server_state(struct client *c)
if (!SPA_FLAG_IS_SET(c->supported_roles, ROLE_METADATA)) if (!SPA_FLAG_IS_SET(c->supported_roles, ROLE_METADATA))
return 0; 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_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "server/state"); spa_json_builder_object_string(&b, "type", "server/state");
spa_json_builder_object_push(&b, "payload", "{"); 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_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); return pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return res; 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); 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_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "server/time"); spa_json_builder_object_string(&b, "type", "server/time");
spa_json_builder_object_push(&b, "payload", "{"); 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_object_uint(&b, "server_transmitted", t3);
spa_json_builder_pop(&b, "}"); 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); return pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return res; return res;
} }
@ -511,7 +515,8 @@ static int send_server_command(struct client *c, int command, int value)
char *mem; char *mem;
int res; 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_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "server/command"); spa_json_builder_object_string(&b, "type", "server/command");
spa_json_builder_object_push(&b, "payload", "{"); 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_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); return pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return res; return res;
} }
#endif #endif
@ -572,7 +577,8 @@ static int send_stream_start(struct client *c)
return -ENOTSUP; 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_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "stream/start"); spa_json_builder_object_string(&b, "type", "stream/start");
spa_json_builder_object_push(&b, "payload", "{"); 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_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); return pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return res; return res;
} }
@ -600,7 +606,8 @@ static int send_stream_end(struct client *c)
size_t size; size_t size;
char *mem; 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_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "stream/end"); spa_json_builder_object_string(&b, "type", "stream/end");
spa_json_builder_object_push(&b, "payload", "{"); 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_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); return pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return res; return res;
} }
#endif #endif
@ -623,10 +630,11 @@ static int send_group_update(struct client *c, bool playing)
struct impl *impl = c->impl; struct impl *impl = c->impl;
struct spa_json_builder b; struct spa_json_builder b;
int res; int res;
char *mem; spa_autofree char *mem = NULL;
size_t size; 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_array_push(&b, "{");
spa_json_builder_object_string(&b, "type", "group/update"); spa_json_builder_object_string(&b, "type", "group/update");
spa_json_builder_object_push(&b, "payload", "{"); 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_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_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; c->playing = playing;
res = pw_websocket_connection_send_text(c->conn, mem, size); return pw_websocket_connection_send_text(c->conn, mem, size);
free(mem);
return res;
} }
/* {"codec":"pcm","sample_rate":44100,"channels":2,"bit_depth":16} */ /* {"codec":"pcm","sample_rate":44100,"channels":2,"bit_depth":16} */

View file

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

View file

@ -12,6 +12,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/result.h> #include <spa/utils/result.h>
#include <spa/utils/string.h> #include <spa/utils/string.h>
#include <spa/utils/json-builder.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; struct tunnel_info tinfo;
const struct spa_dict_item *it; const struct spa_dict_item *it;
struct spa_json_builder b; struct spa_json_builder b;
char *args; spa_autofree char *args = NULL;
size_t size; size_t size;
struct pw_impl_module *mod; struct pw_impl_module *mod;
struct pw_properties *props = NULL; 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_object_push(&b, "stream.props", "{");
spa_json_builder_pop(&b, "}"); spa_json_builder_pop(&b, "}");
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); pw_log_info("loading module args:'%s'", args);
mod = pw_context_load_module(impl->context, mod = pw_context_load_module(impl->context,
"libpipewire-module-pulse-tunnel", "libpipewire-module-pulse-tunnel",
args, NULL); args, NULL);
free(args);
if (mod == NULL) { if (mod == NULL) {
pw_log_error("Can't load module: %m"); pw_log_error("Can't load module: %m");

View file

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