GCC Code Coverage Report


Directory: ./
File: src/ppd-utils.c
Date: 2025-03-30 20:28:01
Exec Total Coverage
Lines: 78 85 91.8%
Functions: 8 8 100.0%
Branches: 34 62 54.8%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2020 Bastien Nocera <hadess@hadess.net>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3 as published by
6 * the Free Software Foundation.
7 *
8 */
9
10 #define G_LOG_DOMAIN "Utils"
11
12 #include "ppd-utils.h"
13 #include <glib/gstdio.h>
14 #include <gio/gio.h>
15 #include <fcntl.h>
16 #include <stdio.h>
17 #include <errno.h>
18
19 #define PROC_CPUINFO_PATH "/proc/cpuinfo"
20
21 char *
22 1144 ppd_utils_get_sysfs_path (const char *filename)
23 {
24 1144 const char *root;
25
26 1144 root = g_getenv ("UMOCKDEV_DIR");
27
2/4
✓ Branch 0 taken 1144 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1144 times.
1144 if (!root || *root == '\0')
28 root = "/";
29
30 1144 return g_build_filename (root, filename, NULL);
31 }
32
33 gboolean
34 535 ppd_utils_write (const char *filename,
35 const char *value,
36 GError **error)
37 {
38 #if GLIB_CHECK_VERSION (2, 76, 0)
39 535 g_autofd
40 #endif
41 535 int fd = -1;
42 535 size_t size;
43
44
1/2
✓ Branch 0 taken 535 times.
✗ Branch 1 not taken.
535 g_return_val_if_fail (filename, FALSE);
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 535 times.
535 g_return_val_if_fail (value, FALSE);
46
47 535 g_debug ("Writing '%s' to '%s'", value, filename);
48
49 535 fd = g_open (filename, O_WRONLY | O_TRUNC | O_SYNC);
50
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 523 times.
535 if (fd == -1) {
51 12 g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
52 "Could not open '%s' for writing", filename);
53 12 g_debug ("Could not open for writing '%s'", filename);
54 12 return FALSE;
55 }
56
57 523 size = strlen (value);
58
2/2
✓ Branch 0 taken 523 times.
✓ Branch 1 taken 523 times.
1046 while (size) {
59 523 ssize_t written = write (fd, value, size);
60
61
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 523 times.
523 if (written == -1) {
62 g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
63 "Error writing '%s': %s", filename, g_strerror (errno));
64 g_debug ("Error writing '%s': %s", filename, g_strerror (errno));
65 #if !GLIB_CHECK_VERSION (2, 76, 0)
66 g_close (fd, NULL);
67 #endif
68 return FALSE;
69 }
70
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 523 times.
523 g_return_val_if_fail (written <= size, FALSE);
72 523 size -= written;
73 }
74
75 #if !GLIB_CHECK_VERSION (2, 76, 0)
76 g_close (fd, NULL);
77 #endif
78
79 return TRUE;
80 }
81
82 gboolean
83 54 ppd_utils_write_files (GPtrArray *filenames,
84 const char *value,
85 GError **error)
86 {
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 g_return_val_if_fail (filenames != NULL, FALSE);
88
89
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 50 times.
110 for (guint i = 0; i < filenames->len; i++) {
90 60 const char *file = g_ptr_array_index (filenames, i);
91
92
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 56 times.
60 if (!ppd_utils_write (file, value, error))
93 return FALSE;
94 }
95
96 return TRUE;
97 }
98
99 14 gboolean ppd_utils_write_sysfs (GUdevDevice *device,
100 const char *attribute,
101 const char *value,
102 GError **error)
103 {
104 28 g_autofree char *filename = NULL;
105
106
3/8
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
14 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 g_return_val_if_fail (attribute, FALSE);
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 g_return_val_if_fail (value, FALSE);
109
110 14 filename = g_build_filename (g_udev_device_get_sysfs_path (device), attribute, NULL);
111 14 return ppd_utils_write (filename, value, error);
112 }
113
114 5 gboolean ppd_utils_write_sysfs_int (GUdevDevice *device,
115 const char *attribute,
116 gint64 value,
117 GError **error)
118 {
119 10 g_autofree char *str_value = NULL;
120
121 5 str_value = g_strdup_printf ("%" G_GINT64_FORMAT, value);
122 5 return ppd_utils_write_sysfs (device, attribute, str_value, error);
123 }
124
125 GFileMonitor *
126 8 ppd_utils_monitor_sysfs_attr (GUdevDevice *device,
127 const char *attribute,
128 GError **error)
129 {
130 16 g_autofree char *path = NULL;
131 8 g_autoptr(GFile) file = NULL;
132
133 8 path = g_build_filename (g_udev_device_get_sysfs_path (device), attribute, NULL);
134 8 file = g_file_new_for_path (path);
135 8 g_debug ("Monitoring file %s for changes", path);
136
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 return g_file_monitor_file (file,
137 G_FILE_MONITOR_NONE,
138 NULL,
139 error);
140 }
141
142 GUdevDevice *
143 51 ppd_utils_find_device (const char *subsystem,
144 GCompareFunc func,
145 gpointer user_data)
146 {
147 51 const gchar * subsystems[] = { NULL, NULL };
148 102 g_autoptr(GUdevClient) client = NULL;
149 51 GUdevDevice *ret = NULL;
150 51 GList *devices, *l;
151
152
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 g_return_val_if_fail (subsystem != NULL, NULL);
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 g_return_val_if_fail (func != NULL, NULL);
154
155 51 subsystems[0] = subsystem;
156 51 client = g_udev_client_new (subsystems);
157 51 devices = g_udev_client_query_by_subsystem (client, subsystem);
158
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 43 times.
51 if (devices == NULL)
159 return NULL;
160
161
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 for (l = devices; l != NULL; l = l->next) {
162 8 GUdevDevice *dev = l->data;
163
164
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if ((func) (dev, user_data) != 0)
165 continue;
166
167 8 ret = g_object_ref (dev);
168 8 break;
169 }
170 8 g_list_free_full (devices, g_object_unref);
171
172 8 return ret;
173 }
174
175 gboolean
176 4 ppd_utils_match_cpu_vendor (const char *vendor)
177 {
178 8 g_autofree gchar *cpuinfo_path = NULL;
179 4 g_autofree gchar *cpuinfo = NULL;
180 4 g_auto(GStrv) lines = NULL;
181
182 4 cpuinfo_path = ppd_utils_get_sysfs_path (PROC_CPUINFO_PATH);
183
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (!g_file_get_contents (cpuinfo_path, &cpuinfo, NULL, NULL))
184 return FALSE;
185
186 4 lines = g_strsplit (cpuinfo, "\n", -1);
187
188
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 for (gchar **line = lines; *line != NULL; line++) {
189
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if (g_str_has_prefix (*line, "vendor_id") &&
190
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 strchr (*line, ':')) {
191 8 g_auto(GStrv) sections = g_strsplit (*line, ":", 2);
192
193
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (g_strv_length (sections) < 2)
194 continue;
195
1/2
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
4 if (g_strcmp0 (g_strstrip (sections[1]), vendor) == 0)
196 4 return TRUE;
197 }
198 }
199
200 return FALSE;
201 }
202