X-Git-Url: https://git.octo.it/?p=rrdtool.git;a=blobdiff_plain;f=src%2Frrd_thread_safe.c;h=e1e3cbeaa1b660b3b698de0f504738c4ec961683;hp=bccea99fba2f8508672bc5c8430152405e8c0024;hb=d4d67c5fdf35d76f9c95532acfce632a6213ac1d;hpb=12408853ccdabd7d2aff1b86dc848a2755391bd2 diff --git a/src/rrd_thread_safe.c b/src/rrd_thread_safe.c index bccea99..e1e3cbe 100644 --- a/src/rrd_thread_safe.c +++ b/src/rrd_thread_safe.c @@ -1,5 +1,5 @@ /***************************************************************************** - * RRDtool 1.2.15 Copyright by Tobi Oetiker, 1997-2006 + * RRDtool 1.3.2 Copyright by Tobi Oetiker, 1997-2008 * This file: Copyright 2003 Peter Stamfest * & Tobias Oetiker * Distributed under the GPL @@ -24,46 +24,87 @@ static pthread_once_t context_key_once = PTHREAD_ONCE_INIT; /* Free the thread-specific rrd_context - we might actually use rrd_free_context instead... */ -static void context_destroy_context(void *ctx_) +static void context_destroy_context( + void *ctx_) { - struct rrd_context *ctx = ctx_; - if (ctx) rrd_free_context(ctx); + rrd_context_t *ctx = ctx_; + + if (ctx) + rrd_free_context(ctx); } /* Allocate the key */ -static void context_get_key() +static void context_get_key( + void) { pthread_key_create(&context_key, context_destroy_context); } -struct rrd_context *rrd_get_context(void) { - struct rrd_context *ctx; +rrd_context_t *rrd_get_context( + void) +{ + rrd_context_t *ctx; pthread_once(&context_key_once, context_get_key); ctx = pthread_getspecific(context_key); if (!ctx) { - ctx = rrd_new_context(); - pthread_setspecific(context_key, ctx); - } + ctx = rrd_new_context(); + pthread_setspecific(context_key, ctx); + } return ctx; } #ifdef HAVE_STRERROR_R -const char *rrd_strerror(int err) { - struct rrd_context *ctx = rrd_get_context(); - return strerror_r(err, ctx->lib_errstr, ctx->errlen); +const char *rrd_strerror( + int err) +{ + rrd_context_t *ctx = rrd_get_context(); + char *ret = "unknown error"; + + *ctx->lib_errstr = '\0'; + + /* Even though POSIX/XSI requires "strerror_r" to return an "int", some + * systems (e.g. the GNU libc) return a "char *" _and_ ignore the second + * argument ... -tokkee */ +#ifdef STRERROR_R_CHAR_P + ret = strerror_r(err, ctx->lib_errstr, sizeof(ctx->lib_errstr)); + if ((! ret) || (*ret == '\0')) { + if (*ctx->lib_errstr != '\0') + ret = ctx->lib_errstr; + else { + /* according to the manpage this should not happen - + let's handle it somehow sanely anyway */ + snprintf(ctx->lib_errstr, sizeof(ctx->lib_errstr), + "unknown error %i - strerror_r did not return anything", + err); + ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0'; + ret = ctx->lib_errstr; + } + } +#else /* ! STRERROR_R_CHAR_P */ + if (strerror_r(err, ctx->lib_errstr, sizeof(ctx->lib_errstr))) { + snprintf(ctx->lib_errstr, sizeof(ctx->lib_errstr), + "unknown error %i - strerror_r returned with errno = %i", + err, errno); + ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0'; + } + ret = ctx->lib_errstr; +#endif + return ret; } #else #undef strerror -const char *rrd_strerror(int err) { +const char *rrd_strerror( + int err) +{ static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; - struct rrd_context *ctx; + rrd_context_t *ctx; + ctx = rrd_get_context(); pthread_mutex_lock(&mtx); - strncpy(ctx->lib_errstr, strerror(err), ctx->errlen); - ctx->lib_errstr[ctx->errlen]='\0'; + strncpy(ctx->lib_errstr, strerror(err), sizeof(ctx->lib_errstr)); + ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0'; pthread_mutex_unlock(&mtx); return ctx->lib_errstr; } #endif -