Write directly to FILE stream in glibc printf hooks

This commit is contained in:
Martin Willi
2012-07-13 13:23:29 +02:00
parent 1b40b74de0
commit 4addc415a5
2 changed files with 53 additions and 39 deletions
+2 -10
View File
@@ -86,25 +86,17 @@ static printf_hook_handler_t *printf_hooks[NUM_HANDLERS];
static int custom_print(FILE *stream, const struct printf_info *info,
const void *const *args)
{
int written;
char buf[PRINTF_BUF_LEN];
printf_hook_spec_t spec;
printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
printf_hook_data_t data = {
.buf = buf,
.buflen = sizeof(buf),
.stream = stream,
};
spec.hash = info->alt;
spec.minus = info->left;
spec.width = info->width;
written = handler->hook(&data, &spec, args);
if (written > 0)
{
ignore_result(fwrite(buf, 1, written, stream));
}
return written;
return handler->hook(&data, &spec, args);
}
/**
+51 -29
View File
@@ -46,6 +46,29 @@ enum printf_hook_argtype_t {
PRINTF_HOOK_ARGTYPE_POINTER = PA_POINTER,
};
/**
* Data to pass to a printf hook.
*/
struct printf_hook_data_t {
/**
* Output FILE stream
*/
FILE *stream;;
};
/**
* Helper macro to be used in printf hook callbacks.
*/
#define print_in_hook(data, fmt, ...) ({\
int _written = fprintf(data->stream, fmt, ##__VA_ARGS__);\
if (_written < 0)\
{\
_written = 0;\
}\
_written;\
})
#else
#include <vstr.h>
@@ -86,35 +109,6 @@ int vstr_wrapper_vasprintf(char **str, const char *format, va_list ap);
#define vsnprintf vstr_wrapper_vsnprintf
#define vasprintf vstr_wrapper_vasprintf
#endif
/**
* Callback function type for printf hooks.
*
* @param data hook data, to pass to print_in_hook()
* @param spec format specifier
* @param args arguments array
* @return number of characters written
*/
typedef int (*printf_hook_function_t)(printf_hook_data_t *data,
printf_hook_spec_t *spec,
const void *const *args);
/**
* Helper macro to be used in printf hook callbacks.
* buf and buflen get modified.
*/
#define print_in_hook(data, fmt, ...) ({\
int _written = snprintf(data->buf, data->buflen, fmt, ##__VA_ARGS__);\
if (_written < 0 || _written >= data->buflen)\
{\
_written = data->buflen - 1;\
}\
data->buf += _written;\
data->buflen -= _written;\
_written;\
})
/**
* Data to pass to a printf hook.
*/
@@ -131,6 +125,34 @@ struct printf_hook_data_t {
size_t buflen;
};
/**
* Helper macro to be used in printf hook callbacks.
*/
#define print_in_hook(data, fmt, ...) ({\
int _written = snprintf(data->buf, data->buflen, fmt, ##__VA_ARGS__);\
if (_written < 0 || _written >= data->buflen)\
{\
_written = data->buflen - 1;\
}\
data->buf += _written;\
data->buflen -= _written;\
_written;\
})
#endif
/**
* Callback function type for printf hooks.
*
* @param data hook data, to pass to print_in_hook()
* @param spec format specifier
* @param args arguments array
* @return number of characters written
*/
typedef int (*printf_hook_function_t)(printf_hook_data_t *data,
printf_hook_spec_t *spec,
const void *const *args);
/**
* Properties of the format specifier
*/