diff options
Diffstat (limited to 'src/libstrongswan/printf_hook.c')
-rw-r--r-- | src/libstrongswan/printf_hook.c | 100 |
1 files changed, 79 insertions, 21 deletions
diff --git a/src/libstrongswan/printf_hook.c b/src/libstrongswan/printf_hook.c index 037f0b918..4d4cef829 100644 --- a/src/libstrongswan/printf_hook.c +++ b/src/libstrongswan/printf_hook.c @@ -133,6 +133,14 @@ static int custom_arginfo(const struct printf_info *info, size_t n, int *argtype #include <unistd.h> /* for STDOUT_FILENO */ /** + * These are used below, whenever the public wrapper functions are called before + * initialization or after destruction. + */ +#undef vprintf +#undef vfprintf +#undef vsnprintf + +/** * Vstr custom format specifier callback function. */ static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec) @@ -177,13 +185,16 @@ static void vstr_fmt_add_handler(Vstr_conf *conf, printf_hook_handler_t *handler switch(handler->numargs) { case 1: - vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0], VSTR_TYPE_FMT_END); + vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0], + VSTR_TYPE_FMT_END); break; case 2: - vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0], at[1], VSTR_TYPE_FMT_END); + vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0], + at[1], VSTR_TYPE_FMT_END); break; case 3: - vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0], at[1], at[2], VSTR_TYPE_FMT_END); + vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0], + at[1], at[2], VSTR_TYPE_FMT_END); break; } } @@ -193,7 +204,7 @@ static void vstr_fmt_add_handler(Vstr_conf *conf, printf_hook_handler_t *handler */ #include <threading/thread_value.h> -static thread_value_t *vstr_conf; +static thread_value_t *vstr_conf = NULL; static Vstr_conf *create_vstr_conf() { @@ -216,12 +227,15 @@ static Vstr_conf *create_vstr_conf() static inline Vstr_conf *get_vstr_conf() { - Vstr_conf *conf; - conf = (Vstr_conf*)vstr_conf->get(vstr_conf); - if (!conf) + Vstr_conf *conf = NULL; + if (vstr_conf) { - conf = create_vstr_conf(); - vstr_conf->set(vstr_conf, conf); + conf = (Vstr_conf*)vstr_conf->get(vstr_conf); + if (!conf) + { + conf = create_vstr_conf(); + vstr_conf->set(vstr_conf, conf); + } } return conf; } @@ -265,11 +279,20 @@ int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...) va_end(args); return written; } -static inline int vstr_wrapper_vprintf_internal(int fd, const char *format, +int vstr_wrapper_asprintf(char **str, const char *format, ...) +{ + int written; + va_list args; + va_start(args, format); + written = vstr_wrapper_vasprintf(str, format, args); + va_end(args); + return written; +} +static inline int vstr_wrapper_vprintf_internal(Vstr_conf *conf, int fd, + const char *format, va_list args) { int written; - Vstr_conf *conf = get_vstr_conf(); Vstr_base *s = vstr_make_base(conf); vstr_add_vfmt(s, 0, format, args); written = s->len; @@ -289,24 +312,39 @@ static inline int vstr_wrapper_vprintf_internal(int fd, const char *format, } int vstr_wrapper_vprintf(const char *format, va_list args) { - return vstr_wrapper_vprintf_internal(STDOUT_FILENO, format, args); + Vstr_conf *conf = get_vstr_conf(); + if (conf) + { + return vstr_wrapper_vprintf_internal(conf, STDOUT_FILENO, format, args); + } + return vprintf(format, args); } int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list args) { - return vstr_wrapper_vprintf_internal(fileno(stream), format, args); + Vstr_conf *conf = get_vstr_conf(); + if (conf) + { + return vstr_wrapper_vprintf_internal(conf, fileno(stream), format, + args); + } + return vfprintf(stream, format, args); } static inline int vstr_wrapper_vsnprintf_internal(char *str, size_t size, const char *format, va_list args) { - int written; Vstr_conf *conf = get_vstr_conf(); - Vstr_base *s = vstr_make_base(conf); - vstr_add_vfmt(s, 0, format, args); - written = s->len; - vstr_export_cstr_buf(s, 1, s->len, str, (size > 0) ? size : s->len + 1); - vstr_free_base(s); - return written; + if (conf) + { + int written; + Vstr_base *s = vstr_make_base(conf); + vstr_add_vfmt(s, 0, format, args); + written = s->len; + vstr_export_cstr_buf(s, 1, s->len, str, (size > 0) ? size : s->len + 1); + vstr_free_base(s); + return written; + } + return vsnprintf(str, size, format, args); } int vstr_wrapper_vsprintf(char *str, const char *format, va_list args) { @@ -317,7 +355,26 @@ int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format, { return (size > 0) ? vstr_wrapper_vsnprintf_internal(str, size, format, args) : 0; } - +int vstr_wrapper_vasprintf(char **str, const char *format, va_list args) +{ + size_t len = 100; + int written; + *str = malloc(len); + while (TRUE) + { + va_list ac; + va_copy(ac, args); + written = vstr_wrapper_vsnprintf_internal(*str, len, format, ac); + va_end(ac); + if (written < len) + { + break; + } + len = written + 1; + *str = realloc(*str, len); + } + return written; +} #endif /** @@ -408,6 +465,7 @@ static void destroy(private_printf_hook_t *this) #ifdef USE_VSTR /* freeing the Vstr_conf of the main thread */ vstr_conf->destroy(vstr_conf); + vstr_conf = NULL; vstr_free_conf(conf); vstr_exit(); #endif |