Bug Summary

File:menu-monitor.c
Warning:line 164, column 3
Value stored to 'event' 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 menu-monitor.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 -fdebug-compilation-dir=/rootdir/libmenu -fcoverage-compilation-dir=/rootdir/libmenu -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gio-unix-2.0 -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/libmount -I /usr/include/blkid -D CAFEMENU_I_KNOW_THIS_IS_UNSTABLE -D PIC -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -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.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/2025-02-13-080250-11729-1 -x c menu-monitor.c
1/*
2 * Copyright (C) 2005 Red Hat, Inc.
3 * Copyright (C) 2006 Mark McLoughlin
4 * Copyright (C) 2007 Sebastian Dröge
5 * Copyright (C) 2008 Vincent Untz
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library 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 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#include <config.h>
24
25#include "menu-monitor.h"
26
27#include <gio/gio.h>
28
29#include "menu-util.h"
30
31struct MenuMonitor {
32 char* path;
33 guint refcount;
34
35 GSList* notifies;
36
37 GFileMonitor* monitor;
38
39 guint is_directory: 1;
40};
41
42typedef struct {
43 MenuMonitor* monitor;
44 MenuMonitorEvent event;
45 char* path;
46} MenuMonitorEventInfo;
47
48typedef struct {
49 MenuMonitorNotifyFunc notify_func;
50 gpointer user_data;
51 guint refcount;
52} MenuMonitorNotify;
53
54static MenuMonitorNotify* cafe_menu_monitor_notify_refmenu_monitor_notify_ref(MenuMonitorNotify* notify);
55static void cafe_menu_monitor_notify_unrefmenu_monitor_notify_unref(MenuMonitorNotify* notify);
56
57static GHashTable* monitors_registry = NULL((void*)0);
58static guint events_idle_handler = 0;
59static GSList* pending_events = NULL((void*)0);
60
61static void invoke_notifies(MenuMonitor* monitor, MenuMonitorEvent event, const char* path)
62{
63 GSList *copy;
64 GSList *tmp;
65
66 copy = g_slist_copy (monitor->notifies);
67 g_slist_foreach (copy,
68 (GFunc) cafe_menu_monitor_notify_refmenu_monitor_notify_ref,
69 NULL((void*)0));
70
71 tmp = copy;
72 while (tmp != NULL((void*)0))
73 {
74 MenuMonitorNotify *notify = tmp->data;
75 GSList *next = tmp->next;
76
77 if (notify->notify_func)
78 {
79 notify->notify_func (monitor, event, path, notify->user_data);
80 }
81
82 cafe_menu_monitor_notify_unrefmenu_monitor_notify_unref(notify);
83
84 tmp = next;
85 }
86
87 g_slist_free (copy);
88}
89
90static gboolean emit_events_in_idle(void)
91{
92 GSList *events_to_emit;
93 GSList *tmp;
94
95 events_to_emit = pending_events;
96
97 pending_events = NULL((void*)0);
98 events_idle_handler = 0;
99
100 tmp = events_to_emit;
101 while (tmp != NULL((void*)0))
102 {
103 MenuMonitorEventInfo *event_info = tmp->data;
104
105 cafe_menu_monitor_refmenu_monitor_ref(event_info->monitor);
106
107 tmp = tmp->next;
108 }
109
110 tmp = events_to_emit;
111 while (tmp != NULL((void*)0))
112 {
113 MenuMonitorEventInfo *event_info = tmp->data;
114
115 invoke_notifies (event_info->monitor,
116 event_info->event,
117 event_info->path);
118
119 menu_monitor_unref (event_info->monitor);
120 event_info->monitor = NULL((void*)0);
121
122 g_free (event_info->path);
123 event_info->path = NULL((void*)0);
124
125 event_info->event = MENU_MONITOR_EVENT_INVALID;
126
127 g_free (event_info);
128
129 tmp = tmp->next;
130 }
131
132 g_slist_free (events_to_emit);
133
134 return FALSE(0);
135}
136
137static void menu_monitor_queue_event(MenuMonitorEventInfo* event_info)
138{
139 pending_events = g_slist_append (pending_events, event_info);
140
141 if (events_idle_handler == 0)
142 {
143 events_idle_handler = g_idle_add ((GSourceFunc) emit_events_in_idle, NULL((void*)0));
144 }
145}
146
147static inline char* get_registry_key(const char* path, gboolean is_directory)
148{
149 return g_strdup_printf ("%s:%s",
150 path,
151 is_directory ? "<dir>" : "<file>");
152}
153
154static gboolean monitor_callback (GFileMonitor *monitor G_GNUC_UNUSED__attribute__ ((__unused__)),
155 GFile *child,
156 GFile *other_file G_GNUC_UNUSED__attribute__ ((__unused__)),
157 GFileMonitorEvent eflags,
158 gpointer user_data)
159{
160 MenuMonitorEventInfo *event_info;
161 MenuMonitorEvent event;
162 MenuMonitor *menu_monitor = (MenuMonitor *) user_data;
163
164 event = MENU_MONITOR_EVENT_INVALID;
Value stored to 'event' is never read
165 switch (eflags)
166 {
167 case G_FILE_MONITOR_EVENT_CHANGED:
168 event = MENU_MONITOR_EVENT_CHANGED;
169 break;
170 case G_FILE_MONITOR_EVENT_CREATED:
171 event = MENU_MONITOR_EVENT_CREATED;
172 break;
173 case G_FILE_MONITOR_EVENT_DELETED:
174 event = MENU_MONITOR_EVENT_DELETED;
175 break;
176 default:
177 return TRUE(!(0));
178 }
179
180 event_info = g_new0 (MenuMonitorEventInfo, 1)((MenuMonitorEventInfo *) g_malloc0_n ((1), sizeof (MenuMonitorEventInfo
)))
;
181
182 event_info->path = g_file_get_path (child);
183 event_info->event = event;
184 event_info->monitor = menu_monitor;
185
186 menu_monitor_queue_event (event_info);
187
188 return TRUE(!(0));
189}
190
191static MenuMonitor* register_monitor(const char* path, gboolean is_directory)
192{
193 MenuMonitor *retval;
194 GFile *file;
195
196 retval = g_new0 (MenuMonitor, 1)((MenuMonitor *) g_malloc0_n ((1), sizeof (MenuMonitor)));
197
198 retval->path = g_strdup (path)g_strdup_inline (path);
199 retval->refcount = 1;
200 retval->is_directory = is_directory != FALSE(0);
201
202 file = g_file_new_for_path (retval->path);
203
204 if (file == NULL((void*)0))
205 {
206 menu_verbose ("Not adding monitor on '%s', failed to create GFile\n",
207 retval->path);
208 return retval;
209 }
210
211 if (retval->is_directory)
212 retval->monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE,
213 NULL((void*)0), NULL((void*)0));
214 else
215 retval->monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE,
216 NULL((void*)0), NULL((void*)0));
217
218 g_object_unref (G_OBJECT (file)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((file)), (((GType) ((20) << (2))))))))
);
219
220 if (retval->monitor == NULL((void*)0))
221 {
222 menu_verbose ("Not adding monitor on '%s', failed to create monitor\n",
223 retval->path);
224 return retval;
225 }
226
227 g_signal_connect (retval->monitor, "changed",g_signal_connect_data ((retval->monitor), ("changed"), (((
GCallback) (monitor_callback))), (retval), ((void*)0), (GConnectFlags
) 0)
228 G_CALLBACK (monitor_callback), retval)g_signal_connect_data ((retval->monitor), ("changed"), (((
GCallback) (monitor_callback))), (retval), ((void*)0), (GConnectFlags
) 0)
;
229
230 return retval;
231}
232
233static MenuMonitor* lookup_monitor(const char* path, gboolean is_directory)
234{
235 MenuMonitor *retval;
236 char *registry_key;
237
238 retval = NULL((void*)0);
239
240 registry_key = get_registry_key (path, is_directory);
241
242 if (monitors_registry == NULL((void*)0))
243 {
244 monitors_registry = g_hash_table_new_full (g_str_hash,
245 g_str_equal,
246 g_free,
247 NULL((void*)0));
248 }
249 else
250 {
251 retval = g_hash_table_lookup (monitors_registry, registry_key);
252 }
253
254 if (retval == NULL((void*)0))
255 {
256 retval = register_monitor (path, is_directory);
257 g_hash_table_insert (monitors_registry, registry_key, retval);
258
259 return retval;
260 }
261 else
262 {
263 g_free (registry_key);
264
265 return cafe_menu_monitor_refmenu_monitor_ref(retval);
266 }
267}
268
269MenuMonitor* cafe_menu_monitor_file_getmenu_get_file_monitor(const char* path)
270{
271 g_return_val_if_fail(path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "path != NULL"); return
(((void*)0)); } } while (0)
;
272
273 return lookup_monitor(path, FALSE(0));
274}
275
276MenuMonitor* menu_get_directory_monitor(const char* path)
277{
278 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "path != NULL"); return
(((void*)0)); } } while (0)
;
279
280 return lookup_monitor (path, TRUE(!(0)));
281}
282
283MenuMonitor* cafe_menu_monitor_refmenu_monitor_ref(MenuMonitor* monitor)
284{
285 g_return_val_if_fail(monitor != NULL, NULL)do { if ((monitor != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "monitor != NULL"
); return (((void*)0)); } } while (0)
;
286 g_return_val_if_fail(monitor->refcount > 0, NULL)do { if ((monitor->refcount > 0)) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "monitor->refcount > 0"
); return (((void*)0)); } } while (0)
;
287
288 monitor->refcount++;
289
290 return monitor;
291}
292
293static void menu_monitor_clear_pending_events(MenuMonitor* monitor)
294{
295 GSList *tmp;
296
297 tmp = pending_events;
298 while (tmp != NULL((void*)0))
299 {
300 MenuMonitorEventInfo *event_info = tmp->data;
301 GSList *next = tmp->next;
302
303 if (event_info->monitor == monitor)
304 {
305 pending_events = g_slist_delete_link (pending_events, tmp);
306
307 g_free (event_info->path);
308 event_info->path = NULL((void*)0);
309
310 event_info->monitor = NULL((void*)0);
311 event_info->event = MENU_MONITOR_EVENT_INVALID;
312
313 g_free (event_info);
314 }
315
316 tmp = next;
317 }
318}
319
320void menu_monitor_unref(MenuMonitor* monitor)
321{
322 char *registry_key;
323
324 g_return_if_fail (monitor != NULL)do { if ((monitor != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "monitor != NULL"
); return; } } while (0)
;
325 g_return_if_fail (monitor->refcount > 0)do { if ((monitor->refcount > 0)) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "monitor->refcount > 0"
); return; } } while (0)
;
326
327 if (--monitor->refcount > 0)
328 return;
329
330 registry_key = get_registry_key (monitor->path, monitor->is_directory);
331 g_hash_table_remove (monitors_registry, registry_key);
332 g_free (registry_key);
333
334 if (g_hash_table_size (monitors_registry) == 0)
335 {
336 g_hash_table_destroy (monitors_registry);
337 monitors_registry = NULL((void*)0);
338 }
339
340 if (monitor->monitor)
341 {
342 g_file_monitor_cancel (monitor->monitor);
343 g_object_unref (monitor->monitor);
344 monitor->monitor = NULL((void*)0);
345 }
346
347 g_slist_foreach (monitor->notifies, (GFunc) cafe_menu_monitor_notify_unrefmenu_monitor_notify_unref, NULL((void*)0));
348 g_slist_free (monitor->notifies);
349 monitor->notifies = NULL((void*)0);
350
351 menu_monitor_clear_pending_events (monitor);
352
353 g_free (monitor->path);
354 monitor->path = NULL((void*)0);
355
356 g_free (monitor);
357}
358
359static MenuMonitorNotify* cafe_menu_monitor_notify_refmenu_monitor_notify_ref(MenuMonitorNotify* notify)
360{
361 g_return_val_if_fail(notify != NULL, NULL)do { if ((notify != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "notify != NULL")
; return (((void*)0)); } } while (0)
;
362 g_return_val_if_fail(notify->refcount > 0, NULL)do { if ((notify->refcount > 0)) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "notify->refcount > 0"
); return (((void*)0)); } } while (0)
;
363
364 notify->refcount++;
365
366 return notify;
367}
368
369static void cafe_menu_monitor_notify_unrefmenu_monitor_notify_unref(MenuMonitorNotify* notify)
370{
371 g_return_if_fail(notify != NULL)do { if ((notify != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "notify != NULL")
; return; } } while (0)
;
372 g_return_if_fail(notify->refcount > 0)do { if ((notify->refcount > 0)) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "notify->refcount > 0"
); return; } } while (0)
;
373
374 if (--notify->refcount > 0)
375 {
376 return;
377 }
378
379 g_free(notify);
380}
381
382void menu_monitor_add_notify(MenuMonitor* monitor, MenuMonitorNotifyFunc notify_func, gpointer user_data)
383{
384 MenuMonitorNotify* notify;
385
386 g_return_if_fail(monitor != NULL)do { if ((monitor != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "monitor != NULL"
); return; } } while (0)
;
387 g_return_if_fail(notify_func != NULL)do { if ((notify_func != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "notify_func != NULL"
); return; } } while (0)
;
388
389 GSList* tmp = monitor->notifies;
390
391 while (tmp != NULL((void*)0))
392 {
393 notify = tmp->data;
394
395 if (notify->notify_func == notify_func && notify->user_data == user_data)
396 {
397 break;
398 }
399
400 tmp = tmp->next;
401 }
402
403 if (tmp == NULL((void*)0))
404 {
405 notify = g_new0(MenuMonitorNotify, 1)((MenuMonitorNotify *) g_malloc0_n ((1), sizeof (MenuMonitorNotify
)))
;
406 notify->notify_func = notify_func;
407 notify->user_data = user_data;
408 notify->refcount = 1;
409
410 monitor->notifies = g_slist_append(monitor->notifies, notify);
411 }
412}
413
414void cafe_menu_monitor_notify_removemenu_monitor_remove_notify(MenuMonitor* monitor, MenuMonitorNotifyFunc notify_func, gpointer user_data)
415{
416 GSList* tmp = monitor->notifies;
417
418 while (tmp != NULL((void*)0))
419 {
420 MenuMonitorNotify* notify = tmp->data;
421 GSList* next = tmp->next;
422
423 if (notify->notify_func == notify_func && notify->user_data == user_data)
424 {
425 notify->notify_func = NULL((void*)0);
426 notify->user_data = NULL((void*)0);
427
428 cafe_menu_monitor_notify_unrefmenu_monitor_notify_unref(notify);
429
430 monitor->notifies = g_slist_delete_link(monitor->notifies, tmp);
431 }
432
433 tmp = next;
434 }
435}