Imported Upstream version 2.74.3
[platform/upstream/glib.git] / glib / glib-init.c
1 /*
2  * Copyright © 2011 Canonical Limited
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  *
19  * Author: Ryan Lortie <desrt@desrt.ca>
20  */
21
22 #include "config.h"
23
24 #include "glib-init.h"
25 #include "gmacros.h"
26 #include "gtypes.h"
27 #include "gutils.h"     /* for GDebugKey */
28 #include "gconstructor.h"
29 #include "gmem.h"       /* for g_mem_gc_friendly */
30
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <ctype.h>
35
36 /* Deliberately not checking HAVE_STDINT_H here: we officially require a
37  * C99 toolchain, which implies <stdint.h>, int8_t and so on. If your
38  * toolchain does not have this, now would be a good time to upgrade. */
39 #include <stdint.h>
40
41 /* This seems as good a place as any to make static assertions about platform
42  * assumptions we make throughout GLib. */
43
44 /* We do not support 36-bit bytes or other historical curiosities. */
45 G_STATIC_ASSERT (CHAR_BIT == 8);
46
47 /* We assume that data pointers are the same size as function pointers... */
48 G_STATIC_ASSERT (sizeof (gpointer) == sizeof (GFunc));
49 G_STATIC_ASSERT (G_ALIGNOF (gpointer) == G_ALIGNOF (GFunc));
50 /* ... and that all function pointers are the same size. */
51 G_STATIC_ASSERT (sizeof (GFunc) == sizeof (GCompareDataFunc));
52 G_STATIC_ASSERT (G_ALIGNOF (GFunc) == G_ALIGNOF (GCompareDataFunc));
53
54 /* We assume that "small" enums (those where all values fit in INT32_MIN
55  * to INT32_MAX) are exactly int-sized. In particular, we assume that if
56  * an enum has no members that exceed the range of char/short, the
57  * compiler will make it int-sized anyway, so adding a member later that
58  * *does* exceed the range of char/short is not an ABI break. */
59 typedef enum {
60     TEST_CHAR_0 = 0
61 } TestChar;
62 typedef enum {
63     TEST_SHORT_0 = 0,
64     TEST_SHORT_256 = 256
65 } TestShort;
66 typedef enum {
67     TEST_INT32_MIN = G_MININT32,
68     TEST_INT32_MAX = G_MAXINT32
69 } TestInt;
70 G_STATIC_ASSERT (sizeof (TestChar) == sizeof (int));
71 G_STATIC_ASSERT (sizeof (TestShort) == sizeof (int));
72 G_STATIC_ASSERT (sizeof (TestInt) == sizeof (int));
73 G_STATIC_ASSERT (G_ALIGNOF (TestChar) == G_ALIGNOF (int));
74 G_STATIC_ASSERT (G_ALIGNOF (TestShort) == G_ALIGNOF (int));
75 G_STATIC_ASSERT (G_ALIGNOF (TestInt) == G_ALIGNOF (int));
76
77 G_STATIC_ASSERT (sizeof (gchar) == 1);
78 G_STATIC_ASSERT (sizeof (guchar) == 1);
79 G_STATIC_ASSERT (sizeof (gint8) * CHAR_BIT == 8);
80 G_STATIC_ASSERT (sizeof (guint8) * CHAR_BIT == 8);
81 G_STATIC_ASSERT (sizeof (gint16) * CHAR_BIT == 16);
82 G_STATIC_ASSERT (sizeof (guint16) * CHAR_BIT == 16);
83 G_STATIC_ASSERT (sizeof (gint32) * CHAR_BIT == 32);
84 G_STATIC_ASSERT (sizeof (guint32) * CHAR_BIT == 32);
85 G_STATIC_ASSERT (sizeof (gint64) * CHAR_BIT == 64);
86 G_STATIC_ASSERT (sizeof (guint64) * CHAR_BIT == 64);
87
88 G_STATIC_ASSERT (sizeof (void *) == GLIB_SIZEOF_VOID_P);
89 G_STATIC_ASSERT (sizeof (gintptr) == sizeof (void *));
90 G_STATIC_ASSERT (sizeof (guintptr) == sizeof (void *));
91
92 G_STATIC_ASSERT (sizeof (long) == GLIB_SIZEOF_LONG);
93
94 G_STATIC_ASSERT (G_HAVE_GINT64 == 1);
95
96 G_STATIC_ASSERT (sizeof (size_t) == GLIB_SIZEOF_SIZE_T);
97 /* Not a typo: ssize_t is POSIX, not Standard C, but if it exists then
98  * it's the same size as size_t. */
99 G_STATIC_ASSERT (sizeof (size_t) == GLIB_SIZEOF_SSIZE_T);
100 G_STATIC_ASSERT (sizeof (gsize) == GLIB_SIZEOF_SSIZE_T);
101 G_STATIC_ASSERT (sizeof (gsize) == sizeof (size_t));
102 /* Again this is size_t not ssize_t, because ssize_t is POSIX, not C99 */
103 G_STATIC_ASSERT (sizeof (gssize) == sizeof (size_t));
104 G_STATIC_ASSERT (G_ALIGNOF (gsize) == G_ALIGNOF (size_t));
105 G_STATIC_ASSERT (G_ALIGNOF (gssize) == G_ALIGNOF (size_t));
106
107 /* goffset is always 64-bit, even if off_t is only 32-bit
108  * (compiling without large-file-support on 32-bit) */
109 G_STATIC_ASSERT (sizeof (goffset) == sizeof (gint64));
110 G_STATIC_ASSERT (G_ALIGNOF (goffset) == G_ALIGNOF (gint64));
111
112 G_STATIC_ASSERT (sizeof (gfloat) == sizeof (float));
113 G_STATIC_ASSERT (G_ALIGNOF (gfloat) == G_ALIGNOF (float));
114 G_STATIC_ASSERT (sizeof (gdouble) == sizeof (double));
115 G_STATIC_ASSERT (G_ALIGNOF (gdouble) == G_ALIGNOF (double));
116
117 G_STATIC_ASSERT (sizeof (gintptr) == sizeof (intptr_t));
118 G_STATIC_ASSERT (sizeof (guintptr) == sizeof (uintptr_t));
119 G_STATIC_ASSERT (G_ALIGNOF (gintptr) == G_ALIGNOF (intptr_t));
120 G_STATIC_ASSERT (G_ALIGNOF (guintptr) == G_ALIGNOF (uintptr_t));
121
122 G_STATIC_ASSERT (sizeof (gint8) == sizeof (int8_t));
123 G_STATIC_ASSERT (sizeof (guint8) == sizeof (uint8_t));
124 G_STATIC_ASSERT (G_ALIGNOF (gint8) == G_ALIGNOF (int8_t));
125 G_STATIC_ASSERT (G_ALIGNOF (guint8) == G_ALIGNOF (uint8_t));
126
127 G_STATIC_ASSERT (sizeof (gint16) == sizeof (int16_t));
128 G_STATIC_ASSERT (sizeof (guint16) == sizeof (uint16_t));
129 G_STATIC_ASSERT (G_ALIGNOF (gint16) == G_ALIGNOF (int16_t));
130 G_STATIC_ASSERT (G_ALIGNOF (guint16) == G_ALIGNOF (uint16_t));
131
132 G_STATIC_ASSERT (sizeof (gint32) == sizeof (int32_t));
133 G_STATIC_ASSERT (sizeof (guint32) == sizeof (uint32_t));
134 G_STATIC_ASSERT (G_ALIGNOF (gint32) == G_ALIGNOF (int32_t));
135 G_STATIC_ASSERT (G_ALIGNOF (guint32) == G_ALIGNOF (uint32_t));
136
137 G_STATIC_ASSERT (sizeof (gint64) == sizeof (int64_t));
138 G_STATIC_ASSERT (sizeof (guint64) == sizeof (uint64_t));
139 G_STATIC_ASSERT (G_ALIGNOF (gint64) == G_ALIGNOF (int64_t));
140 G_STATIC_ASSERT (G_ALIGNOF (guint64) == G_ALIGNOF (uint64_t));
141
142 /**
143  * g_mem_gc_friendly:
144  *
145  * This variable is %TRUE if the `G_DEBUG` environment variable
146  * includes the key `gc-friendly`.
147  */
148 gboolean g_mem_gc_friendly = FALSE;
149
150 GLogLevelFlags g_log_msg_prefix = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING |
151                                   G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_DEBUG;
152 GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
153
154 static gboolean
155 debug_key_matches (const gchar *key,
156                    const gchar *token,
157                    guint        length)
158 {
159   /* may not call GLib functions: see note in g_parse_debug_string() */
160   for (; length; length--, key++, token++)
161     {
162       char k = (*key   == '_') ? '-' : tolower (*key  );
163       char t = (*token == '_') ? '-' : tolower (*token);
164
165       if (k != t)
166         return FALSE;
167     }
168
169   return *key == '\0';
170 }
171
172 /* The GVariant documentation indirectly says that int is at least 32 bits
173  * (by saying that b, y, n, q, i, u, h are promoted to int). On any
174  * reasonable platform, int is in fact *exactly* 32 bits long, because
175  * otherwise, {signed char, short, int} wouldn't be sufficient to provide
176  * {int8_t, int16_t, int32_t}. */
177 G_STATIC_ASSERT (sizeof (int) == sizeof (gint32));
178
179 /**
180  * g_parse_debug_string:
181  * @string: (nullable): a list of debug options separated by colons, spaces, or
182  * commas, or %NULL.
183  * @keys: (array length=nkeys): pointer to an array of #GDebugKey which associate
184  *     strings with bit flags.
185  * @nkeys: the number of #GDebugKeys in the array.
186  *
187  * Parses a string containing debugging options
188  * into a %guint containing bit flags. This is used
189  * within GDK and GTK+ to parse the debug options passed on the
190  * command line or through environment variables.
191  *
192  * If @string is equal to "all", all flags are set. Any flags
193  * specified along with "all" in @string are inverted; thus,
194  * "all,foo,bar" or "foo,bar,all" sets all flags except those
195  * corresponding to "foo" and "bar".
196  *
197  * If @string is equal to "help", all the available keys in @keys
198  * are printed out to standard error.
199  *
200  * Returns: the combined set of bit flags.
201  */
202 guint
203 g_parse_debug_string  (const gchar     *string,
204                        const GDebugKey *keys,
205                        guint            nkeys)
206 {
207   guint i;
208   guint result = 0;
209
210   if (string == NULL)
211     return 0;
212
213   /* this function is used during the initialisation of gmessages, gmem
214    * and gslice, so it may not do anything that causes memory to be
215    * allocated or risks messages being emitted.
216    *
217    * this means, more or less, that this code may not call anything
218    * inside GLib.
219    */
220
221   if (!strcasecmp (string, "help"))
222     {
223       /* using stdio directly for the reason stated above */
224       fprintf (stderr, "Supported debug values:");
225       for (i = 0; i < nkeys; i++)
226         fprintf (stderr, " %s", keys[i].key);
227       fprintf (stderr, " all help\n");
228     }
229   else
230     {
231       const gchar *p = string;
232       const gchar *q;
233       gboolean invert = FALSE;
234
235       while (*p)
236        {
237          q = strpbrk (p, ":;, \t");
238          if (!q)
239            q = p + strlen (p);
240
241          if (debug_key_matches ("all", p, q - p))
242            {
243              invert = TRUE;
244            }
245          else
246            {
247              for (i = 0; i < nkeys; i++)
248                if (debug_key_matches (keys[i].key, p, q - p))
249                  result |= keys[i].value;
250            }
251
252          p = q;
253          if (*p)
254            p++;
255        }
256
257       if (invert)
258         {
259           guint all_flags = 0;
260
261           for (i = 0; i < nkeys; i++)
262             all_flags |= keys[i].value;
263
264           result = all_flags & (~result);
265         }
266     }
267
268   return result;
269 }
270
271 static guint
272 g_parse_debug_envvar (const gchar     *envvar,
273                       const GDebugKey *keys,
274                       gint             n_keys,
275                       guint            default_value)
276 {
277   const gchar *value;
278
279 #ifdef OS_WIN32
280   /* "fatal-warnings,fatal-criticals,all,help" is pretty short */
281   gchar buffer[100];
282
283   if (GetEnvironmentVariable (envvar, buffer, 100) < 100)
284     value = buffer;
285   else
286     return 0;
287 #else
288   value = getenv (envvar);
289 #endif
290
291   if (value == NULL)
292     return default_value;
293
294   return g_parse_debug_string (value, keys, n_keys);
295 }
296
297 static void
298 g_messages_prefixed_init (void)
299 {
300   const GDebugKey keys[] = {
301     { "error", G_LOG_LEVEL_ERROR },
302     { "critical", G_LOG_LEVEL_CRITICAL },
303     { "warning", G_LOG_LEVEL_WARNING },
304     { "message", G_LOG_LEVEL_MESSAGE },
305     { "info", G_LOG_LEVEL_INFO },
306     { "debug", G_LOG_LEVEL_DEBUG }
307   };
308
309   g_log_msg_prefix = g_parse_debug_envvar ("G_MESSAGES_PREFIXED", keys, G_N_ELEMENTS (keys), g_log_msg_prefix);
310 }
311
312 static void
313 g_debug_init (void)
314 {
315   const GDebugKey keys[] = {
316     { "gc-friendly", 1 },
317     {"fatal-warnings",  G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL },
318     {"fatal-criticals", G_LOG_LEVEL_CRITICAL }
319   };
320   GLogLevelFlags flags;
321
322   flags = g_parse_debug_envvar ("G_DEBUG", keys, G_N_ELEMENTS (keys), 0);
323
324   g_log_always_fatal |= flags & G_LOG_LEVEL_MASK;
325
326   g_mem_gc_friendly = flags & 1;
327 }
328
329 void
330 glib_init (void)
331 {
332   static gboolean glib_inited;
333
334   if (glib_inited)
335     return;
336
337   glib_inited = TRUE;
338
339   g_messages_prefixed_init ();
340   g_debug_init ();
341   g_quark_init ();
342   g_error_init ();
343 }
344
345 #ifdef G_PLATFORM_WIN32
346
347 HMODULE glib_dll = NULL;
348 void glib_win32_init (void);
349
350 void
351 glib_win32_init (void)
352 {
353   /* May be called more than once in static compilation mode */
354   static gboolean win32_already_init = FALSE;
355   if (!win32_already_init)
356     {
357       win32_already_init = TRUE;
358
359       g_crash_handler_win32_init ();
360 #ifdef THREADS_WIN32
361       g_thread_win32_init ();
362 #endif
363
364       g_clock_win32_init ();
365       glib_init ();
366       /* must go after glib_init */
367       g_console_win32_init ();
368     }
369 }
370
371 static void
372 glib_win32_deinit (gboolean detach_thread)
373 {
374 #ifdef THREADS_WIN32
375   if (detach_thread)
376     g_thread_win32_process_detach ();
377 #endif
378   g_crash_handler_win32_deinit ();
379 }
380
381 #ifndef GLIB_STATIC_COMPILATION
382
383 BOOL WINAPI DllMain (HINSTANCE hinstDLL,
384                      DWORD     fdwReason,
385                      LPVOID    lpvReserved);
386
387 BOOL WINAPI
388 DllMain (HINSTANCE hinstDLL,
389          DWORD     fdwReason,
390          LPVOID    lpvReserved)
391 {
392   switch (fdwReason)
393     {
394     case DLL_PROCESS_ATTACH:
395       glib_dll = hinstDLL;
396       glib_win32_init ();
397       break;
398
399     case DLL_THREAD_DETACH:
400 #ifdef THREADS_WIN32
401       g_thread_win32_thread_detach ();
402 #endif
403       break;
404
405     case DLL_PROCESS_DETACH:
406       glib_win32_deinit (lpvReserved == NULL);
407       break;
408
409     default:
410       /* do nothing */
411       ;
412     }
413
414   return TRUE;
415 }
416
417 #elif defined(G_HAS_CONSTRUCTORS) /* && G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION */
418 #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
419 #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(glib_init_ctor)
420 #endif
421 #ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA
422 #pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(glib_init_dtor)
423 #endif
424
425 G_DEFINE_CONSTRUCTOR (glib_init_ctor)
426
427 static void
428 glib_init_ctor (void)
429 {
430   glib_win32_init ();
431 }
432
433 G_DEFINE_DESTRUCTOR (glib_init_dtor)
434
435 static void
436 glib_init_dtor (void)
437 {
438   glib_win32_deinit (FALSE);
439 }
440
441 #else /* G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION && !G_HAS_CONSTRUCTORS */
442 #error Your platform/compiler is missing constructor support
443 #endif /* GLIB_STATIC_COMPILATION */
444
445 #elif defined(G_HAS_CONSTRUCTORS) /* && !G_PLATFORM_WIN32 */
446
447 #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
448 #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(glib_init_ctor)
449 #endif
450 G_DEFINE_CONSTRUCTOR(glib_init_ctor)
451
452 static void
453 glib_init_ctor (void)
454 {
455   glib_init ();
456 }
457
458 #else /* !G_PLATFORM_WIN32 && !G_HAS_CONSTRUCTORS */
459 # error Your platform/compiler is missing constructor support
460 #endif /* G_PLATFORM_WIN32 */