Branch data Line data Source code
1 : : /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 : : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
3 : : // SPDX-FileCopyrightText: 2008 litl, LLC
4 : :
5 : : #ifndef UTIL_MISC_H_
6 : : #define UTIL_MISC_H_
7 : :
8 : : #include <errno.h>
9 : : #include <stdio.h> // for FILE, stdout
10 : : #include <string.h> // for memcpy
11 : :
12 : : #include <glib.h> // for g_malloc
13 : :
14 : : #ifdef G_DISABLE_ASSERT
15 : : # define GJS_USED_ASSERT [[maybe_unused]]
16 : : #else
17 : : # define GJS_USED_ASSERT
18 : : #endif
19 : :
20 : : bool gjs_environment_variable_is_set (const char *env_variable_name);
21 : :
22 : : char** gjs_g_strv_concat(char*** strv_array, int len);
23 : :
24 : : /*
25 : : * _gjs_memdup2:
26 : : * @mem: (nullable): the memory to copy.
27 : : * @byte_size: the number of bytes to copy.
28 : : *
29 : : * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it
30 : : * from @mem. If @mem is null or @byte_size is 0 it returns null.
31 : : *
32 : : * This replaces g_memdup(), which was prone to integer overflows when
33 : : * converting the argument from a gsize to a guint.
34 : : *
35 : : * This static inline version is a backport of the new public g_memdup2() API
36 : : * from GLib 2.68.
37 : : * See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1927.
38 : : * It should be replaced when GLib 2.68 becomes the stable branch.
39 : : *
40 : : * Returns: (nullable): a pointer to the newly-allocated copy of the memory,
41 : : * or null if @mem is null.
42 : : */
43 : 79 : static inline void* _gjs_memdup2(const void* mem, size_t byte_size) {
44 [ + - + + ]: 79 : if (!mem || byte_size == 0)
45 : 1 : return nullptr;
46 : :
47 : 78 : void* new_mem = g_malloc(byte_size);
48 : 78 : memcpy(new_mem, mem, byte_size);
49 : 78 : return new_mem;
50 : : }
51 : :
52 : : /*
53 : : * LogFile:
54 : : * RAII class encapsulating access to a FILE* pointer that must be closed,
55 : : * unless it is an already-open fallback file such as stdout or stderr.
56 : : */
57 : : class LogFile {
58 : : FILE* m_fp;
59 : : const char* m_errmsg;
60 : : bool m_should_close : 1;
61 : :
62 : : LogFile(const LogFile&) = delete;
63 : : LogFile& operator=(const LogFile&) = delete;
64 : :
65 : : public:
66 : 106 : explicit LogFile(const char* filename, FILE* fallback_fp = stdout)
67 : 106 : : m_errmsg(nullptr), m_should_close(false) {
68 [ + + ]: 106 : if (filename) {
69 : 3 : m_fp = fopen(filename, "a");
70 [ + + ]: 3 : if (!m_fp)
71 : 2 : m_errmsg = strerror(errno);
72 : : else
73 : 1 : m_should_close = true;
74 : : } else {
75 : 103 : m_fp = fallback_fp;
76 : : }
77 : 106 : }
78 : :
79 : 106 : ~LogFile() {
80 [ + + ]: 106 : if (m_should_close)
81 : 1 : fclose(m_fp);
82 : 106 : }
83 : :
84 : 3 : FILE* fp() { return m_fp; }
85 : 3 : bool has_error() { return !!m_errmsg; }
86 : 2 : const char* errmsg() { return m_errmsg; }
87 : : };
88 : :
89 : : #endif // UTIL_MISC_H_
|