From 5761d2c1bf8e9824a04883b42d2b6ee41da206ad Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 13 Dec 2011 17:56:40 +0100 Subject: Add goto based error-path cleanup to main --- src/interface.c | 8 +++--- src/interface.h | 2 +- src/pa-sink-ctl.c | 81 ++++++++++++++++++++++++++++++------------------------- src/pa-sink-ctl.h | 1 + 4 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/interface.c b/src/interface.c index 43b38b8..905ffa3 100644 --- a/src/interface.c +++ b/src/interface.c @@ -241,7 +241,7 @@ resize_gio(GIOChannel *source, GIOCondition condition, gpointer data) } #endif -void +int interface_init(struct context *ctx) { GIOChannel *input_channel; @@ -279,7 +279,7 @@ interface_init(struct context *ctx) sigaddset(&mask, SIGWINCH); if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) - exit(EXIT_FAILURE); + return -1; ctx->signal_fd = signalfd(-1, &mask, 0); channel = g_io_channel_unix_new(ctx->signal_fd); ctx->resize_source_id = @@ -293,10 +293,12 @@ interface_init(struct context *ctx) #endif input_channel = g_io_channel_unix_new(STDIN_FILENO); if (!input_channel) - exit(EXIT_FAILURE); + return -1; ctx->input_source_id = g_io_add_watch(input_channel, G_IO_IN, interface_get_input, ctx); g_io_channel_unref(input_channel); refresh(); + + return 0; } diff --git a/src/interface.h b/src/interface.h index 84a794b..abd6341 100644 --- a/src/interface.h +++ b/src/interface.h @@ -31,7 +31,7 @@ struct context; void interface_redraw(struct context *ctx); -void +int interface_init(struct context *ctx); void diff --git a/src/pa-sink-ctl.c b/src/pa-sink-ctl.c index 0c03cf4..7dfe187 100644 --- a/src/pa-sink-ctl.c +++ b/src/pa-sink-ctl.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "sink.h" #include "interface.h" @@ -318,61 +319,67 @@ change_callback(pa_context* c, gint success, gpointer userdata) int main(int argc, char** argv) { - struct context *ctx = g_new0(struct context, 1); + struct context ctx; pa_mainloop_api *mainloop_api = NULL; pa_glib_mainloop *m = NULL; - ctx->sink_list = NULL; - ctx->input_list = NULL; - ctx->max_name_len = 0; - ctx->context_ready = FALSE; + memset(&ctx, 0, sizeof ctx); + + ctx.sink_list = NULL; + ctx.input_list = NULL; + ctx.max_name_len = 0; + ctx.context_ready = FALSE; + ctx.return_value = 1; - ctx->loop = g_main_loop_new(NULL, FALSE); + ctx.loop = g_main_loop_new(NULL, FALSE); + if (!ctx.loop) + goto cleanup_context; - if (config_init(&ctx->config) < 0) - return -1; + if (config_init(&ctx.config) < 0) + goto cleanup_loop; - interface_init(ctx); + if (interface_init(&ctx) < 0) + goto cleanup_config; if (!(m = pa_glib_mainloop_new(NULL))) { - interface_clear(ctx); - g_printerr("pa_glib_mainloop_newfailed\n"); - return -1; + g_printerr("pa_glib_mainloop_new failed\n"); + goto cleanup_interface; } - mainloop_api = pa_glib_mainloop_get_api(m); - if (!(ctx->context = pa_context_new(mainloop_api, "pa-sink-ctl"))) { - interface_clear(ctx); - g_printerr("pa_context_new failed: %s\n", - pa_strerror(pa_context_errno(ctx->context))); - return -1; + if (!(ctx.context = pa_context_new(mainloop_api, "pa-sink-ctl"))) { + char *s = g_strdup_printf("pa_context_new failed: %s\n", + pa_strerror(pa_context_errno(ctx.context))); + interface_set_status(&ctx, s); + g_free(s); } // define callback for connection init - pa_context_set_state_callback(ctx->context, - context_state_callback, ctx); - if (pa_context_connect(ctx->context, NULL, + pa_context_set_state_callback(ctx.context, + context_state_callback, &ctx); + if (pa_context_connect(ctx.context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL)) { - interface_clear(ctx); - g_printerr("pa_context_connect failed: %s\n", - pa_strerror(pa_context_errno(ctx->context))); - return -1; + char *s = g_strdup_printf("pa_context_connect failed: %s\n", + pa_strerror(pa_context_errno(ctx.context))); + interface_set_status(&ctx, s); + g_free(s); } - g_main_loop_run(ctx->loop); + ctx.return_value = 0; + g_main_loop_run(ctx.loop); - interface_clear(ctx); - g_list_free_full(ctx->sink_list, sink_free); - g_list_free_full(ctx->input_list, sink_input_free); + g_list_free_full(ctx.sink_list, sink_free); + g_list_free_full(ctx.input_list, sink_input_free); + pa_context_unref(ctx.context); pa_glib_mainloop_free(m); - pa_context_unref(ctx->context); - g_main_loop_unref(ctx->loop); - - config_uninit(&ctx->config); - - g_free(ctx); - - return 0; +cleanup_interface: + interface_clear(&ctx); +cleanup_config: + config_uninit(&ctx.config); +cleanup_loop: + g_main_loop_unref(ctx.loop); +cleanup_context: + + return ctx.return_value; } diff --git a/src/pa-sink-ctl.h b/src/pa-sink-ctl.h index f56b17c..a59f18b 100644 --- a/src/pa-sink-ctl.h +++ b/src/pa-sink-ctl.h @@ -53,6 +53,7 @@ struct context { gchar *status; struct config config; + int return_value; }; void -- cgit