diff --git a/src/utils/error.c b/src/utils/error.c
index 08a77f1c40b9007d9e05dd365dc9a6b07f5e15c3..fc360ebaa98b3f0741907e0d85fa79744f59add3 100644 (file)
--- a/src/utils/error.c
+++ b/src/utils/error.c
*/
#include "utils/error.h"
+#include "utils/strbuf.h"
#include <pthread.h>
typedef struct {
int prio;
- char msg[SDB_MAX_ERROR];
- _Bool finalized;
+ sdb_strbuf_t *msg;
+ _Bool logged;
} sdb_error_ctx_t;
-#define SDB_ERROR_INIT { -1, "", 1 }
+#define SDB_ERROR_INIT { -1, NULL, 1 }
/*
* private variables
*/
static void
-sdb_error_ctx_destructor(void *ctx)
+sdb_error_ctx_destructor(void *p)
{
+ sdb_error_ctx_t *ctx = p;
+
if (! ctx)
return;
+
+ sdb_strbuf_destroy(ctx->msg);
free(ctx);
} /* sdb_error_ctx_destructor */
return NULL;
*ctx = default_error_ctx;
+ ctx->msg = sdb_strbuf_create(64);
+ if (! ctx->msg) {
+ free(ctx);
+ return NULL;
+ }
if (! error_ctx_key_initialized)
sdb_error_ctx_init();
} /* sdb_error_get_ctx */
static int
-sdb_error_clear(void)
+sdb_error_vprintf(const char *fmt, va_list ap)
{
sdb_error_ctx_t *ctx;
if (! ctx)
return -1;
- ctx->prio = -1;
- ctx->msg[0] = '\0';
- ctx->finalized = 1;
- return 0;
-} /* sdb_error_clear */
+ ctx->logged = 0;
+ return (int)sdb_strbuf_vsprintf(ctx->msg, fmt, ap);
+} /* sdb_error_vprintf */
static int
-sdb_error_vappend(int prio, const char *fmt, va_list ap)
+sdb_error_vappend(const char *fmt, va_list ap)
{
sdb_error_ctx_t *ctx;
- size_t len;
ctx = sdb_error_get_ctx();
if (! ctx)
return -1;
- len = strlen(ctx->msg);
- if (len >= sizeof(ctx->msg))
- return 0; /* nothing written */
-
- if (prio >= 0)
- ctx->prio = prio;
-
- ctx->finalized = 0;
- return vsnprintf(ctx->msg + len, sizeof(ctx->msg) - len, fmt, ap);
+ ctx->logged = 0;
+ return (int)sdb_strbuf_vappend(ctx->msg, fmt, ap);
} /* sdb_error_vappend */
static int
-sdb_error_log(void)
+sdb_do_log(int prio)
{
sdb_error_ctx_t *ctx;
int ret;
if (! ctx)
return -1;
- if (ctx->finalized)
+ if (prio >= 0)
+ ctx->prio = prio;
+
+ if (ctx->logged)
return 0;
ret = fprintf(stderr, "[%s] %s\n",
- SDB_LOG_PRIO_TO_STRING(ctx->prio), ctx->msg);
- ctx->finalized = 1;
+ SDB_LOG_PRIO_TO_STRING(prio),
+ sdb_strbuf_string(ctx->msg));
+ ctx->logged = 1;
return ret;
-} /* sdb_error_log */
+} /* sdb_do_log */
/*
* public API
*/
int
-sdb_error_set(int prio, const char *fmt, ...)
+sdb_log(int prio, const char *fmt, ...)
{
va_list ap;
int ret;
- if (sdb_error_clear())
- return -1;
-
va_start(ap, fmt);
- ret = sdb_error_vappend(prio, fmt, ap);
+ ret = sdb_error_vprintf(fmt, ap);
va_end(ap);
- sdb_error_log();
+ if (ret > 0)
+ sdb_do_log(prio);
return ret;
-} /* sdb_error_set */
+} /* sdb_log */
int
-sdb_error_start(int prio, const char *fmt, ...)
+sdb_error_set(const char *fmt, ...)
{
va_list ap;
int ret;
- if (sdb_error_clear())
- return -1;
-
va_start(ap, fmt);
- ret = sdb_error_vappend(prio, fmt, ap);
+ ret = sdb_error_vprintf(fmt, ap);
va_end(ap);
return ret;
-} /* sdb_error_start */
+} /* sdb_error_set */
int
sdb_error_append(const char *fmt, ...)
int ret;
va_start(ap, fmt);
- ret = sdb_error_vappend(/* dont change prio */ -1, fmt, ap);
+ ret = sdb_error_vappend(fmt, ap);
va_end(ap);
return ret;
} /* sdb_error_append */
int
-sdb_error_finish(void)
+sdb_error_log(int prio)
{
- return sdb_error_log();
-} /* sdb_error_finish */
+ return sdb_do_log(prio);
+} /* sdb_error_log */
const char *
sdb_error_get(void)
ctx = sdb_error_get_ctx();
if (! ctx)
return "success";
- return ctx->msg;
+ return sdb_strbuf_string(ctx->msg);
} /* sdb_error_get */
int
return ctx->prio;
} /* sdb_error_get_prio */
+char *
+sdb_strerror(int errnum, char *strerrbuf, size_t buflen)
+{
+#if STRERROR_R_CHAR_P
+ {
+ char *tmp = strerror_r(errnum, strerrbuf, buflen);
+ if (*strerrbuf = '\0') {
+ if (tmp && (tmp != strerrbuf) && (*tmp != '\0'))
+ strncpy(strerrbuf, tmp, buflen);
+ else
+ snprintf(strerrbuf, buflen, "unknown error #%i "
+ "(strerror_r(3) did not return an error message)",
+ errnum);
+ }
+ }
+#else
+ if (strerror_r(errnum, strerrbuf, buflen))
+ snprintf(strerrbuf, buflen, "unknown error #%i "
+ "(strerror_r(3) failed)", errnum);
+#endif
+
+ strerrbuf[buflen - 1] = '\0';
+ return strerrbuf;
+} /* sdb_strerror */
+
/* vim: set tw=78 sw=4 ts=4 noexpandtab : */