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