xref: /qemu/include/glib-compat.h (revision 080832e4f4801a28bd1170c49e61f6a0f5f05d03)
1  /*
2   * GLIB Compatibility Functions
3   *
4   * Copyright IBM, Corp. 2013
5   *
6   * Authors:
7   *  Anthony Liguori   <aliguori@us.ibm.com>
8   *  Michael Tokarev   <mjt@tls.msk.ru>
9   *  Paolo Bonzini     <pbonzini@redhat.com>
10   *
11   * This work is licensed under the terms of the GNU GPL, version 2 or later.
12   * See the COPYING file in the top-level directory.
13   *
14   */
15  
16  #ifndef QEMU_GLIB_COMPAT_H
17  #define QEMU_GLIB_COMPAT_H
18  
19  /* Ask for warnings for anything that was marked deprecated in
20   * the defined version, or before. It is a candidate for rewrite.
21   */
22  #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56
23  
24  /* Ask for warnings if code tries to use function that did not
25   * exist in the defined version. These risk breaking builds
26   */
27  #define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_56
28  
29  #pragma GCC diagnostic push
30  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
31  
32  #include <glib.h>
33  #if defined(G_OS_UNIX)
34  #include <glib-unix.h>
35  #include <sys/types.h>
36  #include <pwd.h>
37  #endif
38  
39  /*
40   * Note that because of the GLIB_VERSION_MAX_ALLOWED constant above, allowing
41   * use of functions from newer GLib via this compat header needs a little
42   * trickery to prevent warnings being emitted.
43   *
44   * Consider a function from newer glib-X.Y that we want to use
45   *
46   *    int g_foo(const char *wibble)
47   *
48   * We must define a static inline function with the same signature that does
49   * what we need, but with a "_qemu" suffix e.g.
50   *
51   * static inline void g_foo_qemu(const char *wibble)
52   * {
53   *     #if GLIB_CHECK_VERSION(X, Y, 0)
54   *        g_foo(wibble)
55   *     #else
56   *        g_something_equivalent_in_older_glib(wibble);
57   *     #endif
58   * }
59   *
60   * The #pragma at the top of this file turns off -Wdeprecated-declarations,
61   * ensuring this wrapper function impl doesn't trigger the compiler warning
62   * about using too new glib APIs. Finally we can do
63   *
64   *   #define g_foo(a) g_foo_qemu(a)
65   *
66   * So now the code elsewhere in QEMU, which *does* have the
67   * -Wdeprecated-declarations warning active, can call g_foo(...) as normal,
68   * without generating warnings.
69   */
70  
71  #if defined(G_OS_UNIX)
72  /*
73   * Note: The fallback implementation is not MT-safe, and it returns a copy of
74   * the libc passwd (must be g_free() after use) but not the content. Because of
75   * these important differences the caller must be aware of, it's not #define for
76   * GLib API substitution.
77   */
78  static inline struct passwd *
79  g_unix_get_passwd_entry_qemu(const gchar *user_name, GError **error)
80  {
81  #if GLIB_CHECK_VERSION(2, 64, 0)
82      return g_unix_get_passwd_entry(user_name, error);
83  #else
84      struct passwd *p = getpwnam(user_name);
85      if (!p) {
86          g_set_error_literal(error, G_UNIX_ERROR, 0, g_strerror(errno));
87          return NULL;
88      }
89      return (struct passwd *)g_memdup(p, sizeof(*p));
90  #endif
91  }
92  #endif /* G_OS_UNIX */
93  
94  static inline bool
95  qemu_g_test_slow(void)
96  {
97      static int cached = -1;
98      if (cached == -1) {
99          cached = g_test_slow() || getenv("G_TEST_SLOW") != NULL;
100      }
101      return cached;
102  }
103  
104  #undef g_test_slow
105  #undef g_test_thorough
106  #undef g_test_quick
107  #define g_test_slow() qemu_g_test_slow()
108  #define g_test_thorough() qemu_g_test_slow()
109  #define g_test_quick() (!qemu_g_test_slow())
110  
111  #pragma GCC diagnostic pop
112  
113  #endif
114