X-Git-Url: https://git.octo.it/?p=rrdtool.git;a=blobdiff_plain;f=src%2Frrd_error.c;h=7798c9f0c5775c0cf027288b78dbc07325dd2cca;hp=71bce3c170a683af0a5710826e9a1ea280ae94ea;hb=b02eace34f83a08c55830cb05bc55078153e2ba6;hpb=5837606887a6d81e8b1f7588525cb1c8783fb62b diff --git a/src/rrd_error.c b/src/rrd_error.c index 71bce3c..7798c9f 100644 --- a/src/rrd_error.c +++ b/src/rrd_error.c @@ -1,21 +1,41 @@ /***************************************************************************** - * RRDtool 1.0.33 Copyright Tobias Oetiker, 1997 - 2000 + * RRDtool 1.2rc4 Copyright by Tobi Oetiker, 1997-2005 ***************************************************************************** * rrd_error.c Common Header File ***************************************************************************** * $Id$ * $Log$ - * Revision 1.1 2001/02/25 22:25:05 oetiker - * Initial revision + * Revision 1.4 2003/02/22 21:57:03 oetiker + * a patch to avoid a memory leak and a Makefile.am patch to + * distribute all required source files -- Peter Stamfest + * + * Revision 1.3 2003/02/13 07:05:27 oetiker + * Find attached the patch I promised to send to you. Please note that there + * are three new source files (src/rrd_is_thread_safe.h, src/rrd_thread_safe.c + * and src/rrd_not_thread_safe.c) and the introduction of librrd_th. This + * library is identical to librrd, but it contains support code for per-thread + * global variables currently used for error information only. This is similar + * to how errno per-thread variables are implemented. librrd_th must be linked + * alongside of libpthred + * + * There is also a new file "THREADS", holding some documentation. + * + * -- Peter Stamfest + * + * Revision 1.2 2002/02/01 20:34:49 oetiker + * fixed version number and date/time + * + * Revision 1.1.1.1 2001/02/25 22:25:05 oetiker + * checkin * *************************************************************************** */ #include "rrd_tool.h" -#define MAXLEN 4096 -static char rrd_error[MAXLEN] = "\0"; #include - +#define MAXLEN 4096 +#define ERRBUFLEN 256 +#define CTX (rrd_get_context()) void rrd_set_error(char *fmt, ...) @@ -24,35 +44,102 @@ rrd_set_error(char *fmt, ...) rrd_clear_error(); va_start(argp, fmt); #ifdef HAVE_VSNPRINTF - vsnprintf((char *)rrd_error, MAXLEN-1, fmt, argp); + vsnprintf(CTX->rrd_error, CTX->len, fmt, argp); #else - vsprintf((char *)rrd_error, fmt, argp); + vsprintf(CTX->rrd_error, fmt, argp); #endif va_end(argp); } int rrd_test_error(void) { - return rrd_error[0] != '\0'; + return CTX->rrd_error[0] != '\0'; } void rrd_clear_error(void){ - rrd_error[0] = '\0'; + CTX->rrd_error[0] = '\0'; } char * rrd_get_error(void){ - return (char *)rrd_error; + return CTX->rrd_error; } +#if 0 +/* PS: Keep this stuff around, maybe we want it again if we use + rrd_contexts to really associate them with single RRD files and + operations on them... Then a single thread may use more than one + context. Using these functions would require to change each and + every function containing any of the non _r versions... */ +void +rrd_set_error_r(struct rrd_context *rrd_ctx, char *fmt, ...) +{ + va_list argp; + rrd_clear_error_r(rrd_ctx); + va_start(argp, fmt); +#ifdef HAVE_VSNPRINTF + vsnprintf((char *)rrd_ctx->rrd_error, rrd_ctx->len, fmt, argp); +#else + vsprintf((char *)rrd_ctx->rrd_error, fmt, argp); +#endif + va_end(argp); +} +int +rrd_test_error_r(struct rrd_context *rrd_ctx) { + return rrd_ctx->rrd_error[0] != '\0'; +} +void +rrd_clear_error_r(struct rrd_context *rrd_ctx) { + rrd_ctx->rrd_error[0] = '\0'; +} +char * +rrd_get_error_r(struct rrd_context *rrd_ctx) { + return (char *)rrd_ctx->rrd_error; +} +#endif +/* PS: Should we move this to some other file? It is not really error + related. */ +struct rrd_context * +rrd_new_context(void) { + struct rrd_context *rrd_ctx = + (struct rrd_context *) malloc(sizeof(struct rrd_context)); + + if (rrd_ctx) { + rrd_ctx->len = 0; + rrd_ctx->rrd_error = malloc(MAXLEN); + rrd_ctx->lib_errstr = malloc(ERRBUFLEN); + if (rrd_ctx->rrd_error && rrd_ctx->lib_errstr) { + *rrd_ctx->rrd_error = 0; + *rrd_ctx->lib_errstr = 0; + rrd_ctx->len = MAXLEN; + rrd_ctx->errlen = ERRBUFLEN; + return rrd_ctx; + } + if (rrd_ctx->rrd_error) free(rrd_ctx->rrd_error); + if (rrd_ctx->lib_errstr) free(rrd_ctx->lib_errstr); + free(rrd_ctx); + } + return NULL; +} +void +rrd_free_context(struct rrd_context *rrd_ctx) { + if (rrd_ctx) { + if (rrd_ctx->rrd_error) free(rrd_ctx->rrd_error); + if (rrd_ctx->lib_errstr) free(rrd_ctx->lib_errstr); + free(rrd_ctx); + } +} - - - - +#if 0 +void rrd_globalize_error(struct rrd_context *rrd_ctx) { + if (rrd_ctx) { + rrd_set_error(rrd_ctx->rrd_error); + } +} +#endif