From: Ingo Bürk Date: Sun, 3 Dec 2017 18:51:25 +0000 (+0100) Subject: Merge pull request #3022 from orestisf1993/i3bar-leaks X-Git-Tag: 4.15~34 X-Git-Url: https://git.sur5r.net/?p=i3%2Fi3;a=commitdiff_plain;h=458e2a2e46027844d733540ddea1701fcfca230a;hp=730264d9b2032805247584b2bd556dc0b2b1185e Merge pull request #3022 from orestisf1993/i3bar-leaks Fix i3bar leaks --- diff --git a/i3bar/include/outputs.h b/i3bar/include/outputs.h index de960270..29a7bcd3 100644 --- a/i3bar/include/outputs.h +++ b/i3bar/include/outputs.h @@ -33,6 +33,12 @@ void parse_outputs_json(char* json); */ void init_outputs(void); +/* + * free() all outputs data structures. + * + */ +void free_outputs(void); + /* * Returns the output with the given name * diff --git a/i3bar/src/child.c b/i3bar/src/child.c index fe989c44..170fcdef 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -106,7 +106,7 @@ __attribute__((format(printf, 1, 2))) static void set_statusline_error(const cha va_list args; va_start(args, format); if (vasprintf(&message, format, args) == -1) { - return; + goto finish; } struct status_block *err_block = scalloc(1, sizeof(struct status_block)); @@ -124,6 +124,7 @@ __attribute__((format(printf, 1, 2))) static void set_statusline_error(const cha TAILQ_INSERT_HEAD(&statusline_head, err_block, blocks); TAILQ_INSERT_TAIL(&statusline_head, message_block, blocks); +finish: FREE(message); va_end(args); } diff --git a/i3bar/src/config.c b/i3bar/src/config.c index b98d4123..79e106c0 100644 --- a/i3bar/src/config.c +++ b/i3bar/src/config.c @@ -192,6 +192,7 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len if (!strcmp(cur_key, "font")) { DLOG("font = %.*s\n", len, val); + FREE(config.fontname); sasprintf(&config.fontname, "%.*s", len, val); return 1; } diff --git a/i3bar/src/ipc.c b/i3bar/src/ipc.c index 49c729ae..cc3563ec 100644 --- a/i3bar/src/ipc.c +++ b/i3bar/src/ipc.c @@ -64,17 +64,14 @@ void got_subscribe_reply(char *reply) { */ void got_output_reply(char *reply) { DLOG("Clearing old output configuration...\n"); - i3_output *o_walk; - SLIST_FOREACH(o_walk, outputs, slist) { - destroy_window(o_walk); - } - FREE_SLIST(outputs, i3_output); + free_outputs(); DLOG("Parsing outputs JSON...\n"); parse_outputs_json(reply); DLOG("Reconfiguring windows...\n"); reconfig_windows(false); + i3_output *o_walk; SLIST_FOREACH(o_walk, outputs, slist) { kick_tray_clients(o_walk); } diff --git a/i3bar/src/main.c b/i3bar/src/main.c index 910e9524..069803d4 100644 --- a/i3bar/src/main.c +++ b/i3bar/src/main.c @@ -182,7 +182,5 @@ int main(int argc, char **argv) { clean_xcb(); ev_default_destroy(); - free_workspaces(); - return 0; } diff --git a/i3bar/src/outputs.c b/i3bar/src/outputs.c index bd056a70..4c9ce651 100644 --- a/i3bar/src/outputs.c +++ b/i3bar/src/outputs.c @@ -173,6 +173,12 @@ static int outputs_start_map_cb(void *params_) { return 1; } +static void clear_output(i3_output *output) { + FREE(output->name); + FREE(output->workspaces); + FREE(output->trayclients); +} + /* * We hit the end of a map (rect or a new output) * @@ -199,9 +205,7 @@ static int outputs_end_map_cb(void *params_) { if (!handle_output) { DLOG("Ignoring output \"%s\", not configured to handle it.\n", params->outputs_walk->name); - FREE(params->outputs_walk->name); - FREE(params->outputs_walk->workspaces); - FREE(params->outputs_walk->trayclients); + clear_output(params->outputs_walk); FREE(params->outputs_walk); FREE(params->cur_key); return 1; @@ -217,6 +221,9 @@ static int outputs_end_map_cb(void *params_) { target->primary = params->outputs_walk->primary; target->ws = params->outputs_walk->ws; target->rect = params->outputs_walk->rect; + + clear_output(params->outputs_walk); + FREE(params->outputs_walk); } return 1; } @@ -260,7 +267,6 @@ void init_outputs(void) { */ void parse_outputs_json(char *json) { struct outputs_json_params params; - params.outputs_walk = NULL; params.cur_key = NULL; params.json = json; @@ -286,6 +292,27 @@ void parse_outputs_json(char *json) { yajl_free(handle); } +/* + * free() all outputs data structures. + * + */ +void free_outputs(void) { + free_workspaces(); + + i3_output *outputs_walk; + if (outputs == NULL) { + return; + } + SLIST_FOREACH(outputs_walk, outputs, slist) { + destroy_window(outputs_walk); + if (outputs_walk->trayclients != NULL && !TAILQ_EMPTY(outputs_walk->trayclients)) { + FREE_TAILQ(outputs_walk->trayclients, trayclient); + } + clear_output(outputs_walk); + } + FREE_SLIST(outputs, i3_output); +} + /* * Returns the output with the given name * diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 98f0dcbe..1a9240fb 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -1499,16 +1499,7 @@ void init_tray_colors(void) { * */ void clean_xcb(void) { - i3_output *o_walk; - free_workspaces(); - SLIST_FOREACH(o_walk, outputs, slist) { - destroy_window(o_walk); - FREE(o_walk->trayclients); - FREE(o_walk->workspaces); - FREE(o_walk->name); - } - FREE_SLIST(outputs, i3_output); - FREE(outputs); + free_outputs(); free_font();