/src/rauc/include/utils.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <gio/gio.h> |
4 | | #include <glib.h> |
5 | | |
6 | 146 | #define R_UTILS_ERROR r_utils_error_quark() |
7 | | |
8 | | GQuark r_utils_error_quark(void); |
9 | | |
10 | | typedef enum { |
11 | | R_UTILS_ERROR_FAILED, |
12 | | R_UTILS_ERROR_INAPPROPRIATE_IOCTL, |
13 | | R_UTILS_ERROR_INVALID_ENV_KEY, |
14 | | R_UTILS_ERROR_SEMVER_PARSE, |
15 | | R_UTILS_ERROR_OPEN_FILE, |
16 | | } RUtilsError; |
17 | | |
18 | | #define BIT(nr) (1UL << (nr)) |
19 | | |
20 | | /* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno' |
21 | | * set to EINTR. Needed for builds against musl, taken from glibc's unistd.h. |
22 | | */ |
23 | | #ifndef TEMP_FAILURE_RETRY |
24 | | #define TEMP_FAILURE_RETRY(expression) \ |
25 | | (__extension__ \ |
26 | | ({ long int __result; \ |
27 | | do {__result = (long int) (expression);} \ |
28 | | while (__result == -1L && errno == EINTR); \ |
29 | | __result; })) |
30 | | #endif |
31 | | |
32 | | /* Use |
33 | | * |
34 | | * g_auto(filedesc) fd = -1 |
35 | | * |
36 | | * to declare a file descriptor that will be automatically closed when |
37 | | * fd goes out of scope. The destructor is guaranteed to preserve |
38 | | * errno. |
39 | | */ |
40 | | typedef int filedesc; |
41 | | void close_preserve_errno(filedesc fd); |
42 | | G_DEFINE_AUTO_CLEANUP_FREE_FUNC(filedesc, close_preserve_errno, -1) |
43 | | |
44 | 0 | #define R_LOG_DOMAIN_SUBPROCESS "rauc-subprocess" |
45 | | |
46 | | static inline GSubprocess* r_subprocess_newv(GPtrArray *args, GSubprocessFlags flags, GError **error) |
47 | 0 | { |
48 | 0 | g_return_val_if_fail(args, NULL); |
49 | 0 | g_return_val_if_fail(args->len, NULL); |
50 | 0 | g_return_val_if_fail(args->pdata[args->len-1] == NULL, NULL); |
51 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, FALSE); |
52 | 0 | g_autofree gchar *call = g_strjoinv(" ", (gchar**) args->pdata); |
53 | 0 | g_log(R_LOG_DOMAIN_SUBPROCESS, G_LOG_LEVEL_DEBUG, "launching subprocess: %s", call); |
54 | |
|
55 | 0 | return g_subprocess_newv((const gchar * const *) args->pdata, flags, error); |
56 | 0 | } Unexecuted instantiation: manifest.c:r_subprocess_newv Unexecuted instantiation: utils.c:r_subprocess_newv Unexecuted instantiation: checksum.c:r_subprocess_newv Unexecuted instantiation: context.c:r_subprocess_newv Unexecuted instantiation: event_log.c:r_subprocess_newv Unexecuted instantiation: signature.c:r_subprocess_newv Unexecuted instantiation: status_file.c:r_subprocess_newv Unexecuted instantiation: bootchooser.c:r_subprocess_newv Unexecuted instantiation: barebox.c:r_subprocess_newv Unexecuted instantiation: custom.c:r_subprocess_newv Unexecuted instantiation: efi.c:r_subprocess_newv Unexecuted instantiation: grub.c:r_subprocess_newv Unexecuted instantiation: uboot.c:r_subprocess_newv Unexecuted instantiation: config_file.c:r_subprocess_newv Unexecuted instantiation: install.c:r_subprocess_newv Unexecuted instantiation: mark.c:r_subprocess_newv Unexecuted instantiation: mount.c:r_subprocess_newv Unexecuted instantiation: service.c:r_subprocess_newv Unexecuted instantiation: shell.c:r_subprocess_newv Unexecuted instantiation: slot.c:r_subprocess_newv Unexecuted instantiation: update_handler.c:r_subprocess_newv Unexecuted instantiation: update_utils.c:r_subprocess_newv Unexecuted instantiation: artifacts.c:r_subprocess_newv Unexecuted instantiation: bundle.c:r_subprocess_newv Unexecuted instantiation: crypt.c:r_subprocess_newv Unexecuted instantiation: emmc.c:r_subprocess_newv Unexecuted instantiation: hash_index.c:r_subprocess_newv Unexecuted instantiation: mbr.c:r_subprocess_newv |
57 | | |
58 | | static inline GSubprocess * r_subprocess_launcher_spawnv(GSubprocessLauncher *launcher, GPtrArray *args, GError **error) |
59 | 0 | { |
60 | 0 | g_return_val_if_fail(launcher, NULL); |
61 | 0 | g_return_val_if_fail(args, NULL); |
62 | 0 | g_return_val_if_fail(args->len, NULL); |
63 | 0 | g_return_val_if_fail(args->pdata[args->len-1] == NULL, NULL); |
64 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, FALSE); |
65 | 0 | g_autofree gchar *call = g_strjoinv(" ", (gchar**) args->pdata); |
66 | 0 | g_log(R_LOG_DOMAIN_SUBPROCESS, G_LOG_LEVEL_DEBUG, "launching subprocess: %s", call); |
67 | |
|
68 | 0 | return g_subprocess_launcher_spawnv(launcher, |
69 | 0 | (const gchar * const *)args->pdata, error); |
70 | 0 | } Unexecuted instantiation: manifest.c:r_subprocess_launcher_spawnv Unexecuted instantiation: utils.c:r_subprocess_launcher_spawnv Unexecuted instantiation: checksum.c:r_subprocess_launcher_spawnv Unexecuted instantiation: context.c:r_subprocess_launcher_spawnv Unexecuted instantiation: event_log.c:r_subprocess_launcher_spawnv Unexecuted instantiation: signature.c:r_subprocess_launcher_spawnv Unexecuted instantiation: status_file.c:r_subprocess_launcher_spawnv Unexecuted instantiation: bootchooser.c:r_subprocess_launcher_spawnv Unexecuted instantiation: barebox.c:r_subprocess_launcher_spawnv Unexecuted instantiation: custom.c:r_subprocess_launcher_spawnv Unexecuted instantiation: efi.c:r_subprocess_launcher_spawnv Unexecuted instantiation: grub.c:r_subprocess_launcher_spawnv Unexecuted instantiation: uboot.c:r_subprocess_launcher_spawnv Unexecuted instantiation: config_file.c:r_subprocess_launcher_spawnv Unexecuted instantiation: install.c:r_subprocess_launcher_spawnv Unexecuted instantiation: mark.c:r_subprocess_launcher_spawnv Unexecuted instantiation: mount.c:r_subprocess_launcher_spawnv Unexecuted instantiation: service.c:r_subprocess_launcher_spawnv Unexecuted instantiation: shell.c:r_subprocess_launcher_spawnv Unexecuted instantiation: slot.c:r_subprocess_launcher_spawnv Unexecuted instantiation: update_handler.c:r_subprocess_launcher_spawnv Unexecuted instantiation: update_utils.c:r_subprocess_launcher_spawnv Unexecuted instantiation: artifacts.c:r_subprocess_launcher_spawnv Unexecuted instantiation: bundle.c:r_subprocess_launcher_spawnv Unexecuted instantiation: crypt.c:r_subprocess_launcher_spawnv Unexecuted instantiation: emmc.c:r_subprocess_launcher_spawnv Unexecuted instantiation: hash_index.c:r_subprocess_launcher_spawnv Unexecuted instantiation: mbr.c:r_subprocess_launcher_spawnv |
71 | | |
72 | | GSubprocess *r_subprocess_new(GSubprocessFlags flags, GError **error, const gchar *argv0, ...) |
73 | | G_GNUC_WARN_UNUSED_RESULT; |
74 | | |
75 | | /** |
76 | | * Starts a subprocess and waits for it to finish. |
77 | | * |
78 | | * @param args subprocess arguments |
79 | | * @param flags subprocess flags |
80 | | * @param error return location for a GError, or NULL |
81 | | * |
82 | | * @return TRUE on success, FALSE if an error occurred |
83 | | */ |
84 | | gboolean r_subprocess_runv(GPtrArray *args, GSubprocessFlags flags, GError **error) |
85 | | G_GNUC_WARN_UNUSED_RESULT; |
86 | | |
87 | | #define R_LOG_LEVEL_TRACE 1 << G_LOG_LEVEL_USER_SHIFT |
88 | | #define r_trace(...) g_log(G_LOG_DOMAIN, \ |
89 | | R_LOG_LEVEL_TRACE, \ |
90 | | __VA_ARGS__) |
91 | | |
92 | | /** |
93 | | * Adds elements of a zero-terminated GStrv/gchar** to an existing GPtrArray |
94 | | * |
95 | | * @param ptrarray GPtrArray to add to |
96 | | * @param argvp arguments to add (may be NULL) |
97 | | * @param copy whether to just add the pointer (FALSE) or copy the underlying data (TRUE) |
98 | | */ |
99 | | static inline void r_ptr_array_addv(GPtrArray *ptrarray, gchar **argvp, gboolean copy) |
100 | 0 | { |
101 | 0 | if (argvp == NULL) |
102 | 0 | return; |
103 | | |
104 | 0 | for (gchar **addarg = argvp; *addarg != NULL; addarg++) { |
105 | 0 | g_ptr_array_add(ptrarray, copy ? g_strdup(*addarg) : *addarg); |
106 | 0 | } |
107 | 0 | } Unexecuted instantiation: manifest.c:r_ptr_array_addv Unexecuted instantiation: utils.c:r_ptr_array_addv Unexecuted instantiation: checksum.c:r_ptr_array_addv Unexecuted instantiation: context.c:r_ptr_array_addv Unexecuted instantiation: event_log.c:r_ptr_array_addv Unexecuted instantiation: signature.c:r_ptr_array_addv Unexecuted instantiation: status_file.c:r_ptr_array_addv Unexecuted instantiation: bootchooser.c:r_ptr_array_addv Unexecuted instantiation: barebox.c:r_ptr_array_addv Unexecuted instantiation: custom.c:r_ptr_array_addv Unexecuted instantiation: efi.c:r_ptr_array_addv Unexecuted instantiation: grub.c:r_ptr_array_addv Unexecuted instantiation: uboot.c:r_ptr_array_addv Unexecuted instantiation: config_file.c:r_ptr_array_addv Unexecuted instantiation: install.c:r_ptr_array_addv Unexecuted instantiation: mark.c:r_ptr_array_addv Unexecuted instantiation: mount.c:r_ptr_array_addv Unexecuted instantiation: service.c:r_ptr_array_addv Unexecuted instantiation: shell.c:r_ptr_array_addv Unexecuted instantiation: slot.c:r_ptr_array_addv Unexecuted instantiation: update_handler.c:r_ptr_array_addv Unexecuted instantiation: update_utils.c:r_ptr_array_addv Unexecuted instantiation: artifacts.c:r_ptr_array_addv Unexecuted instantiation: bundle.c:r_ptr_array_addv Unexecuted instantiation: crypt.c:r_ptr_array_addv Unexecuted instantiation: emmc.c:r_ptr_array_addv Unexecuted instantiation: hash_index.c:r_ptr_array_addv Unexecuted instantiation: mbr.c:r_ptr_array_addv |
108 | | |
109 | | /** |
110 | | * Adds a formatted string to the end of a GPtrArray |
111 | | * |
112 | | * This is a shorter alternative to: |
113 | | * g_ptr_array_add(arr, g_strdup_printf("%s: %s", ...)); |
114 | | * |
115 | | * @param ptrarray GPtrArray to add to |
116 | | * @param format the printf-like format string |
117 | | * @param ... the parameters for the format string |
118 | | */ |
119 | | void r_ptr_array_add_printf(GPtrArray *ptrarray, const gchar *format, ...) |
120 | | __attribute__((__format__(__printf__, 2, 3))); |
121 | | |
122 | | /** |
123 | | * Converts an array of 'key=value' strings to a shell quoted string. |
124 | | * |
125 | | * This is useful when generating shell-parsable output. |
126 | | * |
127 | | * @param ptrarray the GPtrArray to print |
128 | | */ |
129 | | gchar *r_ptr_array_env_to_shell(const GPtrArray *ptrarray); |
130 | | |
131 | | /** |
132 | | * Calls g_environ_setenv for each 'key=value' string in the array. |
133 | | * |
134 | | * This is useful when setting up the environment for a subprocess. |
135 | | * |
136 | | * @param envp an environment list |
137 | | * @param ptrarray the GPtrArray to add to the environment |
138 | | * @param overwrite whether to change existing variables |
139 | | */ |
140 | | gchar **r_environ_setenv_ptr_array(gchar **envp, const GPtrArray *ptrarray, gboolean overwrite) |
141 | | G_GNUC_WARN_UNUSED_RESULT; |
142 | | |
143 | | /** |
144 | | * Calls g_subprocess_launcher_setenv for each 'key=value' string in the array. |
145 | | * |
146 | | * This is useful when setting up the environment via a subprocess launcher. |
147 | | * |
148 | | * @param launcher a GSubprocessLauncher |
149 | | * @param ptrarray the GPtrArray to add to the environment |
150 | | * @param overwrite whether to change existing variables |
151 | | */ |
152 | | void r_subprocess_launcher_setenv_ptr_array(GSubprocessLauncher *launcher, const GPtrArray *ptrarray, gboolean overwrite); |
153 | | |
154 | | /** |
155 | | * Read file content into a GBytes. |
156 | | * |
157 | | * @param filename Filename to read from |
158 | | * @param error return location for a GError, or NULL |
159 | | * |
160 | | * @return A newly allocated GBytes on success, NULL if an error occurred |
161 | | */ |
162 | | GBytes *read_file(const gchar *filename, GError **error) |
163 | | G_GNUC_WARN_UNUSED_RESULT; |
164 | | |
165 | | /** |
166 | | * Read file content into a gchar. |
167 | | * |
168 | | * @param filename Filename to read from |
169 | | * @param error return location for a GError, or NULL |
170 | | * |
171 | | * @return A newly allocated gchar on success, NULL if an error occurred |
172 | | */ |
173 | | gchar *read_file_str(const gchar *filename, GError **error) |
174 | | G_GNUC_WARN_UNUSED_RESULT; |
175 | | |
176 | | /** |
177 | | * Write content of a GBytes to file. |
178 | | * |
179 | | * @param filename |
180 | | * @param bytes |
181 | | * @param error return location for a GError, or NULL |
182 | | * |
183 | | * @return TRUE on success, FALSE if an error occurred |
184 | | */ |
185 | | gboolean write_file(const gchar *filename, GBytes *bytes, GError **error) |
186 | | G_GNUC_WARN_UNUSED_RESULT; |
187 | | |
188 | | /** |
189 | | * Copy a file. |
190 | | * |
191 | | * @param srcprefix Prefix path to append to filename given in srcfile |
192 | | * @param srcfile filename or path of file to copy from |
193 | | * @param dtsprefix Prefix path to append to filename given in dstfile |
194 | | * @param dstfile filename or path of file to copy to |
195 | | * @param error return location for a GError, or NULL |
196 | | * |
197 | | * @return TRUE on success, FALSE if an error occurred |
198 | | */ |
199 | | gboolean copy_file(const gchar *srcprefix, const gchar *srcfile, |
200 | | const gchar *dstprefix, const gchar *dstfile, GError **error) |
201 | | G_GNUC_WARN_UNUSED_RESULT; |
202 | | |
203 | | /** |
204 | | * Recursively delete directory contents. |
205 | | * |
206 | | * @param path path of directory to delete |
207 | | * @param error return location for a GError, or NULL |
208 | | * |
209 | | * @return TRUE on success, FALSE if an error occurred |
210 | | */ |
211 | | gboolean rm_tree(const gchar *path, GError **error); |
212 | | |
213 | | /** |
214 | | * Recursively check directory tree for open files. |
215 | | * |
216 | | * @param path path of directory to check |
217 | | * @param error return location for a GError, or NULL |
218 | | * |
219 | | * @return TRUE if no files are open, FALSE otherwise |
220 | | */ |
221 | | gboolean r_tree_check_open(const gchar *path, GError **error) |
222 | | G_GNUC_WARN_UNUSED_RESULT; |
223 | | |
224 | | /** |
225 | | * Resolve path based on directory of `basefile` argument or current working dir. |
226 | | * |
227 | | * This is useful for parsing paths from config files where the path locations |
228 | | * may depend on the config files location. In this case `path` would be the |
229 | | * pathname set in the config file, and `basefile` would be the path to the |
230 | | * config file itself. |
231 | | * |
232 | | * If given path itself is absolute, this will be returned. |
233 | | * If `basefile` is given and absolute, its location (with the pathname |
234 | | * stripped) will be used as the prefix path for `path`. |
235 | | * If `basefile` is not an absolute path, the current workding dir will be used |
236 | | * as the prefix path for `path` instead. |
237 | | * |
238 | | * @param basefile Reference path to resolve `path` to |
239 | | * @param path The path to resolve an absolute path for |
240 | | * |
241 | | * @return An absolute path name, determined as described above, NULL if undeterminable |
242 | | * [transfer full] |
243 | | */ |
244 | | gchar *resolve_path(const gchar *basefile, const gchar *path) |
245 | | G_GNUC_WARN_UNUSED_RESULT; |
246 | | |
247 | | /** |
248 | | * Resolve path based on directory of `basefile` argument or current working dir |
249 | | * and free path. |
250 | | * |
251 | | * This is a wrapper around resolve_path(), for use when the path argument is |
252 | | * not needed after the call. |
253 | | * |
254 | | * @param basefile Reference path to resolve `path` to |
255 | | * @param path The path to resolve an absolute path for (freed) |
256 | | * |
257 | | * @return An absolute path name, determined as described above, NULL if undeterminable |
258 | | * [transfer full] |
259 | | */ |
260 | | gchar *resolve_path_take(const gchar *basefile, gchar *path) |
261 | | G_GNUC_WARN_UNUSED_RESULT; |
262 | | |
263 | | gboolean check_remaining_groups(GKeyFile *key_file, GError **error) |
264 | | G_GNUC_WARN_UNUSED_RESULT; |
265 | | gboolean check_remaining_keys(GKeyFile *key_file, const gchar *groupname, GError **error) |
266 | | G_GNUC_WARN_UNUSED_RESULT; |
267 | | |
268 | | /** |
269 | | * Get string argument from key and remove key from key_file. |
270 | | * |
271 | | * @return A newly allocated string or NULL on error. |
272 | | */ |
273 | | gchar * key_file_consume_string( |
274 | | GKeyFile *key_file, |
275 | | const gchar *group_name, |
276 | | const gchar *key, |
277 | | GError **error) |
278 | | G_GNUC_WARN_UNUSED_RESULT; |
279 | | |
280 | | /** |
281 | | * Ensure that the input string contains neither whitespace nor tab. |
282 | | * |
283 | | * @param str string to check. |
284 | | * |
285 | | * @return TRUE if str contains neither whitespace nor tab, FALSE otherwise |
286 | | */ |
287 | | gboolean value_check_tab_whitespace(const gchar *str, GError **error) |
288 | | G_GNUC_WARN_UNUSED_RESULT; |
289 | | |
290 | | /** |
291 | | * Get integer argument from key and remove key from key_file. |
292 | | */ |
293 | | gint key_file_consume_integer( |
294 | | GKeyFile *key_file, |
295 | | const gchar *group_name, |
296 | | const gchar *key, |
297 | | GError **error) |
298 | | G_GNUC_WARN_UNUSED_RESULT; |
299 | | |
300 | | guint64 key_file_consume_binary_suffixed_string(GKeyFile *key_file, |
301 | | const gchar *group_name, |
302 | | const gchar *key, |
303 | | GError **error) |
304 | | G_GNUC_WARN_UNUSED_RESULT; |
305 | | |
306 | | gchar * r_realpath(const gchar *path) |
307 | | G_GNUC_WARN_UNUSED_RESULT; |
308 | | |
309 | | /** |
310 | | * Remove surrounding whitespace and signal changes. |
311 | | * |
312 | | * @param str string to modify |
313 | | * |
314 | | * @return TRUE if whitespace was removed, FALSE otherwise |
315 | | */ |
316 | | gboolean r_whitespace_removed(gchar *str) |
317 | | G_GNUC_WARN_UNUSED_RESULT; |
318 | | |
319 | | guint8 *r_hex_decode(const gchar *hex, size_t len) |
320 | | G_GNUC_WARN_UNUSED_RESULT; |
321 | | gchar *r_hex_encode(const guint8 *raw, size_t len) |
322 | | G_GNUC_WARN_UNUSED_RESULT; |
323 | | |
324 | | gboolean r_read_exact(const int fd, guint8 *data, size_t size, GError **error) |
325 | | G_GNUC_WARN_UNUSED_RESULT; |
326 | | gboolean r_write_exact(const int fd, const guint8 *data, size_t size, GError **error) |
327 | | G_GNUC_WARN_UNUSED_RESULT; |
328 | | |
329 | | gboolean r_pread_exact(const int fd, guint8 *data, size_t size, off_t offset, GError **error) |
330 | | G_GNUC_WARN_UNUSED_RESULT; |
331 | | |
332 | | gboolean r_pwrite_exact(const int fd, const guint8 *data, size_t size, off_t offset, GError **error) |
333 | | G_GNUC_WARN_UNUSED_RESULT; |
334 | | |
335 | | gboolean r_pwrite_lazy(const int fd, const guint8 *data, size_t size, off_t offset, GError **error) |
336 | | G_GNUC_WARN_UNUSED_RESULT; |
337 | | |
338 | | guint get_sectorsize(gint fd) |
339 | | G_GNUC_WARN_UNUSED_RESULT; |
340 | | |
341 | | goffset get_device_size(gint fd, GError **error) |
342 | | G_GNUC_WARN_UNUSED_RESULT; |
343 | | |
344 | | /** |
345 | | * Replaces a string pointer with a newly allocated copy of the source string. |
346 | | * |
347 | | * If the pointer was non-NULL previously, the old string is freed. |
348 | | * |
349 | | * @param dst the pointer to update |
350 | | * @param src the string to copy |
351 | | */ |
352 | | void r_replace_strdup(gchar **dst, const gchar *src); |
353 | | |
354 | | /** |
355 | | * Converts a key for use in an environment variable name. |
356 | | * |
357 | | * Only alphanumeric characters and '_' are allowed. '-' is converted to '_'. |
358 | | * |
359 | | * @param key string to convert |
360 | | * @param error return location for a GError, or NULL |
361 | | * |
362 | | * @return the newly alloacted and converted string |
363 | | */ |
364 | | gchar *r_prepare_env_key(const gchar *key, GError **error) |
365 | | G_GNUC_WARN_UNUSED_RESULT; |
366 | | |
367 | | /** |
368 | | * Atomically updates a symlink (if needed). |
369 | | * |
370 | | * @param target new target for the symlink |
371 | | * @param name filename of the symlink to update |
372 | | * @param error return location for a GError, or NULL |
373 | | * |
374 | | * @return TRUE if the symlink now points to the given target, FALSE otherwise |
375 | | */ |
376 | | gboolean r_update_symlink(const gchar *target, const gchar *name, GError **error) |
377 | | G_GNUC_WARN_UNUSED_RESULT; |
378 | | |
379 | | /** |
380 | | * Calls syncfs on a given filesystem. |
381 | | * |
382 | | * @param path path on the filesystem to sync |
383 | | * @param error return location for a GError, or NULL |
384 | | * |
385 | | * @return TRUE if the filesystem was synced, FALSE otherwise |
386 | | */ |
387 | | gboolean r_syncfs(const gchar *path, GError **error) |
388 | | G_GNUC_WARN_UNUSED_RESULT; |
389 | | |
390 | | /** |
391 | | * Create a temporary directory for the fakeroot environment file. |
392 | | * |
393 | | * @param error return location for a GError, or NULL |
394 | | * |
395 | | * @return path to the env file, NULL on error |
396 | | */ |
397 | | gchar* r_fakeroot_init(GError **error) |
398 | | G_GNUC_WARN_UNUSED_RESULT; |
399 | | |
400 | | /** |
401 | | * Add fakeroot startup arguments to the array. |
402 | | * |
403 | | * The env file needs to be created with r_fakeroot_init first. |
404 | | * Does nothing if the path is NULL. |
405 | | * |
406 | | * @param args the GPtrArray to modify |
407 | | * @param envpath path to the env file |
408 | | */ |
409 | | void r_fakeroot_add_args(GPtrArray *args, const gchar *envpath); |
410 | | |
411 | | /** |
412 | | * Removes the temporary directory containing the fakeroot environment file. |
413 | | * |
414 | | * Does nothing if the path is NULL. |
415 | | * |
416 | | * @param envpath path to the env file |
417 | | * @param error return location for a GError, or NULL |
418 | | * |
419 | | * @return TRUE if the cleanup was successful, FALSE otherwise |
420 | | */ |
421 | | gboolean r_fakeroot_cleanup(const gchar *envpath, GError **error) |
422 | | G_GNUC_WARN_UNUSED_RESULT; |
423 | | |
424 | | /** |
425 | | * Removes a temporary file and frees the filename string. |
426 | | * |
427 | | * Does nothing if the path is NULL. If the filename does not refer to a |
428 | | * regular file, it only frees the string. |
429 | | * |
430 | | * @param filename path to the temporary file |
431 | | */ |
432 | | void r_tempfile_cleanup(gchar *filename); |
433 | | |
434 | | /* Use |
435 | | * |
436 | | * g_auto(RTempFile) filename = g_build_filename(...); |
437 | | * |
438 | | * to declare a file that will be automatically removed when |
439 | | * filename goes out of scope. |
440 | | * |
441 | | * If the file should become permanent on success, simply use |
442 | | * |
443 | | * g_clear_pointer(&filename, g_free); |
444 | | * |
445 | | * to avoid the automatic cleanup. |
446 | | */ |
447 | | typedef gchar* RTempFile; |
448 | | G_DEFINE_AUTO_CLEANUP_FREE_FUNC(RTempFile, r_tempfile_cleanup, NULL) |
449 | | |
450 | | /** |
451 | | * Returns the contents of the GBytes as a '\0'-terminated string. |
452 | | * |
453 | | * The provided GBytes pointer is freed and nulled. |
454 | | * Internally, it uses g_strndup. |
455 | | * |
456 | | * @param bytes GBytes to take the contents from |
457 | | * |
458 | | * @return null-terminated string, to be freed by the caller |
459 | | */ |
460 | | gchar *r_bytes_unref_to_string(GBytes **bytes) |
461 | | G_GNUC_WARN_UNUSED_RESULT; |
462 | | |
463 | | /** |
464 | | * Parse a "semantic version" string into its constituents. |
465 | | * |
466 | | * |
467 | | * @param version_string input string |
468 | | * @param[out] version_core return location for version-core as {major,minor,patch} |
469 | | * @param[out] pre_release return location for pre_release version part, can be NULL |
470 | | * @param[out] build return location for build version part, can be NULL |
471 | | * @param[out] error return location for a GError, or NULL |
472 | | * |
473 | | * @return TRUE if the parsing was successful, FALSE otherwise |
474 | | */ |
475 | | gboolean r_semver_parse(const gchar *version_string, guint64 version_core[3], gchar **pre_release, gchar **build, GError **error); |
476 | | |
477 | | /** |
478 | | * Compare two "semantic version" strings over their version-core and pre_release identifier. |
479 | | * |
480 | | * @param version_string_a version A |
481 | | * @param version_string_b version B |
482 | | * @param error return location for a GError, or NULL |
483 | | * |
484 | | * @return TRUE if A<=B, FALSE otherwise |
485 | | */ |
486 | | gboolean r_semver_less_equal(const gchar *version_string_a, const gchar *version_string_b, GError **error); |
487 | | |
488 | | /** |
489 | | * Converts a duration given in seconds into a short human-readable string. |
490 | | * The format is compact and space-separated, for example: "2h 15m 30s". |
491 | | * |
492 | | * Units are: |
493 | | * - Days: "d" |
494 | | * - Hours: "h" |
495 | | * - Minutes: "m" |
496 | | * - Seconds: "s" |
497 | | * |
498 | | * Units with zero values are omitted (except when the entire duration is zero, |
499 | | * in which case "0s" is returned). |
500 | | * |
501 | | * @param total_seconds duration in seconds |
502 | | * |
503 | | * @return newly-allocated string representing the formatted duration |
504 | | */ |
505 | | gchar *r_format_duration(gint64 total_seconds); |
506 | | |
507 | | /** |
508 | | * Compiles, matches and fetches the match in one call. |
509 | | * |
510 | | * This should only be used to simplify code in non-performance-critical places. |
511 | | * |
512 | | * @param pattern the regular expression |
513 | | * @param string the string to search |
514 | | * |
515 | | * @return newly-allocated string with the matched substring or NULL |
516 | | */ |
517 | | gchar *r_regex_match_simple(const gchar *pattern, const gchar *string) |
518 | | G_GNUC_WARN_UNUSED_RESULT; |