summaryrefslogtreecommitdiff
path: root/src/libstrongswan/printf_hook.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/printf_hook.c')
-rw-r--r--src/libstrongswan/printf_hook.c77
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;
}