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)
100 {
101 return rrd_ctx->rrd_error[0] != '\0';
102 }
104 void rrd_clear_error_r(
105 struct rrd_context *rrd_ctx)
106 {
107 rrd_ctx->rrd_error[0] = '\0';
108 }
110 char *rrd_get_error_r(
111 struct rrd_context *rrd_ctx)
112 {
113 return (char *) rrd_ctx->rrd_error;
114 }
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)
121 {
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;
142 }
144 void rrd_free_context(
145 struct rrd_context *rrd_ctx)
146 {
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 }
154 }
156 #if 0
157 void rrd_globalize_error(
158 struct rrd_context *rrd_ctx)
159 {
160 if (rrd_ctx) {
161 rrd_set_error(rrd_ctx->rrd_error);
162 }
163 }
164 #endif