From: Timo Sirainen Date: Fri, 4 Sep 2009 22:10:19 +0000 (-0400) Subject: Memory leak fixes. X-Git-Tag: 2.0.alpha1~171 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6ed1e82824590b514201d9db84ba96bdfc832dd5;p=thirdparty%2Fdovecot%2Fcore.git Memory leak fixes. --HG-- branch : HEAD --- diff --git a/src/config/config-filter.c b/src/config/config-filter.c index 3b6b4493d9..249376ee48 100644 --- a/src/config/config-filter.c +++ b/src/config/config-filter.c @@ -69,9 +69,12 @@ struct config_filter_context *config_filter_init(pool_t pool) void config_filter_deinit(struct config_filter_context **_ctx) { struct config_filter_context *ctx = *_ctx; + unsigned int i; *_ctx = NULL; + for (i = 0; ctx->parsers[i] != NULL; i++) + config_filter_parsers_free(ctx->parsers[i]->parsers); pool_unref(&ctx->pool); } @@ -158,9 +161,9 @@ config_module_parser_apply_changes(struct config_module_parser *dest, return 0; } -int config_filter_get_parsers(struct config_filter_context *ctx, pool_t pool, +int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool, const struct config_filter *filter, - const struct config_module_parser **parsers_r, + struct config_module_parser **parsers_r, const char **error_r) { struct config_filter_parser *const *src; @@ -190,6 +193,7 @@ int config_filter_get_parsers(struct config_filter_context *ctx, pool_t pool, if (config_module_parser_apply_changes(dest, src[i], pool, error_p) < 0) { + config_filter_parsers_free(dest); *error_r = error; return -1; } @@ -197,3 +201,11 @@ int config_filter_get_parsers(struct config_filter_context *ctx, pool_t pool, *parsers_r = dest; return 0; } + +void config_filter_parsers_free(struct config_module_parser *parsers) +{ + unsigned int i; + + for (i = 0; parsers[i].module_name != NULL; i++) + settings_parser_deinit(&parsers[i].parser); +} diff --git a/src/config/config-filter.h b/src/config/config-filter.h index 7e2db415ec..207aa4ac9e 100644 --- a/src/config/config-filter.h +++ b/src/config/config-filter.h @@ -25,10 +25,11 @@ void config_filter_add_all(struct config_filter_context *ctx, struct config_filter_parser *const *parsers); /* Build new parsers from all existing ones matching the given filter. */ -int config_filter_get_parsers(struct config_filter_context *ctx, pool_t pool, +int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool, const struct config_filter *filter, - const struct config_module_parser **parsers_r, + struct config_module_parser **parsers_r, const char **error_r); +void config_filter_parsers_free(struct config_module_parser *parsers); /* Returns TRUE if filter matches mask. */ bool config_filter_match(const struct config_filter *mask, diff --git a/src/config/config-parser.c b/src/config/config-parser.c index 623004b857..ebd005d1cd 100644 --- a/src/config/config-parser.c +++ b/src/config/config-parser.c @@ -273,25 +273,29 @@ config_all_parsers_check(struct parser_context *ctx, const char **error_r) { struct config_filter_parser *const *parsers; - const struct config_module_parser *tmp_parsers; + struct config_module_parser *tmp_parsers; unsigned int i, count; pool_t tmp_pool; + int ret = 0; tmp_pool = pool_alloconly_create("config parsers check", 1024*32); parsers = array_get(&ctx->all_parsers, &count); i_assert(count > 0 && parsers[count-1] == NULL); count--; - for (i = 0; i < count; i++) { - p_clear(tmp_pool); - if (config_filter_get_parsers(new_filter, tmp_pool, + for (i = 0; i < count && ret == 0; i++) { + if (config_filter_parsers_get(new_filter, tmp_pool, &parsers[i]->filter, - &tmp_parsers, error_r) < 0) + &tmp_parsers, error_r) < 0) { + ret = -1; break; + } - if (config_filter_parser_check(ctx, tmp_parsers, error_r) < 0) - break; + ret = config_filter_parser_check(ctx, tmp_parsers, error_r); + config_filter_parsers_free(tmp_parsers); + p_clear(tmp_pool); } - return i == count ? 0 : -1; + pool_unref(&tmp_pool); + return ret; } static int diff --git a/src/config/config-request.c b/src/config/config-request.c index 8f819c9d86..a3ce2f3d9f 100644 --- a/src/config/config-request.c +++ b/src/config/config-request.c @@ -236,16 +236,17 @@ int config_request_handle(const struct config_filter *filter, bool check_settings, config_request_callback_t *callback, void *context) { - const struct config_module_parser *l; + struct config_module_parser *parsers, *parser; struct settings_export_context ctx; const char *error; + unsigned int i; int ret = 0; memset(&ctx, 0, sizeof(ctx)); ctx.pool = pool_alloconly_create("config request", 1024*16); - if (config_filter_get_parsers(config_filter, ctx.pool, filter, - &l, &error) < 0) { + if (config_filter_parsers_get(config_filter, ctx.pool, filter, + &parsers, &error) < 0) { i_error("%s", error); pool_unref(&ctx.pool); return -1; @@ -259,16 +260,18 @@ int config_request_handle(const struct config_filter *filter, ctx.keys = hash_table_create(default_pool, ctx.pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); - for (; l->module_name != NULL; l++) { + for (i = 0; parsers[i].module_name != NULL; i++) { + parser = &parsers[i]; if (*module != '\0' && - !config_module_parser_is_in_service(l, module)) + !config_module_parser_is_in_service(parser, module)) continue; - settings_export(&ctx, l->root, settings_parser_get(l->parser), - settings_parser_get_changes(l->parser)); + settings_export(&ctx, parser->root, + settings_parser_get(parser->parser), + settings_parser_get_changes(parser->parser)); if (check_settings) { - if (!settings_parser_check(l->parser, ctx.pool, + if (!settings_parser_check(parser->parser, ctx.pool, &error)) { i_error("%s", error); ret = -1; @@ -276,6 +279,7 @@ int config_request_handle(const struct config_filter *filter, } } } + config_filter_parsers_free(parsers); hash_table_destroy(&ctx.keys); pool_unref(&ctx.pool); return ret; diff --git a/src/config/doveconf.c b/src/config/doveconf.c index fd020a9e98..04c24f4a63 100644 --- a/src/config/doveconf.c +++ b/src/config/doveconf.c @@ -168,6 +168,7 @@ static void config_dump_human(const struct config_filter *filter, o_stream_cork(output); config_connection_request_human(output, filter, module, scope); o_stream_uncork(output); + o_stream_unref(&output); } static void config_request_putenv(const char *key, const char *value, @@ -297,6 +298,7 @@ int main(int argc, char *argv[]) execvp(exec_args[0], exec_args); i_fatal("execvp(%s) failed: %m", exec_args[0]); } + config_filter_deinit(&config_filter); master_service_deinit(&master_service); return 0; } diff --git a/src/config/main.c b/src/config/main.c index 146845f774..dd449f3b21 100644 --- a/src/config/main.c +++ b/src/config/main.c @@ -36,6 +36,8 @@ int main(int argc, char *argv[]) master_service_run(master_service, client_connected); config_connections_destroy_all(); + + config_filter_deinit(&config_filter); master_service_deinit(&master_service); return 0; } diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index 151934dac0..749154d89a 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -488,6 +488,7 @@ void master_service_deinit(struct master_service **_service) lib_signals_deinit(); io_loop_destroy(&service->ioloop); + i_free(service->listeners); i_free(service->name); i_free(service); diff --git a/src/lib-settings/settings-parser.c b/src/lib-settings/settings-parser.c index 1538b00862..2da926d625 100644 --- a/src/lib-settings/settings-parser.c +++ b/src/lib-settings/settings-parser.c @@ -118,7 +118,6 @@ settings_parser_init_list(pool_t set_pool, i_assert(count > 0); - pool_ref(set_pool); parser_pool = pool_alloconly_create("settings parser", 16384); ctx = p_new(parser_pool, struct setting_parser_context, 1); ctx->set_pool = set_pool; @@ -1184,19 +1183,21 @@ settings_parser_dup(struct setting_parser_context *old_ctx, pool_t new_pool) struct hash_table *links; void *key, *value; unsigned int i; + pool_t parser_pool; pool_ref(new_pool); - new_ctx = p_new(new_pool, struct setting_parser_context, 1); + parser_pool = pool_alloconly_create("dup settings parser", 8192); + new_ctx = p_new(parser_pool, struct setting_parser_context, 1); new_ctx->set_pool = new_pool; - new_ctx->parser_pool = - pool_alloconly_create("dup settings parser", 8192); + new_ctx->parser_pool = parser_pool; new_ctx->flags = old_ctx->flags; new_ctx->str_vars_are_expanded = old_ctx->str_vars_are_expanded; new_ctx->linenum = old_ctx->linenum; new_ctx->error = p_strdup(new_ctx->parser_pool, old_ctx->error); new_ctx->prev_info = old_ctx->prev_info; - links = hash_table_create(default_pool, default_pool, 0, NULL, NULL); + links = hash_table_create(default_pool, new_ctx->parser_pool, + 0, NULL, NULL); new_ctx->root_count = old_ctx->root_count; new_ctx->roots = p_new(new_ctx->parser_pool, struct setting_link,