Code

Merge branch 'upstream/1.3' into experimental
[pkg-rrdtool.git] / src / rrd_error.c
1 /*****************************************************************************
2  * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
3  *****************************************************************************
4  * rrd_error.c   Common Header File
5  *****************************************************************************
6  * $Id: rrd_error.c 1366 2008-05-18 13:06:44Z oetiker $
7  * $Log$
8  * Revision 1.4  2003/02/22 21:57:03  oetiker
9  * a patch to avoid a memory leak and a Makefile.am patch to
10  * distribute all required source files -- Peter Stamfest <peter@stamfest.at>
11  *
12  * Revision 1.3  2003/02/13 07:05:27  oetiker
13  * Find attached the patch I promised to send to you. Please note that there
14  * are three new source files (src/rrd_is_thread_safe.h, src/rrd_thread_safe.c
15  * and src/rrd_not_thread_safe.c) and the introduction of librrd_th. This
16  * library is identical to librrd, but it contains support code for per-thread
17  * global variables currently used for error information only. This is similar
18  * to how errno per-thread variables are implemented.  librrd_th must be linked
19  * alongside of libpthred
20  *
21  * There is also a new file "THREADS", holding some documentation.
22  *
23  * -- Peter Stamfest <peter@stamfest.at>
24  *
25  * Revision 1.2  2002/02/01 20:34:49  oetiker
26  * fixed version number and date/time
27  *
28  * Revision 1.1.1.1  2001/02/25 22:25:05  oetiker
29  * checkin
30  *
31  *************************************************************************** */
33 #include "rrd_tool.h"
34 #include <stdarg.h>
36 #define MAXLEN 4096
37 #define ERRBUFLEN 256
38 #define CTX (rrd_get_context())
40 void rrd_set_error(
41     char *fmt,
42     ...)
43 {
44     va_list   argp;
46     rrd_clear_error();
47     va_start(argp, fmt);
48 #ifdef HAVE_VSNPRINTF
49     vsnprintf(CTX->rrd_error, CTX->len, fmt, argp);
50 #else
51     vsprintf(CTX->rrd_error, fmt, argp);
52 #endif
53     va_end(argp);
54 }
56 int rrd_test_error(
57     void)
58 {
59     return CTX->rrd_error[0] != '\0';
60 }
62 void rrd_clear_error(
63     void)
64 {
65     CTX->rrd_error[0] = '\0';
66 }
68 char     *rrd_get_error(
69     void)
70 {
71     return CTX->rrd_error;
72 }
74 #if 0
75 /* PS: Keep this stuff around, maybe we want it again if we use
76    rrd_contexts to really associate them with single RRD files and
77    operations on them... Then a single thread may use more than one
78    context. Using these functions would require to change each and
79    every function containing any of the non _r versions... */
80 void rrd_set_error_r(
81     struct rrd_context *rrd_ctx,
82     char *fmt,
83     ...)
84 {
85     va_list   argp;
87     rrd_clear_error_r(rrd_ctx);
88     va_start(argp, fmt);
89 #ifdef HAVE_VSNPRINTF
90     vsnprintf((char *) rrd_ctx->rrd_error, rrd_ctx->len, fmt, argp);
91     rrd_ctx->rrd_error[rrd_ctx->len] = '\0';
92 #else
93     vsprintf((char *) rrd_ctx->rrd_error, fmt, argp);
94 #endif
95     va_end(argp);
96 }
98 int rrd_test_error_r(
99     struct rrd_context *rrd_ctx)
101     return rrd_ctx->rrd_error[0] != '\0';
104 void rrd_clear_error_r(
105     struct rrd_context *rrd_ctx)
107     rrd_ctx->rrd_error[0] = '\0';
110 char     *rrd_get_error_r(
111     struct rrd_context *rrd_ctx)
113     return (char *) rrd_ctx->rrd_error;
115 #endif
117 /* PS: Should we move this to some other file? It is not really error
118    related. */
119 struct rrd_context *rrd_new_context(
120     void)
122     struct rrd_context *rrd_ctx =
123         (struct rrd_context *) malloc(sizeof(struct rrd_context));
125     if (rrd_ctx) {
126         rrd_ctx->rrd_error = malloc(MAXLEN + 10);
127         rrd_ctx->lib_errstr = malloc(ERRBUFLEN + 10);
128         if (rrd_ctx->rrd_error && rrd_ctx->lib_errstr) {
129             *rrd_ctx->rrd_error = 0;
130             *rrd_ctx->lib_errstr = 0;
131             rrd_ctx->len = MAXLEN;
132             rrd_ctx->errlen = ERRBUFLEN;
133             return rrd_ctx;
134         }
135         if (rrd_ctx->rrd_error)
136             free(rrd_ctx->rrd_error);
137         if (rrd_ctx->lib_errstr)
138             free(rrd_ctx->lib_errstr);
139         free(rrd_ctx);
140     }
141     return NULL;
144 void rrd_free_context(
145     struct rrd_context *rrd_ctx)
147     if (rrd_ctx) {
148         if (rrd_ctx->rrd_error)
149             free(rrd_ctx->rrd_error);
150         if (rrd_ctx->lib_errstr)
151             free(rrd_ctx->lib_errstr);
152         free(rrd_ctx);
153     }
156 #if 0
157 void rrd_globalize_error(
158     struct rrd_context *rrd_ctx)
160     if (rrd_ctx) {
161         rrd_set_error(rrd_ctx->rrd_error);
162     }
164 #endif