Mercurial > dovecot > core-2.2
changeset 9280:8e7809057f85 HEAD
settings_dup(): Copy only the settings, leave the rest of the struct zeroed out.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 14 May 2009 18:51:17 -0400 |
parents | 2da7dec937d4 |
children | 11e974e40f7b |
files | src/lib-settings/settings-parser.c |
diffstat | 1 files changed, 28 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-settings/settings-parser.c Thu May 14 17:20:51 2009 -0400 +++ b/src/lib-settings/settings-parser.c Thu May 14 18:51:17 2009 -0400 @@ -847,6 +847,18 @@ return FALSE; } +static void settings_set_parent(const struct setting_parser_info *info, + void *child, void *parent) +{ + void **ptr; + + if (info->parent_offset == (size_t)-1) + return; + + ptr = PTR_OFFSET(child, info->parent_offset); + *ptr = parent; +} + void *settings_dup(const struct setting_parser_info *info, const void *set, pool_t pool) { @@ -855,17 +867,27 @@ void *dest_set, *dest, *const *children; unsigned int i, count; + /* don't just copy everything from set to dest_set. it may contain + some non-setting fields allocated from the original pool. */ dest_set = p_malloc(pool, info->struct_size); - memcpy(dest_set, set, info->struct_size); for (def = info->defines; def->key != NULL; def++) { src = CONST_PTR_OFFSET(set, def->offset); dest = PTR_OFFSET(dest_set, def->offset); switch (def->type) { - case SET_INTERNAL: - case SET_BOOL: - case SET_UINT: + case SET_BOOL: { + const bool *src_bool = src; + bool *dest_bool = dest; + + *dest_bool = *src_bool; + } + case SET_UINT: { + const unsigned int *src_uint = src; + unsigned int *dest_uint = dest; + + *dest_uint = *src_uint; break; + } case SET_STR_VARS: case SET_STR: case SET_ENUM: { @@ -889,6 +911,8 @@ child_set = settings_dup(def->list_info, children[i], pool); array_append(dest_arr, &child_set, 1); + settings_set_parent(def->list_info, child_set, + dest_set); } break; }