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 : 71 : static inline void* _gjs_memdup2(const void* mem, size_t byte_size) { 44 [ + - - + ]: 71 : if (!mem || byte_size == 0) 45 : 0 : return nullptr; 46 : : 47 : 71 : void* new_mem = g_malloc(byte_size); 48 : 71 : memcpy(new_mem, mem, byte_size); 49 : 71 : 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 : 105 : explicit LogFile(const char* filename, FILE* fallback_fp = stdout) 67 : 105 : : m_errmsg(nullptr), m_should_close(false) { 68 [ + + ]: 105 : 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 : 102 : m_fp = fallback_fp; 76 : : } 77 : 105 : } 78 : : 79 : 105 : ~LogFile() { 80 [ + + ]: 105 : if (m_should_close) 81 : 1 : fclose(m_fp); 82 : 105 : } 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_