diff options
Diffstat (limited to 'src/libstrongswan/printf_hook.c')
-rw-r--r-- | src/libstrongswan/printf_hook.c | 77 |
1 files changed, 41 insertions, 36 deletions
diff --git a/src/libstrongswan/printf_hook.c b/src/libstrongswan/printf_hook.c index 692ad9cf8..0b516c99e 100644 --- a/src/libstrongswan/printf_hook.c +++ b/src/libstrongswan/printf_hook.c @@ -44,17 +44,17 @@ struct private_printf_hook_t { * struct with information about a registered handler */ struct printf_hook_handler_t { - + /** * callback function */ printf_hook_function_t hook; - + /** * number of arguments */ int numargs; - + /** * types of the arguments */ @@ -75,7 +75,8 @@ static printf_hook_handler_t *printf_hooks[NUM_HANDLERS]; #define SPEC_TO_INDEX(spec) ((int)(spec) - (int)'A') #define IS_VALID_SPEC(spec) (SPEC_TO_INDEX(spec) > -1 && SPEC_TO_INDEX(spec) < NUM_HANDLERS) -#if defined(HAVE_PRINTF_HOOKS) && !defined(USE_VSTR) +#if !defined(USE_VSTR) && \ + (defined(HAVE_PRINTF_FUNCTION) || defined(HAVE_PRINTF_SPECIFIER)) /** * Printf hook print function. This is actually of type "printf_function", @@ -89,11 +90,11 @@ static int custom_print(FILE *stream, const struct printf_info *info, char buf[PRINTF_BUF_LEN]; printf_hook_spec_t spec; printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)]; - + spec.hash = info->alt; spec.minus = info->left; spec.width = info->width; - + written = handler->hook(buf, sizeof(buf), &spec, args); if (written > 0) { @@ -104,13 +105,17 @@ static int custom_print(FILE *stream, const struct printf_info *info, /** * Printf hook arginfo function, which is actually of type - * "printf_arginfo_function". + * "printf_arginfo_[size_]function". */ -static int custom_arginfo(const struct printf_info *info, size_t n, int *argtypes) +static int custom_arginfo(const struct printf_info *info, size_t n, int *argtypes +#ifdef HAVE_PRINTF_SPECIFIER + , int *size +#endif + ) { int i; printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)]; - + if (handler->numargs <= n) { for (i = 0; i < handler->numargs; ++i) @@ -118,6 +123,7 @@ static int custom_arginfo(const struct printf_info *info, size_t n, int *argtype argtypes[i] = handler->argtypes[i]; } } + /* we never set "size", as we have no user defined types */ return handler->numargs; } @@ -136,7 +142,7 @@ static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec) const void *args[ARGS_MAX]; printf_hook_spec_t spec; printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(fmt_spec->name[0])]; - + for (i = 0; i < handler->numargs; i++) { switch(handler->argtypes[i]) @@ -149,11 +155,11 @@ static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec) break; } } - + spec.hash = fmt_spec->fmt_hash; spec.minus = fmt_spec->fmt_minus; spec.width = fmt_spec->fmt_field_width; - + written = handler->hook(buf, sizeof(buf), &spec, args); if (written > 0) { @@ -185,15 +191,9 @@ static void vstr_fmt_add_handler(Vstr_conf *conf, printf_hook_handler_t *handler /** * Management of thread-specific Vstr_conf objects */ -#include <pthread.h> - -static pthread_key_t vstr_conf_key; -static pthread_once_t vstr_conf_key_once = PTHREAD_ONCE_INIT; +#include <threading/thread_value.h> -static void init_vstr_conf_key(void) -{ - pthread_key_create(&vstr_conf_key, (void*)vstr_free_conf); -} +static thread_value_t *vstr_conf; static Vstr_conf *create_vstr_conf() { @@ -217,12 +217,11 @@ static Vstr_conf *create_vstr_conf() static inline Vstr_conf *get_vstr_conf() { Vstr_conf *conf; - pthread_once(&vstr_conf_key_once, init_vstr_conf_key); - conf = (Vstr_conf*)pthread_getspecific(vstr_conf_key); + conf = (Vstr_conf*)vstr_conf->get(vstr_conf); if (!conf) { conf = create_vstr_conf(); - pthread_setspecific(vstr_conf_key, conf); + vstr_conf->set(vstr_conf, conf); } return conf; } @@ -331,16 +330,16 @@ static void add_handler(private_printf_hook_t *this, char spec, printf_hook_handler_t *handler; printf_hook_argtype_t argtype; va_list args; - + if (!IS_VALID_SPEC(spec)) { DBG1("'%c' is not a valid printf hook specifier, not registered!", spec); return; } - + handler = malloc_thing(printf_hook_handler_t); handler->hook = hook; - + va_start(args, hook); while ((argtype = va_arg(args, printf_hook_argtype_t)) != PRINTF_HOOK_ARGTYPE_END) { @@ -354,13 +353,18 @@ static void add_handler(private_printf_hook_t *this, char spec, handler->argtypes[i] = argtype; } va_end(args); - + handler->numargs = i + 1; - + if (handler->numargs > 0) { -#if defined(HAVE_PRINTF_HOOKS) && !defined(USE_VSTR) +#if !defined(USE_VSTR) && \ + (defined(HAVE_PRINTF_FUNCTION) || defined(HAVE_PRINTF_SPECIFIER)) +# ifdef HAVE_PRINTF_SPECIFIER + register_printf_specifier(spec, custom_print, custom_arginfo); +# else register_printf_function(spec, custom_print, custom_arginfo); +# endif #else Vstr_conf *conf = get_vstr_conf(); handler->name = malloc(2); @@ -385,7 +389,7 @@ static void destroy(private_printf_hook_t *this) #ifdef USE_VSTR Vstr_conf *conf = get_vstr_conf(); #endif - + for (i = 0; i < NUM_HANDLERS; ++i) { printf_hook_handler_t *handler = printf_hooks[i]; @@ -398,10 +402,10 @@ static void destroy(private_printf_hook_t *this) free(handler); } } - + #ifdef USE_VSTR /* freeing the Vstr_conf of the main thread */ - pthread_key_delete(vstr_conf_key); + vstr_conf->destroy(vstr_conf); vstr_free_conf(conf); vstr_exit(); #endif @@ -414,12 +418,12 @@ static void destroy(private_printf_hook_t *this) printf_hook_t *printf_hook_create() { private_printf_hook_t *this = malloc_thing(private_printf_hook_t); - + this->public.add_handler = (void(*)(printf_hook_t*, char, printf_hook_function_t, ...))add_handler; this->public.destroy = (void(*)(printf_hook_t*))destroy; - + memset(printf_hooks, 0, sizeof(printf_hooks)); - + #ifdef USE_VSTR if (!vstr_init()) { @@ -427,8 +431,9 @@ printf_hook_t *printf_hook_create() free(this); return NULL; } + vstr_conf = thread_value_create((thread_cleanup_t)vstr_free_conf); #endif - + return &this->public; } |