Write directly to FILE stream in glibc printf hooks
This commit is contained in:
@@ -86,25 +86,17 @@ static printf_hook_handler_t *printf_hooks[NUM_HANDLERS];
|
|||||||
static int custom_print(FILE *stream, const struct printf_info *info,
|
static int custom_print(FILE *stream, const struct printf_info *info,
|
||||||
const void *const *args)
|
const void *const *args)
|
||||||
{
|
{
|
||||||
int written;
|
|
||||||
char buf[PRINTF_BUF_LEN];
|
|
||||||
printf_hook_spec_t spec;
|
printf_hook_spec_t spec;
|
||||||
printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
|
printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
|
||||||
printf_hook_data_t data = {
|
printf_hook_data_t data = {
|
||||||
.buf = buf,
|
.stream = stream,
|
||||||
.buflen = sizeof(buf),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
spec.hash = info->alt;
|
spec.hash = info->alt;
|
||||||
spec.minus = info->left;
|
spec.minus = info->left;
|
||||||
spec.width = info->width;
|
spec.width = info->width;
|
||||||
|
|
||||||
written = handler->hook(&data, &spec, args);
|
return handler->hook(&data, &spec, args);
|
||||||
if (written > 0)
|
|
||||||
{
|
|
||||||
ignore_result(fwrite(buf, 1, written, stream));
|
|
||||||
}
|
|
||||||
return written;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -46,6 +46,29 @@ enum printf_hook_argtype_t {
|
|||||||
PRINTF_HOOK_ARGTYPE_POINTER = PA_POINTER,
|
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
|
#else
|
||||||
|
|
||||||
#include <vstr.h>
|
#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 vsnprintf vstr_wrapper_vsnprintf
|
||||||
#define vasprintf vstr_wrapper_vasprintf
|
#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.
|
* Data to pass to a printf hook.
|
||||||
*/
|
*/
|
||||||
@@ -131,6 +125,34 @@ struct printf_hook_data_t {
|
|||||||
size_t buflen;
|
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
|
* Properties of the format specifier
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user