improve error handling

Set errno for functions returning NULL if relevant.
Propagate errno and result codes better.
Handle more error cases.
This commit is contained in:
Wim Taymans 2019-06-07 10:11:23 +02:00
parent 0a5bce4a3b
commit 504d78cd18
26 changed files with 359 additions and 148 deletions

View file

@ -522,7 +522,6 @@ static int module_init(struct pw_module *module, struct pw_properties *propertie
error:
free(impl);
return res;
}
SPA_EXPORT

View file

@ -137,8 +137,10 @@ static inline void *pw_array_add_fixed(struct pw_array *arr, size_t size)
{
void *p;
if (SPA_UNLIKELY(arr->alloc < arr->size + size))
if (SPA_UNLIKELY(arr->alloc < arr->size + size)) {
errno = ENOSPC;
return NULL;
}
p = SPA_MEMBER(arr->data, arr->size, void);
arr->size += size;

View file

@ -195,7 +195,7 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
resource = pw_resource_new(client, id, permissions, global->type, version, sizeof(*data));
if (resource == NULL)
goto no_mem;
goto out;
data = pw_resource_get_user_data(resource);
data->client = this;
@ -219,9 +219,9 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
return 0;
no_mem:
pw_log_error("can't create client resource");
return -ENOMEM;
out:
pw_log_error("can't create client resource: %m");
return -errno;
}
static void
@ -335,7 +335,7 @@ int pw_client_register(struct pw_client *client,
global_bind,
client);
if (client->global == NULL)
return -ENOMEM;
return -errno;
pw_global_add_listener(client->global, &client->global_listener, &global_events, client);
pw_global_register(client->global, owner, parent);

View file

@ -52,6 +52,7 @@ pw_control_new(struct pw_core *core,
direction = SPA_DIRECTION_OUTPUT;
break;
default:
errno = -ENOTSUP;
goto exit;
}

View file

@ -461,14 +461,18 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop,
if (properties == NULL)
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
goto no_mem;
if (properties == NULL) {
res = -errno;
goto out_free;
}
this->properties = properties;
this->data_loop_impl = pw_data_loop_new(pw_properties_copy(properties));
if (this->data_loop_impl == NULL)
goto no_data_loop;
if (this->data_loop_impl == NULL) {
res = -errno;
goto out_free;
}
this->data_loop = pw_data_loop_get_loop(this->data_loop_impl);
this->data_system = this->data_loop->system;
@ -541,8 +545,10 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop,
NULL),
global_bind,
this);
if (this->global == NULL)
goto no_mem;
if (this->global == NULL) {
res = -errno;
goto out_cleanup;
}
pw_global_add_listener(this->global, &this->global_listener, &global_events, this);
pw_global_register(this->global, NULL, NULL);
@ -550,9 +556,10 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop,
return this;
no_mem:
no_data_loop:
out_cleanup:
out_free:
free(this);
errno = -res;
return NULL;
}
@ -724,13 +731,16 @@ struct pw_global *pw_core_find_global(struct pw_core *core, uint32_t id)
struct pw_global *global;
global = pw_map_lookup(&core->globals, id);
if (global == NULL)
if (global == NULL) {
errno = ENOENT;
return NULL;
}
if (core->current_client &&
!PW_PERM_IS_R(pw_global_get_permissions(global, core->current_client)))
!PW_PERM_IS_R(pw_global_get_permissions(global, core->current_client))) {
errno = EACCES;
return NULL;
}
return global;
}
@ -1076,13 +1086,12 @@ int pw_core_add_spa_lib(struct pw_core *core,
entry = pw_array_add(&core->factory_lib, sizeof(*entry));
if (entry == NULL)
return -ENOMEM;
return -errno;
if ((err = regcomp(&entry->regex, factory_regexp, REG_EXTENDED | REG_NOSUB)) != 0) {
char errbuf[1024];
regerror(err, &entry->regex, errbuf, sizeof(errbuf));
pw_log_error("can compile regex: %s", errbuf);
pw_array_remove(&core->factory_lib, entry);
return -EINVAL;
}
@ -1090,7 +1099,6 @@ int pw_core_add_spa_lib(struct pw_core *core,
entry->lib = strdup(lib);
pw_log_debug("core %p: map factory regex '%s' to '%s", core,
factory_regexp, lib);
return 0;
}

View file

@ -64,6 +64,7 @@ static void do_stop(void *data, uint64_t count)
struct pw_data_loop *pw_data_loop_new(struct pw_properties *properties)
{
struct pw_data_loop *this;
int res;
this = calloc(1, sizeof(struct pw_data_loop));
if (this == NULL)
@ -72,17 +73,26 @@ struct pw_data_loop *pw_data_loop_new(struct pw_properties *properties)
pw_log_debug("data-loop %p: new", this);
this->loop = pw_loop_new(properties);
if (this->loop == NULL)
if (this->loop == NULL) {
res = -errno;
goto no_loop;
}
this->event = pw_loop_add_event(this->loop, do_stop, this);
if (this->event == NULL) {
res = -errno;
goto no_event;
}
spa_hook_list_init(&this->listener_list);
this->event = pw_loop_add_event(this->loop, do_stop, this);
return this;
no_event:
pw_loop_destroy(this->loop);
no_loop:
free(this);
errno = -res;
return NULL;
}

View file

@ -79,6 +79,7 @@ struct pw_device *pw_device_new(struct pw_core *core,
{
struct impl *impl;
struct pw_device *this;
int res;
impl = calloc(1, sizeof(struct impl) + user_data_size);
if (impl == NULL)
@ -88,8 +89,10 @@ struct pw_device *pw_device_new(struct pw_core *core,
if (properties == NULL)
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
if (properties == NULL) {
res = -errno;
goto no_mem;
}
this->core = core;
this->properties = properties;
@ -110,6 +113,7 @@ struct pw_device *pw_device_new(struct pw_core *core,
no_mem:
free(impl);
errno = -res;
return NULL;
}
@ -317,7 +321,7 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
no_mem:
pw_log_error("can't create device resource");
return -ENOMEM;
return -errno;
}
static void global_destroy(void *object)
@ -346,7 +350,7 @@ int pw_device_register(struct pw_device *device,
if (properties == NULL)
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
return -ENOMEM;
return -errno;
pw_properties_set(properties, PW_KEY_DEVICE_NAME, device->info.name);
if ((str = pw_properties_get(device->properties, PW_KEY_MEDIA_CLASS)) != NULL)
@ -361,7 +365,7 @@ int pw_device_register(struct pw_device *device,
global_bind,
device);
if (device->global == NULL)
return -ENOMEM;
return -errno;
device->info.id = device->global->id;
pw_global_add_listener(device->global, &device->global_listener, &global_events, device);

View file

@ -49,6 +49,9 @@ struct pw_factory *pw_factory_new(struct pw_core *core,
struct pw_factory *this;
this = calloc(1, sizeof(*this) + user_data_size);
if (this == NULL)
return NULL;
this->core = core;
this->properties = properties;
@ -124,8 +127,8 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
return 0;
no_mem:
pw_log_error("can't create factory resource");
return -ENOMEM;
pw_log_error("can't create factory resource: %m");
return -errno;
}
static void global_destroy(void *object)
@ -155,7 +158,7 @@ int pw_factory_register(struct pw_factory *factory,
if (properties == NULL)
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
return -ENOMEM;
return -errno;
pw_properties_set(properties, PW_KEY_FACTORY_NAME, factory->info.name);
pw_properties_setf(properties, PW_KEY_FACTORY_TYPE_NAME, "%s",
@ -172,8 +175,7 @@ int pw_factory_register(struct pw_factory *factory,
global_bind,
factory);
if (factory->global == NULL)
return -ENOMEM;
return -errno;
pw_global_add_listener(factory->global, &factory->global_listener, &global_events, factory);
pw_global_register(factory->global, owner, parent);

View file

@ -109,7 +109,6 @@ static void pw_link_update_state(struct pw_link *link, enum pw_link_state state,
if (state == old)
return;
if (state == PW_LINK_STATE_ERROR) {
pw_log_error("link %p: update state %s -> error (%s)", link,
pw_link_state_as_string(old), error);
@ -441,7 +440,7 @@ static int alloc_buffers(struct pw_link *this,
buffers = calloc(n_buffers, info.skel_size + sizeof(struct spa_buffer *));
if (buffers == NULL)
return -ENOMEM;
return -errno;
/* pointer to buffer structures */
bp = SPA_MEMBER(buffers, n_buffers * sizeof(struct spa_buffer *), struct spa_buffer);
@ -1068,7 +1067,7 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
no_mem:
pw_log_error("can't create link resource");
return -ENOMEM;
return -errno;
}
static const struct pw_port_events input_port_events = {
@ -1190,11 +1189,11 @@ check_permission(struct pw_core *core,
if ((client = output->global->owner) != NULL &&
!PW_PERM_IS_R(pw_global_get_permissions(input->global, client)))
return -EPERM;
return -EACCES;
if ((client = input->global->owner) != NULL &&
!PW_PERM_IS_R(pw_global_get_permissions(output->global, client)))
return -EPERM;
return -EACCES;
return 0;
}
@ -1405,7 +1404,7 @@ int pw_link_register(struct pw_link *link,
if (properties == NULL)
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
return -ENOMEM;
return -errno;
input_node = link->input->node;
output_node = link->output->node;
@ -1428,7 +1427,7 @@ int pw_link_register(struct pw_link *link,
global_bind,
link);
if (link->global == NULL)
return -ENOMEM;
return -errno;
pw_global_add_listener(link->global, &link->global_listener, &global_events, link);

View file

@ -78,6 +78,7 @@ struct pw_loop *pw_loop_new(struct pw_properties *properties)
properties ? &properties->dict : NULL,
n_support, support);
if (impl->system_handle == NULL) {
res = -errno;
pw_log_error("can't make system handle");
goto out_free;
}
@ -102,6 +103,7 @@ struct pw_loop *pw_loop_new(struct pw_properties *properties)
properties ? &properties->dict : NULL,
n_support, support);
if (impl->loop_handle == NULL) {
res = -errno;
pw_log_error("can't make loop handle");
goto out_free_system;
}
@ -146,6 +148,7 @@ struct pw_loop *pw_loop_new(struct pw_properties *properties)
pw_unload_spa_handle(impl->system_handle);
out_free:
free(impl);
errno = -res;
return NULL;
}

View file

@ -42,6 +42,7 @@ SPA_EXPORT
struct pw_main_loop *pw_main_loop_new(struct pw_properties *properties)
{
struct pw_main_loop *this;
int res;
this = calloc(1, sizeof(struct pw_main_loop));
if (this == NULL)
@ -50,17 +51,26 @@ struct pw_main_loop *pw_main_loop_new(struct pw_properties *properties)
pw_log_debug("main-loop %p: new", this);
this->loop = pw_loop_new(properties);
if (this->loop == NULL)
if (this->loop == NULL) {
res = -errno;
goto no_loop;
}
this->event = pw_loop_add_event(this->loop, do_stop, this);
if (this->event == NULL) {
res = -errno;
goto no_event;
}
spa_hook_list_init(&this->listener_list);
this->event = pw_loop_add_event(this->loop, do_stop, this);
return this;
no_event:
pw_loop_destroy(this->loop);
no_loop:
free(this);
errno = -res;
return NULL;
}

View file

@ -137,7 +137,7 @@ int pw_memblock_map(struct pw_memblock *mem)
} else {
mem->ptr = mmap(NULL, mem->size, prot, MAP_SHARED, mem->fd, 0);
if (mem->ptr == MAP_FAILED)
return -ENOMEM;
return -errno;
}
} else {
mem->ptr = NULL;
@ -161,6 +161,7 @@ int pw_memblock_alloc(enum pw_memblock_flags flags, size_t size, struct pw_membl
struct memblock tmp, *p;
struct pw_memblock *m;
bool use_fd;
int res;
if (mem == NULL)
return -EINVAL;
@ -177,23 +178,26 @@ int pw_memblock_alloc(enum pw_memblock_flags flags, size_t size, struct pw_membl
#ifdef USE_MEMFD
m->fd = memfd_create("pipewire-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (m->fd == -1) {
res = -errno;
pw_log_error("Failed to create memfd: %s\n", strerror(errno));
return -errno;
return res;
}
#else
char filename[] = "/dev/shm/pipewire-tmpfile.XXXXXX";
m->fd = mkostemp(filename, O_CLOEXEC);
if (m->fd == -1) {
res = -errno;
pw_log_error("Failed to create temporary file: %s\n", strerror(errno));
return -errno;
return res;
}
unlink(filename);
#endif
if (ftruncate(m->fd, size) < 0) {
res = -errno;
pw_log_warn("Failed to truncate temporary file: %s", strerror(errno));
close(m->fd);
return -errno;
return res;
}
#ifdef USE_MEMFD
if (flags & PW_MEMBLOCK_FLAG_SEAL) {
@ -203,13 +207,13 @@ int pw_memblock_alloc(enum pw_memblock_flags flags, size_t size, struct pw_membl
}
}
#endif
if (pw_memblock_map(m) != 0)
if ((res = pw_memblock_map(m)) < 0)
goto mmap_failed;
} else {
if (size > 0) {
m->ptr = malloc(size);
if (m->ptr == NULL)
return -ENOMEM;
return -errno;
}
m->fd = -1;
}
@ -219,6 +223,9 @@ int pw_memblock_alloc(enum pw_memblock_flags flags, size_t size, struct pw_membl
}
p = calloc(1, sizeof(struct memblock));
if (p == NULL)
return -errno;
*p = tmp;
spa_list_append(&_memblocks, &p->link);
*mem = &p->mem;
@ -228,7 +235,7 @@ int pw_memblock_alloc(enum pw_memblock_flags flags, size_t size, struct pw_membl
mmap_failed:
close(m->fd);
return -ENOMEM;
return res;
}
SPA_EXPORT

View file

@ -61,6 +61,7 @@ static char *find_module(const char *path, const char *name)
struct dirent *entry;
struct stat s;
DIR *dir;
int res;
asprintf(&filename, "%s/%s.so", path, name);
@ -76,7 +77,9 @@ static char *find_module(const char *path, const char *name)
dir = opendir(path);
if (dir == NULL) {
pw_log_warn("could not open %s: %s", path, strerror(errno));
res = -errno;
pw_log_warn("could not open %s: %m", path);
errno = -res;
return NULL;
}
@ -87,6 +90,8 @@ static char *find_module(const char *path, const char *name)
continue;
asprintf(&newpath, "%s/%s", path, entry->d_name);
if (newpath == NULL)
return NULL;
if (stat(newpath, &s) == 0 && S_ISDIR(s.st_mode)) {
filename = find_module(newpath, name);
@ -141,7 +146,7 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
no_mem:
pw_log_error("can't create module resource");
return -ENOMEM;
return -errno;
}
static void global_destroy(void *object)

View file

@ -462,7 +462,7 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
no_mem:
pw_log_error("can't create node resource");
return -ENOMEM;
return -errno;
}
static void global_destroy(void *data)
@ -496,7 +496,7 @@ int pw_node_register(struct pw_node *this,
if (properties == NULL)
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
return -ENOMEM;
return -errno;
if ((str = pw_properties_get(this->properties, PW_KEY_MEDIA_CLASS)) != NULL)
pw_properties_set(properties, PW_KEY_MEDIA_CLASS, str);
@ -516,7 +516,7 @@ int pw_node_register(struct pw_node *this,
global_bind,
this);
if (this->global == NULL)
return -ENOMEM;
return -errno;
this->info.id = this->global->id;
this->rt.activation->position.clock.id = this->info.id;
@ -774,6 +774,7 @@ struct pw_node *pw_node_new(struct pw_core *core,
size_t size;
struct spa_system *data_system = core->data_system;
char *n;
int res;
impl = calloc(1, sizeof(struct impl) + user_data_size);
if (impl == NULL)
@ -793,32 +794,38 @@ struct pw_node *pw_node_new(struct pw_core *core,
if (properties == NULL)
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
if (properties == NULL) {
res = -errno;
goto clean_impl;
}
this->properties = properties;
size = sizeof(struct pw_node_activation);
this->source.fd = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
if (this->source.fd == -1)
if (this->source.fd == -1) {
res = -errno;
goto clean_impl;
}
this->source.func = node_on_fd_events;
this->source.data = this;
this->source.mask = SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP;
this->source.rmask = 0;
if (pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD |
if ((res = pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD |
PW_MEMBLOCK_FLAG_MAP_READWRITE |
PW_MEMBLOCK_FLAG_SEAL,
size,
&this->activation) < 0)
&this->activation)) < 0)
goto clean_impl;
impl->work = pw_work_queue_new(this->core->main_loop);
if (impl->work == NULL)
if (impl->work == NULL) {
res = -errno;
goto clean_impl;
}
this->info.name = n;
@ -865,6 +872,7 @@ struct pw_node *pw_node_new(struct pw_core *core,
if (properties)
pw_properties_free(properties);
free(impl);
errno = -res;
error:
return NULL;
}

View file

@ -96,9 +96,10 @@ open_plugin(struct registry *registry,
char *filename;
void *hnd;
spa_handle_factory_enum_func_t enum_func;
int res = -EFAULT;
if (asprintf(&filename, "%s/%s.so", path, lib) < 0)
goto no_filename;
goto out;
if ((plugin = find_plugin(registry, filename)) != NULL) {
free(filename);
@ -107,16 +108,20 @@ open_plugin(struct registry *registry,
}
if ((hnd = dlopen(filename, RTLD_NOW)) == NULL) {
res = -ENOENT;
fprintf(stderr, "can't load %s: %s\n", filename, dlerror());
goto open_failed;
goto out_free_filename;
}
if ((enum_func = dlsym(hnd, SPA_HANDLE_FACTORY_ENUM_FUNC_NAME)) == NULL) {
res = -ESRCH;
fprintf(stderr, "can't find enum function\n");
goto no_symbol;
goto out_dlclose;
}
if ((plugin = calloc(1, sizeof(struct plugin))) == NULL)
goto alloc_failed;
if ((plugin = calloc(1, sizeof(struct plugin))) == NULL) {
res = -errno;
goto out_dlclose;
}
plugin->ref = 1;
plugin->filename = filename;
@ -128,12 +133,12 @@ open_plugin(struct registry *registry,
return plugin;
alloc_failed:
no_symbol:
out_dlclose:
dlclose(hnd);
open_failed:
out_free_filename:
free(filename);
no_filename:
out:
errno = -res;
return NULL;
}
@ -150,19 +155,23 @@ unref_plugin(struct plugin *plugin)
static const struct spa_handle_factory *find_factory(struct plugin *plugin, const char *factory_name)
{
int res;
int res = -ENOENT;
uint32_t index;
const struct spa_handle_factory *factory;
for (index = 0;;) {
if ((res = plugin->enum_func(&factory, &index)) <= 0) {
if (res != 0)
fprintf(stderr, "can't enumerate factories: %s\n", spa_strerror(res));
break;
if (res == 0)
break;
goto out;
}
if (strcmp(factory->name, factory_name) == 0)
return factory;
}
res = -ENOENT;
out:
errno = -res;
fprintf(stderr, "can't find factory %s: %m\n", factory_name);
return NULL;
}
@ -215,27 +224,34 @@ struct spa_handle *pw_load_spa_handle(const char *lib,
const struct spa_handle_factory *factory;
int res;
pw_log_debug("load \"%s\", \"%s\"", lib, factory_name);
spa_return_val_if_fail(factory_name != NULL, NULL);
if (factory_name == NULL) {
res = -EINVAL;
goto out;
}
if (lib == NULL)
lib = sup->support_lib;
if (lib == NULL)
return NULL;
pw_log_debug("load \"%s\", \"%s\"", lib, factory_name);
if ((plugin = open_plugin(sup->registry, sup->plugin_dir, lib)) == NULL) {
pw_log_warn("can't load '%s'", lib);
res = -errno;
pw_log_warn("can't load '%s': %m", lib);
goto out;
}
factory = find_factory(plugin, factory_name);
if (factory == NULL)
if (factory == NULL) {
res = -errno;
pw_log_warn("can't find factory '%s': %m %s", factory_name, spa_strerror(res));
goto out_unref_plugin;
}
handle = calloc(1, sizeof(struct handle) + spa_handle_factory_get_size(factory, info));
if (handle == NULL)
if (handle == NULL) {
res = -errno;
goto out;
}
if ((res = spa_handle_factory_init(factory,
&handle->handle, info,
@ -256,6 +272,7 @@ struct spa_handle *pw_load_spa_handle(const char *lib,
out_unref_plugin:
unref_plugin(plugin);
out:
errno = -res;
return NULL;
}
@ -398,6 +415,7 @@ bool pw_debug_is_category_enabled(const char *name)
SPA_EXPORT
const char *pw_get_application_name(void)
{
errno = -ENOTSUP;
return NULL;
}

View file

@ -337,6 +337,7 @@ struct pw_port *pw_port_new(enum pw_direction direction,
struct pw_port *this;
struct pw_properties *properties;
const struct spa_node_methods *mix_methods;
int res;
impl = calloc(1, sizeof(struct impl) + user_data_size);
if (impl == NULL)
@ -351,8 +352,10 @@ struct pw_port *pw_port_new(enum pw_direction direction,
else
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
if (properties == NULL) {
res = -errno;
goto no_mem;
}
if (SPA_FLAG_CHECK(info->flags, SPA_PORT_FLAG_PHYSICAL))
pw_properties_set(properties, PW_KEY_PORT_PHYSICAL, "1");
@ -406,6 +409,7 @@ struct pw_port *pw_port_new(enum pw_direction direction,
no_mem:
pw_log_warn("port %p: new failed", impl);
free(impl);
errno = -res;
return NULL;
}
@ -593,10 +597,13 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
struct pw_global *global = this->global;
struct pw_resource *resource;
struct resource_data *data;
int res;
resource = pw_resource_new(client, id, permissions, global->type, version, sizeof(*data));
if (resource == NULL)
if (resource == NULL) {
res = -errno;
goto no_mem;
}
data = pw_resource_get_user_data(resource);
data->port = this;
@ -619,8 +626,8 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
return 0;
no_mem:
pw_log_error("can't create port resource");
return -ENOMEM;
pw_log_error("can't create port resource: %s", spa_strerror(res));
return res;
}
static void global_destroy(void *object)
@ -651,7 +658,7 @@ int pw_port_register(struct pw_port *port,
global_bind,
port);
if (port->global == NULL)
return -ENOMEM;
return -errno;
pw_global_add_listener(port->global, &port->global_listener, &global_events, port);

View file

@ -157,6 +157,7 @@ pw_properties_new_string(const char *str)
struct properties *impl;
const char *state = NULL, *s = NULL;
size_t len;
int res;
impl = properties_new(16);
if (impl == NULL)
@ -166,8 +167,10 @@ pw_properties_new_string(const char *str)
while (s) {
char *val, *eq;
if ((val = strndup(s, len)) == NULL)
if ((val = strndup(s, len)) == NULL) {
res = -errno;
goto no_mem;
}
eq = strchr(val, '=');
if (eq && eq != val) {
@ -177,8 +180,10 @@ pw_properties_new_string(const char *str)
s = pw_split_walk(str, " \t\n\r", &len, &state);
}
return &impl->this;
no_mem:
pw_properties_free(&impl->this);
errno = -res;
return NULL;
}

View file

@ -135,7 +135,7 @@ pw_protocol_add_marshal(struct pw_protocol *protocol,
impl = calloc(1, sizeof(struct marshal));
if (impl == NULL)
return -ENOMEM;
return -errno;
impl->marshal = marshal;
@ -154,9 +154,6 @@ pw_protocol_get_marshal(struct pw_protocol *protocol, uint32_t type)
{
struct marshal *impl;
if (protocol == NULL)
return NULL;
spa_list_for_each(impl, &protocol->marshal_list, link) {
if (impl->marshal->type == type)
return impl->marshal;
@ -168,6 +165,7 @@ SPA_EXPORT
struct pw_protocol *pw_core_find_protocol(struct pw_core *core, const char *name)
{
struct pw_protocol *protocol;
spa_list_for_each(protocol, &core->protocol_list, link) {
if (strcmp(protocol->name, name) == 0)
return protocol;

View file

@ -160,6 +160,7 @@ struct pw_remote *pw_remote_new(struct pw_core *core,
struct pw_remote *this;
struct pw_protocol *protocol;
const char *protocol_name;
int res;
impl = calloc(1, sizeof(struct remote) + user_data_size);
if (impl == NULL)
@ -191,7 +192,8 @@ struct pw_remote *pw_remote_new(struct pw_core *core,
spa_hook_list_init(&this->listener_list);
if ((protocol_name = pw_properties_get(properties, PW_KEY_PROTOCOL)) == NULL) {
if (!pw_module_load(core, "libpipewire-module-protocol-native", NULL, NULL, NULL, NULL))
if (pw_module_load(core, "libpipewire-module-protocol-native",
NULL, NULL, NULL, NULL) == NULL)
goto no_protocol;
protocol_name = PW_TYPE_INFO_PROTOCOL_Native;
@ -213,19 +215,23 @@ struct pw_remote *pw_remote_new(struct pw_core *core,
return this;
no_mem:
res = -errno;
pw_log_error("no memory");
goto exit;
no_protocol:
pw_log_error("can't load native protocol");
res = -errno;
pw_log_error("can't load native protocol: %m");
goto exit_free_props;
no_connection:
pw_log_error("can't create new native protocol connection");
res = -errno;
pw_log_error("can't create new native protocol connection: %m");
goto exit_free_props;
exit_free_props:
pw_properties_free(properties);
exit:
free(impl);
errno = -res;
return NULL;
}
@ -313,18 +319,23 @@ static int do_connect(struct pw_remote *remote)
{
struct remote *impl = SPA_CONTAINER_OF(remote, struct remote, this);
struct pw_proxy dummy;
int res;
dummy.remote = remote;
remote->core_proxy = (struct pw_core_proxy*)pw_proxy_new(&dummy,
PW_TYPE_INTERFACE_Core, 0);
if (remote->core_proxy == NULL)
if (remote->core_proxy == NULL) {
res = -errno;
goto no_proxy;
}
remote->client_proxy = (struct pw_client_proxy*)pw_proxy_new(&dummy,
PW_TYPE_INTERFACE_Client, 0);
if (remote->client_proxy == NULL)
if (remote->client_proxy == NULL) {
res = -errno;
goto clean_core_proxy;
}
pw_core_proxy_add_listener(remote->core_proxy, &impl->core_listener, &core_proxy_events, remote);
@ -340,7 +351,7 @@ static int do_connect(struct pw_remote *remote)
no_proxy:
pw_protocol_client_disconnect(remote->conn);
pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR, "can't connect: no memory");
return -ENOMEM;
return res;
}
SPA_EXPORT
@ -447,29 +458,38 @@ struct pw_proxy *pw_remote_export(struct pw_remote *remote,
{
struct pw_proxy *proxy;
const struct pw_export_type *t;
int res;
if (remote->core_proxy == NULL)
if (remote->core_proxy == NULL) {
res = -ENETDOWN;
goto no_core_proxy;
}
t = pw_core_find_export_type(remote->core, type);
if (t == NULL)
if (t == NULL) {
res = -EPROTO;
goto no_export_type;
}
proxy = t->func(remote, type, props, object, user_data_size);
if (proxy == NULL)
if (proxy == NULL) {
res = -errno;
goto proxy_failed;
}
return proxy;
no_core_proxy:
errno = ENETDOWN;
pw_log_error("no core proxy: %m");
return NULL;
pw_log_error("no core proxy: %s", spa_strerror(res));
goto out;
no_export_type:
pw_log_error("can't export type %d: %m", type);
return NULL;
pw_log_error("can't export type %d: %s", type, spa_strerror(res));
goto out;
proxy_failed:
pw_log_error("failed to create proxy: %m");
pw_log_error("failed to create proxy: %s", spa_strerror(res));
goto out;
out:
errno = -res;
return NULL;
}
@ -489,6 +509,5 @@ const struct pw_export_type *pw_core_find_export_type(struct pw_core *core, uint
if (t->type == type)
return t;
}
errno = EPROTO;
return NULL;
}

View file

@ -91,6 +91,7 @@ struct pw_resource *pw_resource_new(struct pw_client *client,
in_use:
pw_log_debug("resource %p: id %u in use for client %p", this, id, client);
free(impl);
errno = -EEXIST;
return NULL;
}

View file

@ -175,11 +175,10 @@ static struct param *add_param(struct pw_stream *stream,
uint32_t id;
int idx;
if (param == NULL)
return NULL;
if (!spa_pod_is_object(param))
if (param == NULL || !spa_pod_is_object(param)) {
errno = -EINVAL;
return NULL;
}
p = malloc(sizeof(struct param) + SPA_POD_SIZE(param));
if (p == NULL)
@ -481,7 +480,7 @@ static int port_set_format(void *object,
struct stream *impl = object;
struct pw_stream *stream = &impl->this;
struct param *p;
int count;
int count, res;
pw_log_debug("stream %p: format changed:", impl);
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
@ -490,8 +489,10 @@ static int port_set_format(void *object,
clear_params(stream, PARAM_TYPE_FORMAT);
if (format && spa_pod_is_object_type(format, SPA_TYPE_OBJECT_Format)) {
p = add_param(stream, PARAM_TYPE_FORMAT, format);
if (p == NULL)
if (p == NULL) {
res = -errno;
goto no_mem;
}
((struct spa_pod_object*)p->param)->body.id = SPA_PARAM_Format;
}
@ -517,8 +518,8 @@ static int port_set_format(void *object,
return 0;
no_mem:
pw_stream_finish_format(stream, -ENOMEM, NULL, 0);
return -ENOMEM;
pw_stream_finish_format(stream, res, NULL, 0);
return res;
}
static int impl_port_set_param(void *object,
@ -955,6 +956,7 @@ static const struct pw_node_proxy_events node_events = {
static int handle_connect(struct pw_stream *stream)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
int res;
pw_log_debug("stream %p: creating node", stream);
impl->node = pw_node_new(impl->core, stream->name,
@ -993,11 +995,13 @@ static int handle_connect(struct pw_stream *stream)
return 0;
no_node:
res = -errno;
pw_log_error("stream %p: can't make node: %m", stream);
return -errno;
return res;
no_proxy:
res = -errno;
pw_log_error("stream %p: can't make proxy: %m", stream);
return -errno;
return res;
}
static void on_remote_state_changed(void *_data, enum pw_remote_state old,
@ -1048,6 +1052,7 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name,
struct stream *impl;
struct pw_stream *this;
const char *str;
int res;
impl = calloc(1, sizeof(struct stream));
if (impl == NULL)
@ -1061,8 +1066,10 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name,
} else if (pw_properties_get(props, PW_KEY_MEDIA_NAME) == NULL) {
pw_properties_set(props, PW_KEY_MEDIA_NAME, name);
}
if (props == NULL)
if (props == NULL) {
res = errno;
goto no_mem;
}
if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL) {
const struct pw_properties *p = pw_remote_get_properties(remote);
@ -1104,6 +1111,7 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name,
no_mem:
free(impl);
errno = -res;
return NULL;
}
@ -1119,13 +1127,16 @@ pw_stream_new_simple(struct pw_loop *loop,
struct stream *impl;
struct pw_core *core;
struct pw_remote *remote;
int res;
core = pw_core_new(loop, NULL, 0);
remote = pw_remote_new(core, NULL, 0);
stream = pw_stream_new(remote, name, props);
if (stream == NULL)
if (stream == NULL) {
res = -errno;
goto cleanup;
}
impl = SPA_CONTAINER_OF(stream, struct stream, this);
@ -1139,6 +1150,7 @@ pw_stream_new_simple(struct pw_loop *loop,
cleanup:
pw_core_destroy(core);
errno = -res;
return NULL;
}
@ -1487,11 +1499,13 @@ struct pw_buffer *pw_stream_dequeue_buffer(struct pw_stream *stream)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
struct buffer *b;
int res;
if ((b = pop_queue(impl, &impl->dequeued)) == NULL) {
pw_log_trace("stream %p: no more buffers", stream);
res = -errno;
pw_log_trace("stream %p: no more buffers: %m", stream);
call_trigger(impl);
errno = EPIPE;
errno = -res;
return NULL;
}
pw_log_trace("stream %p: dequeue buffer %d", stream, b->id);

View file

@ -82,6 +82,7 @@ static void do_stop(void *data, uint64_t count)
#define CHECK(expression,label) \
do { \
if ((errno = expression) != 0) { \
res = -errno; \
pw_log_error(#expression ": %s", strerror(errno)); \
goto label; \
} \
@ -108,6 +109,7 @@ struct pw_thread_loop *pw_thread_loop_new(struct pw_loop *loop,
struct pw_thread_loop *this;
pthread_mutexattr_t attr;
pthread_condattr_t cattr;
int res;
this = calloc(1, sizeof(struct pw_thread_loop));
if (this == NULL)
@ -146,6 +148,7 @@ struct pw_thread_loop *pw_thread_loop_new(struct pw_loop *loop,
clean_this:
free(this->name);
free(this);
errno = -res;
no_mem:
return NULL;
}

View file

@ -96,18 +96,30 @@ static void process_work_queue(void *data, uint64_t count)
struct pw_work_queue *pw_work_queue_new(struct pw_loop *loop)
{
struct pw_work_queue *this;
int res;
this = calloc(1, sizeof(struct pw_work_queue));
if (this == NULL)
return NULL;
pw_log_debug("work-queue %p: new", this);
this->loop = loop;
this->wakeup = pw_loop_add_event(this->loop, process_work_queue, this);
if (this->wakeup == NULL)
goto out_free;
spa_list_init(&this->work_list);
spa_list_init(&this->free_list);
return this;
out_free:
res = -errno;
free(this);
errno = -res;
return NULL;
}
/** Destroy a work queue