1 diff a/src/rrd_create.c b/src/rrd_create.c
2 --- a/src/rrd_create.c
3 +++ b/src/rrd_create.c
4 @@ -27,6 +27,9 @@ void parseGENERIC_DS(
5 long int rra_random_row(
6 rra_def_t *);
8 +static void rrd_free2(
9 + rrd_t *rrd); /* our onwn copy, immmune to mmap */
10 +
11 int rrd_create(
12 int argc,
13 char **argv)
14 @@ -125,15 +128,14 @@ int rrd_create_r(
15 /* static header */
16 if ((rrd.stat_head = calloc(1, sizeof(stat_head_t))) == NULL) {
17 rrd_set_error("allocating rrd.stat_head");
18 - free(rrd.stat_head);
19 + rrd_free2(&rrd);
20 return (-1);
21 }
23 /* live header */
24 if ((rrd.live_head = calloc(1, sizeof(live_head_t))) == NULL) {
25 rrd_set_error("allocating rrd.live_head");
26 - free(rrd.stat_head);
27 - free(rrd.live_head);
28 + rrd_free2(&rrd);
29 return (-1);
30 }
32 @@ -166,8 +168,7 @@ int rrd_create_r(
33 old_size + sizeof(ds_def_t))) ==
34 NULL) {
35 rrd_set_error("allocating rrd.ds_def");
36 - free(rrd.stat_head);
37 - free(rrd.live_head);
38 + rrd_free2(&rrd);
39 return (-1);
40 }
41 memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t));
42 @@ -199,8 +200,7 @@ int rrd_create_r(
43 rrd_set_error("invalid DS format");
44 }
45 if (rrd_test_error()) {
46 - free(rrd.stat_head);
47 - free(rrd.live_head);
48 + rrd_free2(&rrd);
49 return -1;
50 }
52 @@ -223,8 +223,7 @@ int rrd_create_r(
53 }
55 if (rrd_test_error()) {
56 - free(rrd.stat_head);
57 - free(rrd.live_head);
58 + rrd_free2(&rrd);
59 return -1;
60 }
61 rrd.stat_head->ds_cnt++;
62 @@ -238,8 +237,7 @@ int rrd_create_r(
63 old_size + sizeof(rra_def_t))) ==
64 NULL) {
65 rrd_set_error("allocating rrd.rra_def");
66 - free(rrd.stat_head);
67 - free(rrd.live_head);
68 + rrd_free2(&rrd);
69 return (-1);
70 }
71 memset(&rrd.rra_def[rrd.stat_head->rra_cnt], 0,
72 @@ -496,8 +494,7 @@ int rrd_create_r(
73 if (rrd_test_error()) {
74 /* all errors are unrecoverable */
75 free(argvcopy);
76 - free(rrd.stat_head);
77 - free(rrd.live_head);
78 + rrd_free2(&rrd);
79 return (-1);
80 }
81 token = strtok_r(NULL, ":", &tokptr);
82 @@ -524,16 +521,14 @@ int rrd_create_r(
83 if (create_hw_contingent_rras(&rrd, period, hashed_name) ==
84 -1) {
85 rrd_set_error("creating contingent RRA");
86 - free(rrd.stat_head);
87 - free(rrd.live_head);
88 + rrd_free2(&rrd);
89 return -1;
90 }
91 }
92 rrd.stat_head->rra_cnt++;
93 } else {
94 rrd_set_error("can't parse argument '%s'", argv[i]);
95 - free(rrd.stat_head);
96 - free(rrd.live_head);
97 + rrd_free2(&rrd);
98 return -1;
99 }
100 }
101 @@ -541,15 +536,13 @@ int rrd_create_r(
103 if (rrd.stat_head->rra_cnt < 1) {
104 rrd_set_error("you must define at least one Round Robin Archive");
105 - free(rrd.stat_head);
106 - free(rrd.live_head);
107 + rrd_free2(&rrd);
108 return (-1);
109 }
111 if (rrd.stat_head->ds_cnt < 1) {
112 rrd_set_error("you must define at least one Data Source");
113 - free(rrd.stat_head);
114 - free(rrd.live_head);
115 + rrd_free2(&rrd);
116 return (-1);
117 }
118 return rrd_create_fn(filename, &rrd);
119 @@ -618,6 +611,7 @@ int create_hw_contingent_rras(
120 if ((rrd->rra_def = rrd_realloc(rrd->rra_def,
121 old_size + 4 * sizeof(rra_def_t))) ==
122 NULL) {
123 + rrd_free2(rrd);
124 rrd_set_error("allocating rrd.rra_def");
125 return (-1);
126 }
127 @@ -682,15 +676,15 @@ int rrd_create_fn(
128 int unkn_cnt;
129 rrd_file_t *rrd_file_dn;
130 rrd_t rrd_dn;
131 - unsigned flags = O_WRONLY | O_CREAT | O_TRUNC;
132 + unsigned flags = O_WRONLY | O_CREAT | O_TRUNC;
133 +
134 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
135 flags |= O_BINARY;
136 #endif
138 if ((rrd_file = open(file_name, flags, 0666)) < 0) {
139 rrd_set_error("creating '%s': %s", file_name, rrd_strerror(errno));
140 - free(rrd->stat_head);
141 - free(rrd->live_head);
142 + rrd_free2(rrd);
143 return (-1);
144 }
146 @@ -705,8 +699,7 @@ int rrd_create_fn(
148 if ((rrd->pdp_prep = calloc(1, sizeof(pdp_prep_t))) == NULL) {
149 rrd_set_error("allocating pdp_prep");
150 - free(rrd->stat_head);
151 - free(rrd->live_head);
152 + rrd_free2(rrd);
153 close(rrd_file);
154 return (-1);
155 }
156 @@ -722,8 +715,7 @@ int rrd_create_fn(
158 if ((rrd->cdp_prep = calloc(1, sizeof(cdp_prep_t))) == NULL) {
159 rrd_set_error("allocating cdp_prep");
160 - free(rrd->stat_head);
161 - free(rrd->live_head);
162 + rrd_free2(rrd);
163 close(rrd_file);
164 return (-1);
165 }
166 @@ -770,8 +762,7 @@ int rrd_create_fn(
168 if ((rrd->rra_ptr = calloc(1, sizeof(rra_ptr_t))) == NULL) {
169 rrd_set_error("allocating rra_ptr");
170 - free(rrd->stat_head);
171 - free(rrd->live_head);
172 + rrd_free2(rrd);
173 close(rrd_file);
174 return (-1);
175 }
176 @@ -788,8 +779,7 @@ int rrd_create_fn(
177 /* write the empty data area */
178 if ((unknown = (rrd_value_t *) malloc(512 * sizeof(rrd_value_t))) == NULL) {
179 rrd_set_error("allocating unknown");
180 - free(rrd->stat_head);
181 - free(rrd->live_head);
182 + rrd_free2(rrd);
183 close(rrd_file);
184 return (-1);
185 }
186 @@ -807,8 +797,7 @@ int rrd_create_fn(
187 }
188 free(unknown);
189 fdatasync(rrd_file);
190 - free(rrd->stat_head);
191 - free(rrd->live_head);
192 + rrd_free2(rrd);
193 if (close(rrd_file) == -1) {
194 rrd_set_error("creating rrd: %s", rrd_strerror(errno));
195 return -1;
196 @@ -821,6 +810,20 @@ int rrd_create_fn(
197 return (0);
198 }
200 +
201 +static void rrd_free2(
202 + rrd_t *rrd)
203 +{
204 + free(rrd->live_head);
205 + free(rrd->stat_head);
206 + free(rrd->ds_def);
207 + free(rrd->rra_def);
208 + free(rrd->rra_ptr);
209 + free(rrd->pdp_prep);
210 + free(rrd->cdp_prep);
211 + free(rrd->rrd_value);
212 +}
213 +
214 static int rand_init = 0;
216 long int rra_random_row(
217 diff a/src/rrd_tool.c b/src/rrd_tool.c
218 --- a/src/rrd_tool.c
219 +++ b/src/rrd_tool.c
220 @@ -364,6 +364,7 @@ static char *fgetslong(
221 return *aLinePtr = linebuf;
222 bufsize += MAX_LENGTH;
223 if (!(linebuf = realloc(linebuf, bufsize))) {
224 + free(linebuf);
225 perror("fgetslong: realloc");
226 exit(1);
227 }
228 @@ -448,6 +449,7 @@ int main(
230 while (fgetslong(&aLine, stdin)) {
231 if ((argc = CountArgs(aLine)) == 0) {
232 + free(aLine);
233 printf("ERROR: not enough arguments\n");
234 }
235 if ((myargv = (char **) malloc((argc + 1) *
236 @@ -456,6 +458,8 @@ int main(
237 exit(1);
238 }
239 if ((argc = CreateArgs(argv[0], aLine, argc, myargv)) < 0) {
240 + free(aLine);
241 + free(myargv);
242 printf("ERROR: creating arguments\n");
243 } else {
244 int ret = HandleInputLine(argc, myargv, stdout);
245 diff a/src/rrd_graph.c b/src/rrd_graph.c
246 --- a/src/rrd_graph.c
247 +++ b/src/rrd_graph.c
248 @@ -3059,6 +3059,7 @@ int graph_paint(
249 (im->surface, CAIRO_SVG_VERSION_1_1);
250 break;
251 };
252 + cairo_destroy(im->cr);
253 im->cr = cairo_create(im->surface);
254 cairo_set_antialias(im->cr, im->graph_antialias);
255 cairo_scale(im->cr, im->zoom, im->zoom);
256 diff a/src/rrd_gfx.c b/src/rrd_gfx.c
257 --- a/src/rrd_gfx.c
258 +++ b/src/rrd_gfx.c
259 @@ -158,10 +158,11 @@ static PangoLayout *gfx_prep_text(
260 /* pango_cairo_update_context(cr, pango_context); */
262 pango_layout_set_tabs(layout, tab_array);
263 + pango_tab_array_free(tab_array);
264 font_desc = pango_font_description_from_string(font);
265 pango_font_description_set_size(font_desc, size * PANGO_SCALE);
266 pango_layout_set_font_description(layout, font_desc);
267 -
268 + pango_font_description_free(font_desc);
269 /* pango expects the string to be utf-8 encoded */
270 utf8_text = g_locale_to_utf8((const gchar *) text, -1, NULL, NULL, NULL);
272 @@ -191,7 +192,6 @@ double gfx_get_text_width(
273 gfx_color_t color = { 0, 0, 0, 0 };
274 layout = gfx_prep_text(im, start, color, font, size, tabwidth, text);
275 pango_layout_get_pixel_extents(layout, NULL, &log_rect);
276 - pango_tab_array_free(pango_layout_get_tabs(layout));
277 g_object_unref(layout);
278 return log_rect.width;
279 }
280 @@ -252,7 +252,6 @@ void gfx_text(
281 pango_cairo_update_layout(cr, layout);
282 cairo_move_to(cr, sx, sy);
283 pango_cairo_show_layout(cr, layout);
284 - pango_tab_array_free(pango_layout_get_tabs(layout));
285 g_object_unref(layout);
286 cairo_restore(cr);
288 diff a/src/rrd_tool.c b/src/rrd_tool.c
289 --- a/src/rrd_tool.c
290 +++ b/src/rrd_tool.c
291 @@ -369,7 +369,11 @@ static char *fgetslong(
292 exit(1);
293 }
294 }
295 - return *aLinePtr = linebuf[0] ? linebuf : 0;
296 + if (linebuf[0]){
297 + return *aLinePtr = linebuf;
298 + }
299 + free(linebuf);
300 + return *aLinePtr = 0;
301 }
303 int main(
304 diff a/bindings/perl-shared/RRDs.xs b/bindings/perl-shared/RRDs.xs
305 --- a/bindings/perl-shared/RRDs.xs
306 +++ b/bindings/perl-shared/RRDs.xs
307 @@ -78,8 +78,8 @@ extern "C" {
308 free(argv); \
309 if (rrd_test_error()) XSRETURN_UNDEF; \
310 hash = newHV(); \
311 + save=data; \
312 while (data) { \
313 - save=data; \
314 /* the newSV will get copied by hv so we create it as a mortal \
315 to make sure it does not keep hanging round after the fact */ \
316 switch (data->type) { \
317 @@ -97,18 +97,14 @@ extern "C" {
318 break; \
319 case RD_I_STR: \
320 hvs(newSVpv(data->value.u_str,0)); \
321 - rrd_freemem(data->value.u_str); \
322 break; \
323 case RD_I_BLO: \
324 hvs(newSVpv(data->value.u_blo.ptr,data->value.u_blo.size)); \
325 - rrd_freemem(data->value.u_blo.ptr); \
326 break; \
327 } \
328 - rrd_freemem(data->key); \
329 data = data->next; \
330 - rrd_freemem(save); \
331 - } \
332 - rrd_freemem(data); \
333 + } \
334 + rrd_info_free(save); \
335 RETVAL = newRV_noinc((SV*)hash);
337 /*
338 diff a/bindings/ruby/main.c b/bindings/ruby/main.c
339 --- a/bindings/ruby/main.c
340 +++ b/bindings/ruby/main.c
341 @@ -155,6 +155,7 @@ VALUE rb_rrd_infocall(
343 RRD_CHECK_ERROR result = rb_hash_new();
345 + p = data;
346 while (data) {
347 VALUE key = rb_str_new2(data->key);
349 @@ -171,19 +172,16 @@ VALUE rb_rrd_infocall(
350 break;
351 case RD_I_STR:
352 rb_hash_aset(result, key, rb_str_new2(data->value.u_str));
353 - rrd_freemem(data->value.u_str);
354 break;
355 case RD_I_BLO:
356 rb_hash_aset(result, key,
357 rb_str_new(data->value.u_blo.ptr,
358 data->value.u_blo.size));
359 - rrd_freemem(data->value.u_blo.ptr);
360 break;
361 }
362 - p = data;
363 data = data->next;
364 - rrd_freemem(p);
365 }
366 + rrd_info_free(p);
367 return result;
368 }