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 | 1238 | ppd_utils_get_sysfs_path (const char *filename) | |
23 | { | ||
24 | 1238 | const char *root; | |
25 | |||
26 | 1238 | root = g_getenv ("UMOCKDEV_DIR"); | |
27 |
2/4✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1238 times.
|
1238 | if (!root || *root == '\0') |
28 | ✗ | root = "/"; | |
29 | |||
30 | 1238 | return g_build_filename (root, filename, NULL); | |
31 | } | ||
32 | |||
33 | gboolean | ||
34 | 532 | ppd_utils_write (const char *filename, | |
35 | const char *value, | ||
36 | GError **error) | ||
37 | { | ||
38 | #if GLIB_CHECK_VERSION (2, 76, 0) | ||
39 | 532 | g_autofd | |
40 | #endif | ||
41 | 532 | int fd = -1; | |
42 | 532 | size_t size; | |
43 | |||
44 |
1/2✓ Branch 0 taken 532 times.
✗ Branch 1 not taken.
|
532 | g_return_val_if_fail (filename, FALSE); |
45 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 532 times.
|
532 | g_return_val_if_fail (value, FALSE); |
46 | |||
47 | 532 | g_debug ("Writing '%s' to '%s'", value, filename); | |
48 | |||
49 | 532 | fd = g_open (filename, O_WRONLY | O_TRUNC | O_SYNC); | |
50 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 520 times.
|
532 | 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 | 520 | size = strlen (value); | |
58 |
2/2✓ Branch 0 taken 520 times.
✓ Branch 1 taken 520 times.
|
1040 | while (size) { |
59 | 520 | ssize_t written = write (fd, value, size); | |
60 | |||
61 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 520 times.
|
520 | 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 520 times.
|
520 | g_return_val_if_fail (written <= size, FALSE); |
72 | 520 | size -= written; | |
73 | } | ||
74 | |||
75 | return TRUE; | ||
76 | } | ||
77 | |||
78 | gboolean | ||
79 | 54 | ppd_utils_write_files (GPtrArray *filenames, | |
80 | const char *value, | ||
81 | GError **error) | ||
82 | { | ||
83 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
|
54 | g_return_val_if_fail (filenames != NULL, FALSE); |
84 | |||
85 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 50 times.
|
110 | for (guint i = 0; i < filenames->len; i++) { |
86 | 60 | const char *file = g_ptr_array_index (filenames, i); | |
87 | |||
88 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 56 times.
|
60 | if (!ppd_utils_write (file, value, error)) |
89 | return FALSE; | ||
90 | } | ||
91 | |||
92 | return TRUE; | ||
93 | } | ||
94 | |||
95 | 16 | gboolean ppd_utils_write_sysfs (GUdevDevice *device, | |
96 | const char *attribute, | ||
97 | const char *value, | ||
98 | GError **error) | ||
99 | { | ||
100 | 32 | g_autofree char *filename = NULL; | |
101 | |||
102 |
3/8✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
16 | g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE); |
103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | g_return_val_if_fail (attribute, FALSE); |
104 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | g_return_val_if_fail (value, FALSE); |
105 | |||
106 | 16 | filename = g_build_filename (g_udev_device_get_sysfs_path (device), attribute, NULL); | |
107 | 16 | return ppd_utils_write (filename, value, error); | |
108 | } | ||
109 | |||
110 | 10 | gboolean ppd_utils_write_sysfs_int (GUdevDevice *device, | |
111 | const char *attribute, | ||
112 | gint64 value, | ||
113 | GError **error) | ||
114 | { | ||
115 | 20 | g_autofree char *str_value = NULL; | |
116 | |||
117 | 10 | str_value = g_strdup_printf ("%" G_GINT64_FORMAT, value); | |
118 | 10 | return ppd_utils_write_sysfs (device, attribute, str_value, error); | |
119 | } | ||
120 | |||
121 | GFileMonitor * | ||
122 | 8 | ppd_utils_monitor_sysfs_attr (GUdevDevice *device, | |
123 | const char *attribute, | ||
124 | GError **error) | ||
125 | { | ||
126 | 16 | g_autofree char *path = NULL; | |
127 | 8 | g_autoptr(GFile) file = NULL; | |
128 | |||
129 | 8 | path = g_build_filename (g_udev_device_get_sysfs_path (device), attribute, NULL); | |
130 | 8 | file = g_file_new_for_path (path); | |
131 | 8 | g_debug ("Monitoring file %s for changes", path); | |
132 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | return g_file_monitor_file (file, |
133 | G_FILE_MONITOR_NONE, | ||
134 | NULL, | ||
135 | error); | ||
136 | } | ||
137 | |||
138 | GUdevDevice * | ||
139 | 50 | ppd_utils_find_device (const char *subsystem, | |
140 | GCompareFunc func, | ||
141 | gpointer user_data) | ||
142 | { | ||
143 | 50 | const gchar * subsystems[] = { NULL, NULL }; | |
144 | 100 | g_autoptr(GUdevClient) client = NULL; | |
145 | 50 | GUdevDevice *ret = NULL; | |
146 | 50 | GList *devices, *l; | |
147 | |||
148 |
1/2✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
|
50 | g_return_val_if_fail (subsystem != NULL, NULL); |
149 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
|
50 | g_return_val_if_fail (func != NULL, NULL); |
150 | |||
151 | 50 | subsystems[0] = subsystem; | |
152 | 50 | client = g_udev_client_new (subsystems); | |
153 | 50 | devices = g_udev_client_query_by_subsystem (client, subsystem); | |
154 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 42 times.
|
50 | if (devices == NULL) |
155 | return NULL; | ||
156 | |||
157 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | for (l = devices; l != NULL; l = l->next) { |
158 | 8 | GUdevDevice *dev = l->data; | |
159 | |||
160 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if ((func) (dev, user_data) != 0) |
161 | ✗ | continue; | |
162 | |||
163 | 8 | ret = g_object_ref (dev); | |
164 | 8 | break; | |
165 | } | ||
166 | 8 | g_list_free_full (devices, g_object_unref); | |
167 | |||
168 | 8 | return ret; | |
169 | } | ||
170 | |||
171 | gboolean | ||
172 | 266 | ppd_utils_match_cpu_vendor (const char *vendor) | |
173 | { | ||
174 | 532 | g_autofree gchar *cpuinfo_path = NULL; | |
175 | 266 | g_autofree gchar *cpuinfo = NULL; | |
176 | 266 | g_auto(GStrv) lines = NULL; | |
177 | |||
178 | 266 | cpuinfo_path = ppd_utils_get_sysfs_path (PROC_CPUINFO_PATH); | |
179 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 248 times.
|
266 | if (!g_file_get_contents (cpuinfo_path, &cpuinfo, NULL, NULL)) |
180 | return FALSE; | ||
181 | |||
182 | 18 | lines = g_strsplit (cpuinfo, "\n", -1); | |
183 | |||
184 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | for (gchar **line = lines; *line != NULL; line++) { |
185 |
2/4✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
18 | if (g_str_has_prefix (*line, "vendor_id") && |
186 |
1/2✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
|
18 | strchr (*line, ':')) { |
187 | 36 | g_auto(GStrv) sections = g_strsplit (*line, ":", 2); | |
188 | |||
189 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
|
18 | if (g_strv_length (sections) < 2) |
190 | ✗ | continue; | |
191 |
1/2✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
|
18 | if (g_strcmp0 (g_strstrip (sections[1]), vendor) == 0) |
192 | 18 | return TRUE; | |
193 | } | ||
194 | } | ||
195 | |||
196 | return FALSE; | ||
197 | } | ||
198 |