Bug Summary

File:libbaul-private/baul-debug-log.c
Warning:line 229, column 17
Value stored to 'p' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name baul-debug-log.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/libbaul-private -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -I .. -I .. -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/cafe-desktop-2.0 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/cail-3.0 -I /usr/include/libxml2 -D G_DISABLE_DEPRECATED -D GDK_PIXBUF_DISABLE_DEPRECATED -D DATADIR="/usr/share" -D SYSCONFDIR="/usr/etc" -D BAUL_DATADIR="/usr/share/baul" -D BAUL_EXTENSIONDIR="/usr/lib/baul/extensions-2.0" -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/libbaul-private -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-07-10-200850-28294-1 -x c baul-debug-log.c
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
2
3 baul-debug-log.c: Ring buffer for logging debug messages
4
5 Copyright (C) 2006 Novell, Inc.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public
18 License along with this program; if not, write to the
19 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21
22 Author: Federico Mena-Quintero <federico@novell.com>
23*/
24#include <config.h>
25#include <errno(*__errno_location ()).h>
26#include <stdio.h>
27#include <string.h>
28#include <time.h>
29#include <sys/time.h>
30#include "baul-debug-log.h"
31#include "baul-file.h"
32
33#define DEFAULT_RING_BUFFER_NUM_LINES1000 1000
34
35#define KEY_FILE_GROUP"debug log" "debug log"
36#define KEY_FILE_DOMAINS_KEY"enable domains" "enable domains"
37#define KEY_FILE_MAX_LINES_KEY"max lines" "max lines"
38
39#define MAX_URI_COUNT20 20
40
41static GMutex log_mutex;
42
43static GHashTable *domains_hash;
44static char **ring_buffer;
45static int ring_buffer_next_index;
46static int ring_buffer_num_lines;
47static int ring_buffer_max_lines = DEFAULT_RING_BUFFER_NUM_LINES1000;
48
49static GSList *milestones_head;
50static GSList *milestones_tail;
51
52static void
53lock (void)
54{
55 g_mutex_lock (&log_mutex);
56}
57
58static void
59unlock (void)
60{
61 g_mutex_unlock (&log_mutex);
62}
63
64void
65baul_debug_log (gboolean is_milestone, const char *domain, const char *format, ...)
66{
67 va_list args;
68
69 va_start (args, format)__builtin_va_start(args, format);
70 baul_debug_logv (is_milestone, domain, NULL((void*)0), format, args);
71 va_end (args)__builtin_va_end(args);
72}
73
74static gboolean
75is_domain_enabled (const char *domain)
76{
77 /* User actions are always logged */
78 if (strcmp (domain, BAUL_DEBUG_LOG_DOMAIN_USER"USER") == 0)
79 return TRUE(!(0));
80
81 if (!domains_hash)
82 return FALSE(0);
83
84 return (g_hash_table_lookup (domains_hash, domain) != NULL((void*)0));
85}
86
87static void
88ensure_ring (void)
89{
90 if (ring_buffer)
91 return;
92
93 ring_buffer = g_new0 (char *, ring_buffer_max_lines)((char * *) g_malloc0_n ((ring_buffer_max_lines), sizeof (char
*)))
;
94 ring_buffer_next_index = 0;
95 ring_buffer_num_lines = 0;
96}
97
98static void
99add_to_ring (char *str)
100{
101 ensure_ring ();
102
103 g_assert (str != NULL)do { if (str != ((void*)0)) ; else g_assertion_message_expr (
((gchar*) 0), "baul-debug-log.c", 103, ((const char*) (__func__
)), "str != NULL"); } while (0)
;
104
105 if (ring_buffer_num_lines == ring_buffer_max_lines)
106 {
107 /* We have an overlap, and the ring_buffer_next_index points to
108 * the "first" item. Free it to make room for the new item.
109 */
110
111 g_assert (ring_buffer[ring_buffer_next_index] != NULL)do { if (ring_buffer[ring_buffer_next_index] != ((void*)0)) ;
else g_assertion_message_expr (((gchar*) 0), "baul-debug-log.c"
, 111, ((const char*) (__func__)), "ring_buffer[ring_buffer_next_index] != NULL"
); } while (0)
;
112 g_free (ring_buffer[ring_buffer_next_index]);
113 }
114 else
115 ring_buffer_num_lines++;
116
117 g_assert (ring_buffer_num_lines <= ring_buffer_max_lines)do { if (ring_buffer_num_lines <= ring_buffer_max_lines) ;
else g_assertion_message_expr (((gchar*) 0), "baul-debug-log.c"
, 117, ((const char*) (__func__)), "ring_buffer_num_lines <= ring_buffer_max_lines"
); } while (0)
;
118
119 ring_buffer[ring_buffer_next_index] = str;
120
121 ring_buffer_next_index++;
122 if (ring_buffer_next_index == ring_buffer_max_lines)
123 {
124 ring_buffer_next_index = 0;
125 g_assert (ring_buffer_num_lines == ring_buffer_max_lines)do { if (ring_buffer_num_lines == ring_buffer_max_lines) ; else
g_assertion_message_expr (((gchar*) 0), "baul-debug-log.c", 125
, ((const char*) (__func__)), "ring_buffer_num_lines == ring_buffer_max_lines"
); } while (0)
;
126 }
127}
128
129static void
130add_to_milestones (const char *str)
131{
132 char *str_copy;
133
134 str_copy = g_strdup (str)g_strdup_inline (str);
135
136 if (milestones_tail)
137 {
138 milestones_tail = g_slist_append (milestones_tail, str_copy);
139 milestones_tail = milestones_tail->next;
140 }
141 else
142 {
143 milestones_head = milestones_tail = g_slist_append (NULL((void*)0), str_copy);
144 }
145
146 g_assert (milestones_head != NULL && milestones_tail != NULL)do { if (milestones_head != ((void*)0) && milestones_tail
!= ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0)
, "baul-debug-log.c", 146, ((const char*) (__func__)), "milestones_head != NULL && milestones_tail != NULL"
); } while (0)
;
147}
148
149void
150baul_debug_logv (gboolean is_milestone, const char *domain, const GList *uris, const char *format, va_list args)
151{
152 char *str;
153 char *debug_str;
154 struct timeval tv;
155 struct tm tm;
156
157 lock ();
158
159 if (!(is_milestone || is_domain_enabled (domain)))
160 goto out;
161
162 str = g_strdup_vprintf (format, args);
163 gettimeofday (&tv, NULL((void*)0));
164
165 tm = *localtime (&tv.tv_sec);
166
167 debug_str = g_strdup_printf ("%p %04d/%02d/%02d %02d:%02d:%02d.%04d (%s): %s",
168 g_thread_self (),
169 tm.tm_year + 1900,
170 tm.tm_mon + 1,
171 tm.tm_mday,
172 tm.tm_hour,
173 tm.tm_min,
174 tm.tm_sec,
175 (int) (tv.tv_usec / 100),
176 domain,
177 str);
178 g_free (str);
179
180 if (uris)
181 {
182 int debug_str_len;
183 int uris_len;
184 const GList *l;
185 char *new_str;
186 char *p;
187 int count;
188
189 uris_len = 0;
190
191 count = 0;
192 for (l = uris; l; l = l->next)
193 {
194 const char *uri;
195
196 uri = l->data;
197 uris_len += strlen (uri) + 2; /* plus 2 for a tab and the newline */
198
199 if (count++ > MAX_URI_COUNT20)
200 {
201 uris_len += 4; /* "...\n" */
202 break;
203 }
204
205 }
206
207 debug_str_len = strlen (debug_str);
208 new_str = g_new (char, debug_str_len + 1 + uris_len + 1)((char *) g_malloc_n ((debug_str_len + 1 + uris_len + 1), sizeof
(char)))
; /* plus 1 for newline & zero */
209
210 p = g_stpcpy (new_str, debug_str);
211 *p++ = '\n';
212
213 count = 0;
214 for (l = uris; l; l = l->next)
215 {
216 const char *uri;
217
218 uri = l->data;
219
220 *p++ = '\t';
221
222 p = g_stpcpy (p, uri);
223
224 if (l->next)
225 *p++ = '\n';
226
227 if (count++ > MAX_URI_COUNT20)
228 {
229 p = g_stpcpy (p, "...\n");
Value stored to 'p' is never read
230 break;
231 }
232 }
233
234 g_free (debug_str);
235 debug_str = new_str;
236 }
237
238 add_to_ring (debug_str);
239 if (is_milestone)
240 add_to_milestones (debug_str);
241
242out:
243 unlock ();
244}
245
246void
247baul_debug_log_with_uri_list (gboolean is_milestone, const char *domain, const GList *uris,
248 const char *format, ...)
249{
250 va_list args;
251
252 va_start (args, format)__builtin_va_start(args, format);
253 baul_debug_logv (is_milestone, domain, uris, format, args);
254 va_end (args)__builtin_va_end(args);
255}
256
257void
258baul_debug_log_with_file_list (gboolean is_milestone, const char *domain, GList *files,
259 const char *format, ...)
260{
261 va_list args;
262 GList *uris;
263 GList *l;
264 int count;
265
266 /* Avoid conversion if debugging disabled */
267 if (!(is_milestone ||
268 baul_debug_log_is_domain_enabled (domain)))
269 {
270 return;
271 }
272
273 uris = NULL((void*)0);
274
275 count = 0;
276 for (l = files; l; l = l->next)
277 {
278 BaulFile *file;
279 char *uri;
280
281 file = BAUL_FILE (l->data)((((BaulFile*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((l->data)), (baul_file_get_type())))))
;
282 uri = baul_file_get_uri (file);
283
284 if (baul_file_is_gone (file))
285 {
286 char *new_uri;
287
288 /* Hack: this will create an invalid URI, but it's for
289 * display purposes only.
290 */
291 new_uri = g_strconcat (uri ? uri : "", " (gone)", NULL((void*)0));
292 g_free (uri);
293 uri = new_uri;
294 }
295 uris = g_list_prepend (uris, uri);
296
297 /* Avoid doing to much work, more than MAX_URI_COUNT uris
298 won't be shown anyway */
299 if (count++ > MAX_URI_COUNT20 + 1)
300 {
301 break;
302 }
303 }
304
305 uris = g_list_reverse (uris);
306
307 va_start (args, format)__builtin_va_start(args, format);
308 baul_debug_logv (is_milestone, domain, uris, format, args);
309 va_end (args)__builtin_va_end(args);
310
311 g_list_free_full (uris, g_free);
312}
313
314gboolean
315baul_debug_log_load_configuration (const char *filename, GError **error)
316{
317 GKeyFile *key_file;
318 char **strings;
319 gsize num_strings;
320 int num;
321 GError *my_error;
322
323 g_assert (filename != NULL)do { if (filename != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-debug-log.c", 323, ((const char*) (__func__
)), "filename != NULL"); } while (0)
;
324 g_assert (error == NULL || *error == NULL)do { if (error == ((void*)0) || *error == ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-debug-log.c", 324, ((const char*) (__func__
)), "error == NULL || *error == NULL"); } while (0)
;
325
326 key_file = g_key_file_new ();
327
328 if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, error))
329 {
330 g_key_file_free (key_file);
331 return FALSE(0);
332 }
333
334 /* Domains */
335
336 my_error = NULL((void*)0);
337 strings = g_key_file_get_string_list (key_file, KEY_FILE_GROUP"debug log", KEY_FILE_DOMAINS_KEY"enable domains", &num_strings, &my_error);
338 if (my_error)
339 g_error_free (my_error);
340 else
341 {
342 int i;
343
344 for (i = 0; i < num_strings; i++)
345 strings[i] = g_strstrip (strings[i])g_strchomp (g_strchug (strings[i]));
346
347 baul_debug_log_enable_domains ((const char **) strings, num_strings);
348 g_strfreev (strings);
349 }
350
351 /* Number of lines */
352
353 my_error = NULL((void*)0);
354 num = g_key_file_get_integer (key_file, KEY_FILE_GROUP"debug log", KEY_FILE_MAX_LINES_KEY"max lines", &my_error);
355 if (my_error)
356 g_error_free (my_error);
357 else
358 baul_debug_log_set_max_lines (num);
359
360 g_key_file_free (key_file);
361 return TRUE(!(0));
362}
363
364void
365baul_debug_log_enable_domains (const char **domains, int n_domains)
366{
367 int i;
368
369 g_assert (domains != NULL)do { if (domains != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-debug-log.c", 369, ((const char*) (__func__
)), "domains != NULL"); } while (0)
;
370 g_assert (n_domains >= 0)do { if (n_domains >= 0) ; else g_assertion_message_expr (
((gchar*) 0), "baul-debug-log.c", 370, ((const char*) (__func__
)), "n_domains >= 0"); } while (0)
;
371
372 lock ();
373
374 if (!domains_hash)
375 domains_hash = g_hash_table_new (g_str_hash, g_str_equal);
376
377 for (i = 0; i < n_domains; i++)
378 {
379 g_assert (domains[i] != NULL)do { if (domains[i] != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-debug-log.c", 379, ((const char*) (__func__
)), "domains[i] != NULL"); } while (0)
;
380
381 if (strcmp (domains[i], BAUL_DEBUG_LOG_DOMAIN_USER"USER") == 0)
382 continue; /* user actions are always enabled */
383
384 if (g_hash_table_lookup (domains_hash, domains[i]) == NULL((void*)0))
385 {
386 char *domain;
387
388 domain = g_strdup (domains[i])g_strdup_inline (domains[i]);
389 g_hash_table_insert (domains_hash, domain, domain);
390 }
391 }
392
393 unlock ();
394}
395
396void
397baul_debug_log_disable_domains (const char **domains, int n_domains)
398{
399 g_assert (domains != NULL)do { if (domains != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-debug-log.c", 399, ((const char*) (__func__
)), "domains != NULL"); } while (0)
;
400 g_assert (n_domains >= 0)do { if (n_domains >= 0) ; else g_assertion_message_expr (
((gchar*) 0), "baul-debug-log.c", 400, ((const char*) (__func__
)), "n_domains >= 0"); } while (0)
;
401
402 lock ();
403
404 if (domains_hash)
405 {
406 int i;
407
408 for (i = 0; i < n_domains; i++)
409 {
410 char *domain;
411
412 g_assert (domains[i] != NULL)do { if (domains[i] != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-debug-log.c", 412, ((const char*) (__func__
)), "domains[i] != NULL"); } while (0)
;
413
414 if (strcmp (domains[i], BAUL_DEBUG_LOG_DOMAIN_USER"USER") == 0)
415 continue; /* user actions are always enabled */
416
417 domain = g_hash_table_lookup (domains_hash, domains[i]);
418 if (domain)
419 {
420 g_hash_table_remove (domains_hash, domain);
421 g_free (domain);
422 }
423 }
424 } /* else, there is nothing to disable */
425
426 unlock ();
427}
428
429gboolean
430baul_debug_log_is_domain_enabled (const char *domain)
431{
432 gboolean retval;
433
434 g_assert (domain != NULL)do { if (domain != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-debug-log.c", 434, ((const char*) (__func__
)), "domain != NULL"); } while (0)
;
435
436 lock ();
437 retval = is_domain_enabled (domain);
438 unlock ();
439
440 return retval;
441}
442
443struct domains_dump_closure
444{
445 char **domains;
446 int num_domains;
447};
448
449static void
450domains_foreach_dump_cb (gpointer key, gpointer value, gpointer data)
451{
452 struct domains_dump_closure *closure;
453 char *domain;
454
455 closure = data;
456 domain = key;
457
458 closure->domains[closure->num_domains] = domain;
459 closure->num_domains++;
460}
461
462static GKeyFile *
463make_key_file_from_configuration (void)
464{
465 GKeyFile *key_file;
466 struct domains_dump_closure closure;
467
468 key_file = g_key_file_new ();
469
470 /* domains */
471
472 if (domains_hash)
473 {
474 int num_domains;
475
476 num_domains = g_hash_table_size (domains_hash);
477 if (num_domains != 0)
478 {
479 closure.domains = g_new (char *, num_domains)((char * *) g_malloc_n ((num_domains), sizeof (char *)));
480 closure.num_domains = 0;
481
482 g_hash_table_foreach (domains_hash, domains_foreach_dump_cb, &closure);
483 g_assert (num_domains == closure.num_domains)do { if (num_domains == closure.num_domains) ; else g_assertion_message_expr
(((gchar*) 0), "baul-debug-log.c", 483, ((const char*) (__func__
)), "num_domains == closure.num_domains"); } while (0)
;
484
485 g_key_file_set_string_list (key_file, KEY_FILE_GROUP"debug log", KEY_FILE_DOMAINS_KEY"enable domains",
486 (const gchar * const *) closure.domains, closure.num_domains);
487 g_free (closure.domains);
488 }
489 }
490
491 /* max lines */
492
493 g_key_file_set_integer (key_file, KEY_FILE_GROUP"debug log", KEY_FILE_MAX_LINES_KEY"max lines", ring_buffer_max_lines);
494
495 return key_file;
496}
497
498static gboolean
499write_string (const char *filename, FILE *file, const char *str, GError **error)
500{
501 if (fputs (str, file) == EOF(-1))
502 {
503 int saved_errno;
504
505 saved_errno = errno(*__errno_location ());
506 g_set_error (error,
507 G_FILE_ERRORg_file_error_quark (),
508 g_file_error_from_errno (saved_errno),
509 "error when writing to log file %s", filename);
510
511 return FALSE(0);
512 }
513
514 return TRUE(!(0));
515}
516
517static gboolean
518dump_configuration (const char *filename, FILE *file, GError **error)
519{
520 GKeyFile *key_file;
521 char *data;
522 gsize length;
523 gboolean success;
524
525 if (!write_string (filename, file,
526 "\n\n"
527 "This configuration for the debug log can be re-created\n"
528 "by putting the following in ~/baul-debug-log.conf\n"
529 "(use ';' to separate domain names):\n\n",
530 error))
531 {
532 return FALSE(0);
533 }
534
535 success = FALSE(0);
536
537 key_file = make_key_file_from_configuration ();
538
539 data = g_key_file_to_data (key_file, &length, error);
540 if (!data)
541 goto out;
542
543 if (!write_string (filename, file, data, error))
544 {
545 goto out;
546 }
547
548 success = TRUE(!(0));
549out:
550 g_key_file_free (key_file);
551 return success;
552}
553
554static gboolean
555dump_milestones (const char *filename, FILE *file, GError **error)
556{
557 GSList *l;
558
559 if (!write_string (filename, file, "===== BEGIN MILESTONES =====\n", error))
560 return FALSE(0);
561
562 for (l = milestones_head; l; l = l->next)
563 {
564 const char *str;
565
566 str = l->data;
567 if (!(write_string (filename, file, str, error)
568 && write_string (filename, file, "\n", error)))
569 return FALSE(0);
570 }
571
572 if (!write_string (filename, file, "===== END MILESTONES =====\n", error))
573 return FALSE(0);
574
575 return TRUE(!(0));
576}
577
578static gboolean
579dump_ring_buffer (const char *filename, FILE *file, GError **error)
580{
581 int start_index;
582 int i;
583
584 if (!write_string (filename, file, "===== BEGIN RING BUFFER =====\n", error))
585 return FALSE(0);
586
587 if (ring_buffer_num_lines == ring_buffer_max_lines)
588 start_index = ring_buffer_next_index;
589 else
590 start_index = 0;
591
592 for (i = 0; i < ring_buffer_num_lines; i++)
593 {
594 int idx;
595
596 idx = (start_index + i) % ring_buffer_max_lines;
597
598 if (!(write_string (filename, file, ring_buffer[idx], error)
599 && write_string (filename, file, "\n", error)))
600 {
601 return FALSE(0);
602 }
603 }
604
605 if (!write_string (filename, file, "===== END RING BUFFER =====\n", error))
606 return FALSE(0);
607
608 return TRUE(!(0));
609}
610
611gboolean
612baul_debug_log_dump (const char *filename, GError **error)
613{
614 FILE *file;
615 gboolean success;
616
617 g_assert (error == NULL || *error == NULL)do { if (error == ((void*)0) || *error == ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-debug-log.c", 617, ((const char*) (__func__
)), "error == NULL || *error == NULL"); } while (0)
;
618
619 lock ();
620
621 success = FALSE(0);
622
623 file = fopen (filename, "w");
624 if (!file)
625 {
626 int saved_errno;
627
628 saved_errno = errno(*__errno_location ());
629 g_set_error (error,
630 G_FILE_ERRORg_file_error_quark (),
631 g_file_error_from_errno (saved_errno),
632 "could not open log file %s", filename);
633 goto out;
634 }
635
636 if (!(dump_milestones (filename, file, error)
637 && dump_ring_buffer (filename, file, error)
638 && dump_configuration (filename, file, error)))
639 {
640 goto do_close;
641 }
642
643 success = TRUE(!(0));
644
645do_close:
646
647 if (fclose (file) != 0)
648 {
649 int saved_errno;
650
651 saved_errno = errno(*__errno_location ());
652
653 if (error && *error)
654 {
655 g_error_free (*error);
656 *error = NULL((void*)0);
657 }
658
659 g_set_error (error,
660 G_FILE_ERRORg_file_error_quark (),
661 g_file_error_from_errno (saved_errno),
662 "error when closing log file %s", filename);
663 success = FALSE(0);
664 }
665
666out:
667
668 unlock ();
669 return success;
670}
671
672void
673baul_debug_log_set_max_lines (int num_lines)
674{
675 char **new_buffer;
676 int lines_to_copy;
677
678 g_assert (num_lines > 0)do { if (num_lines > 0) ; else g_assertion_message_expr ((
(gchar*) 0), "baul-debug-log.c", 678, ((const char*) (__func__
)), "num_lines > 0"); } while (0)
;
679
680 lock ();
681
682 if (num_lines == ring_buffer_max_lines)
683 goto out;
684
685 new_buffer = g_new0 (char *, num_lines)((char * *) g_malloc0_n ((num_lines), sizeof (char *)));
686
687 lines_to_copy = MIN (num_lines, ring_buffer_num_lines)(((num_lines) < (ring_buffer_num_lines)) ? (num_lines) : (
ring_buffer_num_lines))
;
688
689 if (ring_buffer)
690 {
691 int start_index;
692 int i;
693
694 if (ring_buffer_num_lines == ring_buffer_max_lines)
695 start_index = (ring_buffer_next_index + ring_buffer_max_lines - lines_to_copy) % ring_buffer_max_lines;
696 else
697 start_index = ring_buffer_num_lines - lines_to_copy;
698
699 g_assert (start_index >= 0 && start_index < ring_buffer_max_lines)do { if (start_index >= 0 && start_index < ring_buffer_max_lines
) ; else g_assertion_message_expr (((gchar*) 0), "baul-debug-log.c"
, 699, ((const char*) (__func__)), "start_index >= 0 && start_index < ring_buffer_max_lines"
); } while (0)
;
700
701 for (i = 0; i < lines_to_copy; i++)
702 {
703 int idx;
704
705 idx = (start_index + i) % ring_buffer_max_lines;
706
707 new_buffer[i] = ring_buffer[idx];
708 ring_buffer[idx] = NULL((void*)0);
709 }
710
711 for (i = 0; i < ring_buffer_max_lines; i++)
712 g_free (ring_buffer[i]);
713
714 g_free (ring_buffer);
715 }
716
717 ring_buffer = new_buffer;
718 ring_buffer_next_index = lines_to_copy;
719 ring_buffer_num_lines = lines_to_copy;
720 ring_buffer_max_lines = num_lines;
721
722out:
723
724 unlock ();
725}
726
727int
728baul_debug_log_get_max_lines (void)
729{
730 int retval;
731
732 lock ();
733 retval = ring_buffer_max_lines;
734 unlock ();
735
736 return retval;
737}
738
739void
740baul_debug_log_clear (void)
741{
742 int i;
743
744 lock ();
745
746 if (!ring_buffer)
747 goto out;
748
749 for (i = 0; i < ring_buffer_max_lines; i++)
750 {
751 g_free (ring_buffer[i]);
752 ring_buffer[i] = NULL((void*)0);
753 }
754
755 ring_buffer_next_index = 0;
756 ring_buffer_num_lines = 0;
757
758out:
759 unlock ();
760}