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

@ -286,6 +286,7 @@ impl_get_connection(void *object,
struct impl *impl = object;
struct connection *conn;
DBusError error;
int res;
dbus_error_init(&error);
@ -298,6 +299,8 @@ impl_get_connection(void *object,
conn->dispatch_event = spa_loop_utils_add_idle(impl->utils,
false, dispatch_cb, conn);
if (conn->dispatch_event == NULL)
goto no_event;
dbus_connection_set_exit_on_disconnect(conn->conn, false);
dbus_connection_set_dispatch_status_function(conn->conn, dispatch_status, conn, NULL);
@ -314,7 +317,19 @@ impl_get_connection(void *object,
error:
spa_log_error(impl->log, "Failed to connect to system bus: %s", error.message);
dbus_error_free(&error);
res = -ECONNREFUSED;
goto out_free;
no_event:
res = -errno;
spa_log_error(impl->log, "Failed to create idle event: %m");
goto out_unref_dbus;
out_unref_dbus:
dbus_connection_close(conn->conn);
dbus_connection_unref(conn->conn);
out_free:
free(conn);
errno = -res;
return NULL;
}

View file

@ -232,6 +232,20 @@ impl_init(const struct spa_handle_factory *factory,
break;
}
}
if (loop != NULL && this->system != NULL) {
this->source.func = on_trace_event;
this->source.data = this;
this->source.fd = spa_system_eventfd_create(this->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
this->source.mask = SPA_IO_IN;
this->source.rmask = 0;
if (this->source.fd != -1) {
spa_loop_add_source(loop, &this->source);
this->have_source = true;
} else {
fprintf(stderr, "Warning: failed to create eventfd: %m");
}
}
if (info) {
if ((str = spa_dict_lookup(info, SPA_KEY_LOG_COLORS)) != NULL)
this->colors = (strcmp(str, "true") == 0 || atoi(str) == 1);
@ -240,22 +254,12 @@ impl_init(const struct spa_handle_factory *factory,
if ((str = spa_dict_lookup(info, SPA_KEY_LOG_FILE)) != NULL) {
this->file = fopen(str, "w");
if (this->file == NULL)
fprintf(stderr, "failed to open file %s: (%s)", str, strerror(errno));
fprintf(stderr, "Warning: failed to open file %s: (%m)", str);
}
}
if (this->file == NULL)
this->file = stderr;
if (loop != NULL && this->system != NULL) {
this->source.func = on_trace_event;
this->source.data = this;
this->source.fd = spa_system_eventfd_create(this->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
this->source.mask = SPA_IO_IN;
this->source.rmask = 0;
spa_loop_add_source(loop, &this->source);
this->have_source = true;
}
spa_ringbuffer_init(&this->trace_rb);
spa_log_debug(&this->log, NAME " %p: initialized", this);
@ -290,8 +294,8 @@ impl_enum_interface_info(const struct spa_handle_factory *factory,
const struct spa_handle_factory spa_support_logger_factory = {
SPA_VERSION_HANDLE_FACTORY,
NAME,
NULL,
.name = NAME,
.info = NULL,
.get_size = impl_get_size,
.init = impl_init,
.enum_interface_info = impl_enum_interface_info,

View file

@ -280,18 +280,18 @@ static int loop_iterate(void *object, int timeout)
struct impl *impl = object;
struct spa_loop *loop = &impl->loop;
struct spa_poll_event ep[32];
int i, nfds, save_errno = 0;
int i, nfds, res = 0;
spa_loop_control_hook_before(&impl->hooks_list);
nfds = spa_system_pollfd_wait(impl->system, impl->poll_fd, ep, SPA_N_ELEMENTS(ep), timeout);
if (SPA_UNLIKELY(nfds < 0))
save_errno = errno;
res = -errno;
spa_loop_control_hook_after(&impl->hooks_list);
if (SPA_UNLIKELY(nfds < 0))
return save_errno;
return -res;
/* first we set all the rmasks, then call the callbacks. The reason is that
* some callback might also want to look at other sources it manages and
@ -323,10 +323,11 @@ static struct spa_source *loop_add_io(void *object,
{
struct impl *impl = object;
struct source_impl *source;
struct spa_source *res = NULL;
source = calloc(1, sizeof(struct source_impl));
if (source == NULL)
return NULL;
goto out;
source->source.loop = &impl->loop;
source->source.func = source_io_func;
@ -341,7 +342,9 @@ static struct spa_source *loop_add_io(void *object,
spa_list_insert(&impl->source_list, &source->link);
return &source->source;
res = &source->source;
out:
return res;
}
static int loop_update_io(void *object, struct spa_source *source, uint32_t mask)
@ -380,15 +383,22 @@ static struct spa_source *loop_add_idle(void *object,
{
struct impl *impl = object;
struct source_impl *source;
struct spa_source *res = NULL;
int err;
source = calloc(1, sizeof(struct source_impl));
if (source == NULL)
return NULL;
goto out;
source->source.loop = &impl->loop;
source->source.func = source_idle_func;
source->source.data = data;
source->source.fd = spa_system_eventfd_create(impl->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
if (source->source.fd == -1) {
err = -errno;
goto err_free;
}
source->impl = impl;
source->close = true;
source->source.mask = SPA_IO_IN;
@ -401,7 +411,14 @@ static struct spa_source *loop_add_idle(void *object,
if (enabled)
loop_enable_idle(impl, &source->source, true);
return &source->source;
res = &source->source;
out:
return res;
err_free:
free(source);
errno = -err;
goto out;
}
static void source_event_func(struct spa_source *source)
@ -422,15 +439,21 @@ static struct spa_source *loop_add_event(void *object,
{
struct impl *impl = object;
struct source_impl *source;
struct spa_source *res = NULL;
int err;
source = calloc(1, sizeof(struct source_impl));
if (source == NULL)
return NULL;
goto out;
source->source.loop = &impl->loop;
source->source.func = source_event_func;
source->source.data = data;
source->source.fd = spa_system_eventfd_create(impl->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
if (source->source.fd == -1) {
err = -errno;
goto err_free;
}
source->source.mask = SPA_IO_IN;
source->impl = impl;
source->close = true;
@ -440,7 +463,15 @@ static struct spa_source *loop_add_event(void *object,
spa_list_insert(&impl->source_list, &source->link);
return &source->source;
res = &source->source;
out:
return res;
err_free:
free(source);
errno = -err;
goto out;
}
static void loop_signal_event(void *object, struct spa_source *source)
@ -472,16 +503,22 @@ static struct spa_source *loop_add_timer(void *object,
{
struct impl *impl = object;
struct source_impl *source;
struct spa_source *res = NULL;
int err;
source = calloc(1, sizeof(struct source_impl));
if (source == NULL)
return NULL;
goto out;
source->source.loop = &impl->loop;
source->source.func = source_timer_func;
source->source.data = data;
source->source.fd = spa_system_timerfd_create(impl->system, CLOCK_MONOTONIC,
SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
if (source->source.fd == -1) {
err = -errno;
goto err_free;
}
source->source.mask = SPA_IO_IN;
source->impl = impl;
source->close = true;
@ -491,7 +528,14 @@ static struct spa_source *loop_add_timer(void *object,
spa_list_insert(&impl->source_list, &source->link);
return &source->source;
res = &source->source;
out:
return res;
err_free:
free(source);
errno = -err;
goto out;
}
static int
@ -538,10 +582,12 @@ static struct spa_source *loop_add_signal(void *object,
{
struct impl *impl = object;
struct source_impl *source;
struct spa_source *res = NULL;
int err;
source = calloc(1, sizeof(struct source_impl));
if (source == NULL)
return NULL;
goto out;
source->source.loop = &impl->loop;
source->source.func = source_signal_func;
@ -549,6 +595,10 @@ static struct spa_source *loop_add_signal(void *object,
source->source.fd = spa_system_signalfd_create(impl->system,
signal_number, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
if (source->source.fd == -1) {
err = -errno;
goto err_free;
}
source->source.mask = SPA_IO_IN;
source->impl = impl;
@ -559,7 +609,14 @@ static struct spa_source *loop_add_signal(void *object,
spa_list_insert(&impl->source_list, &source->link);
return &source->source;
res = &source->source;
out:
return res;
err_free:
free(source);
errno = -err;
goto out;
}
static void loop_destroy_source(void *object, struct spa_source *source)