diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c index 8a2248b46..395ae65e3 100644 --- a/src/libstrongswan/settings.c +++ b/src/libstrongswan/settings.c @@ -444,6 +444,25 @@ METHOD(settings_t, get_str, char*, return def; } +METHOD(settings_t, alloc_str, char*, + private_settings_t *this, char *key, char *def, ...) +{ + char *value; + va_list args; + + va_start(args, def); + /* additional lock to savely strdup */ + this->lock->read_lock(this->lock); + value = strdupnull(find_value(this, this->top, key, args)); + this->lock->unlock(this->lock); + va_end(args); + if (value) + { + return value; + } + return def; +} + /** * Described in header */ @@ -1192,6 +1211,7 @@ settings_t *settings_create(char *file) INIT(this, .public = { .get_str = _get_str, + .alloc_str = _alloc_str, .get_int = _get_int, .get_double = _get_double, .get_time = _get_time, diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h index 9ccd02327..bc106e3a7 100644 --- a/src/libstrongswan/settings.h +++ b/src/libstrongswan/settings.h @@ -146,13 +146,31 @@ struct settings_t { /** * Get a settings value as a string. * + * This functions returns a string held by settings_t. It is not thread + * save, a thread calling load_files might free the returned string at + * any time. Use the thread save alloc_str if a different thread might + * call load_files() or set_str(). + * * @param key key including sections, printf style format * @param def value returned if key not found * @param ... argument list for key - * @return value pointing to internal string + * @return value pointing to internal string, not to be freed */ char* (*get_str)(settings_t *this, char *key, char *def, ...); + /** + * Get a settings value as a string, thread save variant. + * + * This function is identical to get_str, but is thread save. It allocates + * a copy for the returned string which must be freed. + * + * @param key key including sections, printf style format + * @param def value returned if key not found + * @param ... argument list for key + * @return allocated string, to be free + */ + char* (*alloc_str)(settings_t *this, char *key, char *def, ...); + /** * Get a boolean yes|no, true|false value. *