xref: /openbmc/qemu/include/glib-compat.h (revision 3d48b6b687c558a042d91370633b91c6e29e0e05)
1d63c9477SAnthony Liguori /*
2d63c9477SAnthony Liguori  * GLIB Compatibility Functions
3d63c9477SAnthony Liguori  *
4d63c9477SAnthony Liguori  * Copyright IBM, Corp. 2013
5d63c9477SAnthony Liguori  *
6d63c9477SAnthony Liguori  * Authors:
7d63c9477SAnthony Liguori  *  Anthony Liguori   <aliguori@us.ibm.com>
886946a2dSMichael Tokarev  *  Michael Tokarev   <mjt@tls.msk.ru>
986946a2dSMichael Tokarev  *  Paolo Bonzini     <pbonzini@redhat.com>
10d63c9477SAnthony Liguori  *
11d63c9477SAnthony Liguori  * This work is licensed under the terms of the GNU GPL, version 2 or later.
12d63c9477SAnthony Liguori  * See the COPYING file in the top-level directory.
13d63c9477SAnthony Liguori  *
14d63c9477SAnthony Liguori  */
15d63c9477SAnthony Liguori 
16d63c9477SAnthony Liguori #ifndef QEMU_GLIB_COMPAT_H
17d63c9477SAnthony Liguori #define QEMU_GLIB_COMPAT_H
18d63c9477SAnthony Liguori 
19e71e8cc0SDaniel P. Berrangé /* Ask for warnings for anything that was marked deprecated in
20e71e8cc0SDaniel P. Berrangé  * the defined version, or before. It is a candidate for rewrite.
21e71e8cc0SDaniel P. Berrangé  */
22*0d8caac9SThomas Huth #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_66
23e71e8cc0SDaniel P. Berrangé 
24e71e8cc0SDaniel P. Berrangé /* Ask for warnings if code tries to use function that did not
25e71e8cc0SDaniel P. Berrangé  * exist in the defined version. These risk breaking builds
26e71e8cc0SDaniel P. Berrangé  */
27*0d8caac9SThomas Huth #define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_66
28e71e8cc0SDaniel P. Berrangé 
29e71e8cc0SDaniel P. Berrangé #pragma GCC diagnostic push
30e71e8cc0SDaniel P. Berrangé #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
31e71e8cc0SDaniel P. Berrangé 
32d63c9477SAnthony Liguori #include <glib.h>
336d593ab4SMarc-André Lureau #if defined(G_OS_UNIX)
346d593ab4SMarc-André Lureau #include <glib-unix.h>
356d593ab4SMarc-André Lureau #include <sys/types.h>
366d593ab4SMarc-André Lureau #include <pwd.h>
376d593ab4SMarc-André Lureau #endif
38d63c9477SAnthony Liguori 
39e71e8cc0SDaniel P. Berrangé /*
40e71e8cc0SDaniel P. Berrangé  * Note that because of the GLIB_VERSION_MAX_ALLOWED constant above, allowing
41e71e8cc0SDaniel P. Berrangé  * use of functions from newer GLib via this compat header needs a little
42e71e8cc0SDaniel P. Berrangé  * trickery to prevent warnings being emitted.
43e71e8cc0SDaniel P. Berrangé  *
44e71e8cc0SDaniel P. Berrangé  * Consider a function from newer glib-X.Y that we want to use
45e71e8cc0SDaniel P. Berrangé  *
46e71e8cc0SDaniel P. Berrangé  *    int g_foo(const char *wibble)
47e71e8cc0SDaniel P. Berrangé  *
48e71e8cc0SDaniel P. Berrangé  * We must define a static inline function with the same signature that does
493918fe16SAlex Bennée  * what we need, but with a "_compat" suffix e.g.
50e71e8cc0SDaniel P. Berrangé  *
513918fe16SAlex Bennée  * static inline void g_foo_compat(const char *wibble)
52e71e8cc0SDaniel P. Berrangé  * {
53e71e8cc0SDaniel P. Berrangé  *     #if GLIB_CHECK_VERSION(X, Y, 0)
54e71e8cc0SDaniel P. Berrangé  *        g_foo(wibble)
55e71e8cc0SDaniel P. Berrangé  *     #else
56e71e8cc0SDaniel P. Berrangé  *        g_something_equivalent_in_older_glib(wibble);
57e71e8cc0SDaniel P. Berrangé  *     #endif
58e71e8cc0SDaniel P. Berrangé  * }
59e71e8cc0SDaniel P. Berrangé  *
60e71e8cc0SDaniel P. Berrangé  * The #pragma at the top of this file turns off -Wdeprecated-declarations,
61e71e8cc0SDaniel P. Berrangé  * ensuring this wrapper function impl doesn't trigger the compiler warning
62e71e8cc0SDaniel P. Berrangé  * about using too new glib APIs. Finally we can do
63e71e8cc0SDaniel P. Berrangé  *
643918fe16SAlex Bennée  *   #define g_foo(a) g_foo_compat(a)
65e71e8cc0SDaniel P. Berrangé  *
66e71e8cc0SDaniel P. Berrangé  * So now the code elsewhere in QEMU, which *does* have the
67e71e8cc0SDaniel P. Berrangé  * -Wdeprecated-declarations warning active, can call g_foo(...) as normal,
68e71e8cc0SDaniel P. Berrangé  * without generating warnings.
69e71e8cc0SDaniel P. Berrangé  */
70e71e8cc0SDaniel P. Berrangé 
712c674fadSPhilippe Mathieu-Daudé /*
722c674fadSPhilippe Mathieu-Daudé  * g_memdup2_qemu:
732c674fadSPhilippe Mathieu-Daudé  * @mem: (nullable): the memory to copy.
742c674fadSPhilippe Mathieu-Daudé  * @byte_size: the number of bytes to copy.
752c674fadSPhilippe Mathieu-Daudé  *
762c674fadSPhilippe Mathieu-Daudé  * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it
772c674fadSPhilippe Mathieu-Daudé  * from @mem. If @mem is %NULL it returns %NULL.
782c674fadSPhilippe Mathieu-Daudé  *
792c674fadSPhilippe Mathieu-Daudé  * This replaces g_memdup(), which was prone to integer overflows when
802c674fadSPhilippe Mathieu-Daudé  * converting the argument from a #gsize to a #guint.
812c674fadSPhilippe Mathieu-Daudé  *
822c674fadSPhilippe Mathieu-Daudé  * This static inline version is a backport of the new public API from
832c674fadSPhilippe Mathieu-Daudé  * GLib 2.68, kept internal to GLib for backport to older stable releases.
842c674fadSPhilippe Mathieu-Daudé  * See https://gitlab.gnome.org/GNOME/glib/-/issues/2319.
852c674fadSPhilippe Mathieu-Daudé  *
862c674fadSPhilippe Mathieu-Daudé  * Returns: (nullable): a pointer to the newly-allocated copy of the memory,
872c674fadSPhilippe Mathieu-Daudé  *          or %NULL if @mem is %NULL.
882c674fadSPhilippe Mathieu-Daudé  */
g_memdup2_qemu(gconstpointer mem,gsize byte_size)892c674fadSPhilippe Mathieu-Daudé static inline gpointer g_memdup2_qemu(gconstpointer mem, gsize byte_size)
902c674fadSPhilippe Mathieu-Daudé {
912c674fadSPhilippe Mathieu-Daudé #if GLIB_CHECK_VERSION(2, 68, 0)
922c674fadSPhilippe Mathieu-Daudé     return g_memdup2(mem, byte_size);
932c674fadSPhilippe Mathieu-Daudé #else
942c674fadSPhilippe Mathieu-Daudé     gpointer new_mem;
952c674fadSPhilippe Mathieu-Daudé 
962c674fadSPhilippe Mathieu-Daudé     if (mem && byte_size != 0) {
972c674fadSPhilippe Mathieu-Daudé         new_mem = g_malloc(byte_size);
982c674fadSPhilippe Mathieu-Daudé         memcpy(new_mem, mem, byte_size);
992c674fadSPhilippe Mathieu-Daudé     } else {
1002c674fadSPhilippe Mathieu-Daudé         new_mem = NULL;
1012c674fadSPhilippe Mathieu-Daudé     }
1022c674fadSPhilippe Mathieu-Daudé 
1032c674fadSPhilippe Mathieu-Daudé     return new_mem;
1042c674fadSPhilippe Mathieu-Daudé #endif
1052c674fadSPhilippe Mathieu-Daudé }
1062c674fadSPhilippe Mathieu-Daudé #define g_memdup2(m, s) g_memdup2_qemu(m, s)
1072c674fadSPhilippe Mathieu-Daudé 
1089ba5db49SPaolo Bonzini static inline bool
qemu_g_test_slow(void)1099ba5db49SPaolo Bonzini qemu_g_test_slow(void)
1109ba5db49SPaolo Bonzini {
1119ba5db49SPaolo Bonzini     static int cached = -1;
1129ba5db49SPaolo Bonzini     if (cached == -1) {
1139ba5db49SPaolo Bonzini         cached = g_test_slow() || getenv("G_TEST_SLOW") != NULL;
1149ba5db49SPaolo Bonzini     }
1159ba5db49SPaolo Bonzini     return cached;
1169ba5db49SPaolo Bonzini }
1179ba5db49SPaolo Bonzini 
1189ba5db49SPaolo Bonzini #undef g_test_slow
1199ba5db49SPaolo Bonzini #undef g_test_thorough
1209ba5db49SPaolo Bonzini #undef g_test_quick
1219ba5db49SPaolo Bonzini #define g_test_slow() qemu_g_test_slow()
1229ba5db49SPaolo Bonzini #define g_test_thorough() qemu_g_test_slow()
1239ba5db49SPaolo Bonzini #define g_test_quick() (!qemu_g_test_slow())
1249ba5db49SPaolo Bonzini 
125e71e8cc0SDaniel P. Berrangé #pragma GCC diagnostic pop
126e71e8cc0SDaniel P. Berrangé 
1278905770bSMarc-André Lureau #ifndef G_NORETURN
1288905770bSMarc-André Lureau #define G_NORETURN G_GNUC_NORETURN
1298905770bSMarc-André Lureau #endif
1308905770bSMarc-André Lureau 
131d63c9477SAnthony Liguori #endif
132