Browse Source

[core] log_error, log_perror using printf-like fmt

personal/stbuehler/ci-build
Glenn Strauss 3 years ago
parent
commit
4183e723ce
  1. 2
      src/buffer.h
  2. 88
      src/log.c
  3. 8
      src/log.h

2
src/buffer.h

@ -178,6 +178,8 @@ void buffer_append_path_len(buffer *b, const char *a, size_t alen); /* join stri
#define BUFFER_COPY_STRING_CONST(x, y) \
buffer_copy_string_len(x, y, sizeof(y) - 1)
#define BUFFER_INTLEN_PTR(x) (x)->used ? (int)((x)->used - 1) : 0, (x)->ptr
#define CONST_STR_LEN(x) x, (x) ? sizeof(x) - 1 : 0
#define CONST_BUF_LEN(x) ((x) ? (x)->ptr : NULL), buffer_string_length(x)

88
src/log.c

@ -1,3 +1,8 @@
/* _XOPEN_SOURCE >= 500 for vsnprintf() */
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#endif
#include "first.h"
#include "base.h"
@ -8,6 +13,7 @@
#include <time.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h> /* vsnprintf() */
#include <stdlib.h> /* malloc() free() */
#include <unistd.h>
@ -218,6 +224,88 @@ int log_error_write_multiline_buffer(server *srv, const char *filename, unsigned
}
static void
log_buffer_vprintf (buffer * const b,
const char * const fmt, va_list ap)
{
/* NOTE: log_buffer_prepare() ensures 0 != b->used */
/*assert(0 != b->used);*//*(only because code calcs below assume this)*/
/*assert(0 != b->size);*//*(errh->b should not have 0 size here)*/
size_t blen = buffer_string_length(b);
size_t bsp = buffer_string_space(b)+1;
char *s = b->ptr + blen;
size_t n;
va_list aptry;
va_copy(aptry, ap);
n = (size_t)vsnprintf(s, bsp, fmt, aptry);
va_end(aptry);
if (n >= bsp) {
buffer_string_prepare_append(b, n); /*(must re-read s after realloc)*/
vsnprintf((s = b->ptr + blen), buffer_string_space(b)+1, fmt, ap);
}
size_t i;
for (i = 0; i < n && ' ' <= s[i] && s[i] <= '~'; ++i) ;/*(ASCII isprint())*/
if (i == n) {
buffer_string_set_length(b, blen + n);
return; /* common case; nothing to encode */
}
/* need to encode log line
* copy original line fragment, append encoded line to buffer, free copy */
char * const src = (char *)malloc(n);
memcpy(src, s, n); /*(note: not '\0'-terminated)*/
buffer_append_string_c_escaped(b, src, n);
free(src);
}
static void
log_error_va_list_impl (const log_error_st * const errh,
const char * const filename,
const unsigned int line,
const char * const fmt, va_list ap,
const int perr)
{
const int errnum = errno;
buffer * const b = errh->b;
if (-1 == log_buffer_prepare(errh, filename, line, b)) return;
log_buffer_vprintf(b, fmt, ap);
if (perr) {
buffer_append_string_len(b, CONST_STR_LEN(": "));
buffer_append_string(b, strerror(errnum));
}
log_write(errh, b);
errno = errnum;
}
void
log_error(const log_error_st * const errh,
const char * const filename, const unsigned int line,
const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
log_error_va_list_impl(errh, filename, line, fmt, ap, 0);
va_end(ap);
}
void
log_perror (const log_error_st * const errh,
const char * const filename, const unsigned int line,
const char * const fmt, ...)
{
va_list ap;
va_start(ap, fmt);
log_error_va_list_impl(errh, filename, line, fmt, ap, 1);
va_end(ap);
}
log_error_st *
log_error_st_init (time_t *cur_ts_ptr, time_t *last_ts_ptr)
{

8
src/log.h

@ -31,4 +31,12 @@ log_error_st * log_error_st_init (time_t *cur_ts_ptr, time_t *last_ts_ptr);
__attribute_cold__
void log_error_st_free (log_error_st *errh);
__attribute_cold__
__attribute_format__((__printf__, 4, 5))
void log_error(const log_error_st *errh, const char *filename, unsigned int line, const char *fmt, ...);
__attribute_cold__
__attribute_format__((__printf__, 4, 5))
void log_perror(const log_error_st *errh, const char *filename, unsigned int line, const char *fmt, ...);
#endif

Loading…
Cancel
Save