X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Futils%2Ferror.c;h=2bc99013ebe719199b7f53b2665f5e43dd7a95ae;hb=9d80882865895b9eaebc56e878ad5c3c27f8dddb;hp=34213b319501a7ca13e1d5d10843c6ceb295f4fe;hpb=19d7d13262095deccad56275584aef7c2e6c5dee;p=sysdb.git diff --git a/src/utils/error.c b/src/utils/error.c index 34213b3..2bc9901 100644 --- a/src/utils/error.c +++ b/src/utils/error.c @@ -25,12 +25,19 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#if HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + #include "utils/error.h" +#include "utils/strbuf.h" #include #include +#include #include +#include #include /* @@ -39,10 +46,10 @@ 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 @@ -51,19 +58,33 @@ typedef struct { static sdb_error_ctx_t default_error_ctx = SDB_ERROR_INIT; static pthread_key_t error_ctx_key; -static _Bool error_ctx_key_initialized = 0; +static bool error_ctx_key_initialized = 0; + +static int (*logger)(int prio, const char *msg) = NULL; /* * private helper functions */ +static void +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 */ + static void sdb_error_ctx_init(void) { if (error_ctx_key_initialized) return; - pthread_key_create(&error_ctx_key, NULL); + pthread_key_create(&error_ctx_key, sdb_error_ctx_destructor); error_ctx_key_initialized = 1; } /* sdb_error_init */ @@ -77,6 +98,11 @@ sdb_error_ctx_create(void) 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(); @@ -101,7 +127,7 @@ sdb_error_get_ctx(void) } /* sdb_error_get_ctx */ static int -sdb_error_clear(void) +sdb_error_vprintf(const char *fmt, va_list ap) { sdb_error_ctx_t *ctx; @@ -109,35 +135,25 @@ sdb_error_clear(void) 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; @@ -146,51 +162,65 @@ sdb_error_log(void) 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; + if (logger) + ret = logger(prio, sdb_strbuf_string(ctx->msg)); + else + ret = fprintf(stderr, "[%s] %s\n", SDB_LOG_PRIO_TO_STRING(prio), + sdb_strbuf_string(ctx->msg)); + + ctx->logged = 1; return ret; -} /* sdb_error_log */ +} /* sdb_do_log */ /* * public API */ +void +sdb_error_set_logger(int (*f)(int, const char *)) +{ + logger = f; +} /* sdb_error_set_logger */ + 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_vlog(prio, fmt, ap); va_end(ap); + return ret; +} /* sdb_log */ - sdb_error_log(); +int +sdb_vlog(int prio, const char *fmt, va_list ap) +{ + int ret = sdb_error_vprintf(fmt, ap); + if (ret > 0) + sdb_do_log(prio); return ret; -} /* sdb_error_set */ +} /* sdb_vlog */ 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, ...) @@ -199,17 +229,30 @@ 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_chomp(void) { - return sdb_error_log(); -} /* sdb_error_finish */ + sdb_error_ctx_t *ctx; + + ctx = sdb_error_get_ctx(); + if (! ctx) + return -1; + + sdb_strbuf_chomp(ctx->msg); + return 0; +} /* sdb_error_chomp */ + +int +sdb_error_log(int prio) +{ + return sdb_do_log(prio); +} /* sdb_error_log */ const char * sdb_error_get(void) @@ -219,7 +262,7 @@ 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 @@ -233,5 +276,48 @@ sdb_error_get_prio(void) return ctx->prio; } /* sdb_error_get_prio */ +int +sdb_error_parse_priority(char *prio) +{ + if (! strcasecmp(prio, "EMERG")) + return SDB_LOG_EMERG; + else if (! strcasecmp(prio, "ERROR")) + return SDB_LOG_ERR; + else if (! strcasecmp(prio, "WARNING")) + return SDB_LOG_WARNING; + else if (! strcasecmp(prio, "NOTICE")) + return SDB_LOG_NOTICE; + else if (! strcasecmp(prio, "INFO")) + return SDB_LOG_INFO; + else if (! strcasecmp(prio, "DEBUG")) + return SDB_LOG_DEBUG; + return -1; +} /* sdb_error_parse_priority */ + +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 : */