(root)/
glib-2.79.0/
glib/
gmessages.c
       1  /* GLIB - Library of useful routines for C programming
       2   * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
       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,
      12   * but 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  
      20  /*
      21   * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
      22   * file for a list of people on the GLib Team.  See the ChangeLog
      23   * files for a list of changes.  These files are distributed with
      24   * GLib at ftp://ftp.gtk.org/pub/gtk/.
      25   */
      26  
      27  /*
      28   * MT safe
      29   */
      30  
      31  #include "config.h"
      32  
      33  #include <stdlib.h>
      34  #include <stdarg.h>
      35  #include <stdio.h>
      36  #include <string.h>
      37  #include <signal.h>
      38  #include <locale.h>
      39  #include <errno.h>
      40  
      41  #if defined(__linux__) && !defined(__BIONIC__)
      42  #include <sys/types.h>
      43  #include <sys/socket.h>
      44  #include <sys/un.h>
      45  #include <fcntl.h>
      46  #include <sys/uio.h>
      47  #endif
      48  
      49  #include "galloca.h"
      50  #include "gbacktrace.h"
      51  #include "gcharset.h"
      52  #include "gconvert.h"
      53  #include "genviron.h"
      54  #include "glib-init.h"
      55  #include "glib-private.h"
      56  #include "gmain.h"
      57  #include "gmem.h"
      58  #include "gpattern.h"
      59  #include "gprintfint.h"
      60  #include "gstrfuncs.h"
      61  #include "gstring.h"
      62  #include "gtestutils.h"
      63  #include "gthread.h"
      64  #include "gthreadprivate.h"
      65  #include "gutilsprivate.h"
      66  
      67  #if defined(__linux__) && !defined(__BIONIC__)
      68  #include "gjournal-private.h"
      69  #endif
      70  
      71  #ifdef G_OS_UNIX
      72  #include <unistd.h>
      73  #endif
      74  
      75  #ifdef G_OS_WIN32
      76  #include <process.h>		/* For getpid() */
      77  #include <io.h>
      78  #  include <windows.h>
      79  
      80  #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
      81  #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
      82  #endif
      83  
      84  #include "gwin32.h"
      85  #endif
      86  
      87  /**
      88   * G_LOG_DOMAIN:
      89   *
      90   * Defines the log domain. See [Log Domains](#log-domains).
      91   *
      92   * Libraries should define this so that any messages
      93   * which they log can be differentiated from messages from other
      94   * libraries and application code. But be careful not to define
      95   * it in any public header files.
      96   *
      97   * Log domains must be unique, and it is recommended that they are the
      98   * application or library name, optionally followed by a hyphen and a sub-domain
      99   * name. For example, `bloatpad` or `bloatpad-io`.
     100   *
     101   * If undefined, it defaults to the default %NULL (or `""`) log domain; this is
     102   * not advisable, as it cannot be filtered against using the `G_MESSAGES_DEBUG`
     103   * environment variable.
     104   *
     105   * For example, GTK uses this in its `Makefile.am`:
     106   * |[
     107   * AM_CPPFLAGS = -DG_LOG_DOMAIN=\"Gtk\"
     108   * ]|
     109   *
     110   * Applications can choose to leave it as the default %NULL (or `""`)
     111   * domain. However, defining the domain offers the same advantages as
     112   * above.
     113   *
     114  
     115   */
     116  
     117  /**
     118   * G_LOG_FATAL_MASK:
     119   *
     120   * GLib log levels that are considered fatal by default.
     121   *
     122   * This is not used if structured logging is enabled; see
     123   * [Using Structured Logging][using-structured-logging].
     124   */
     125  
     126  /**
     127   * GLogFunc:
     128   * @log_domain: the log domain of the message
     129   * @log_level: the log level of the message (including the
     130   *     fatal and recursion flags)
     131   * @message: the message to process
     132   * @user_data: user data, set in g_log_set_handler()
     133   *
     134   * Specifies the prototype of log handler functions.
     135   *
     136   * The default log handler, g_log_default_handler(), automatically appends a
     137   * new-line character to @message when printing it. It is advised that any
     138   * custom log handler functions behave similarly, so that logging calls in user
     139   * code do not need modifying to add a new-line character to the message if the
     140   * log handler is changed.
     141   *
     142   * This is not used if structured logging is enabled; see
     143   * [Using Structured Logging][using-structured-logging].
     144   */
     145  
     146  /**
     147   * GLogLevelFlags:
     148   * @G_LOG_FLAG_RECURSION: internal flag
     149   * @G_LOG_FLAG_FATAL: internal flag
     150   * @G_LOG_LEVEL_ERROR: log level for errors, see g_error().
     151   *     This level is also used for messages produced by g_assert().
     152   * @G_LOG_LEVEL_CRITICAL: log level for critical warning messages, see
     153   *     g_critical().
     154   *     This level is also used for messages produced by g_return_if_fail()
     155   *     and g_return_val_if_fail().
     156   * @G_LOG_LEVEL_WARNING: log level for warnings, see g_warning()
     157   * @G_LOG_LEVEL_MESSAGE: log level for messages, see g_message()
     158   * @G_LOG_LEVEL_INFO: log level for informational messages, see g_info()
     159   * @G_LOG_LEVEL_DEBUG: log level for debug messages, see g_debug()
     160   * @G_LOG_LEVEL_MASK: a mask including all log levels
     161   *
     162   * Flags specifying the level of log messages.
     163   *
     164   * It is possible to change how GLib treats messages of the various
     165   * levels using g_log_set_handler() and g_log_set_fatal_mask().
     166   */
     167  
     168  /**
     169   * G_LOG_LEVEL_USER_SHIFT:
     170   *
     171   * Log levels below 1<<G_LOG_LEVEL_USER_SHIFT are used by GLib.
     172   * Higher bits can be used for user-defined log levels.
     173   */
     174  
     175  /**
     176   * g_message:
     177   * @...: format string, followed by parameters to insert
     178   *     into the format string (as with printf())
     179   *
     180   * A convenience function/macro to log a normal message.
     181   *
     182   * If g_log_default_handler() is used as the log handler function, a new-line
     183   * character will automatically be appended to @..., and need not be entered
     184   * manually.
     185   *
     186   * If structured logging is enabled, this will use g_log_structured();
     187   * otherwise it will use g_log(). See
     188   * [Using Structured Logging][using-structured-logging].
     189   */
     190  
     191  /**
     192   * g_warning:
     193   * @...: format string, followed by parameters to insert
     194   *     into the format string (as with printf())
     195   *
     196   * A convenience function/macro to log a warning message. The message should
     197   * typically *not* be translated to the user's language.
     198   *
     199   * This is not intended for end user error reporting. Use of #GError is
     200   * preferred for that instead, as it allows calling functions to perform actions
     201   * conditional on the type of error.
     202   *
     203   * Warning messages are intended to be used in the event of unexpected
     204   * external conditions (system misconfiguration, missing files,
     205   * other trusted programs violating protocol, invalid contents in
     206   * trusted files, etc.)
     207   *
     208   * If attempting to deal with programmer errors (for example, incorrect function
     209   * parameters) then you should use %G_LOG_LEVEL_CRITICAL instead.
     210   *
     211   * g_warn_if_reached() and g_warn_if_fail() log at %G_LOG_LEVEL_WARNING.
     212   *
     213   * You can make warnings fatal at runtime by setting the `G_DEBUG`
     214   * environment variable (see
     215   * [Running GLib Applications](glib-running.html)):
     216   *
     217   * |[
     218   *   G_DEBUG=fatal-warnings gdb ./my-program
     219   * ]|
     220   *
     221   * Any unrelated failures can be skipped over in
     222   * [gdb](https://www.gnu.org/software/gdb/) using the `continue` command.
     223   *
     224   * If g_log_default_handler() is used as the log handler function,
     225   * a newline character will automatically be appended to @..., and
     226   * need not be entered manually.
     227   *
     228   * If structured logging is enabled, this will use g_log_structured();
     229   * otherwise it will use g_log(). See
     230   * [Using Structured Logging][using-structured-logging].
     231   */
     232  
     233  /**
     234   * g_critical:
     235   * @...: format string, followed by parameters to insert
     236   *     into the format string (as with printf())
     237   *
     238   * Logs a "critical warning" (%G_LOG_LEVEL_CRITICAL).
     239   *
     240   * Critical warnings are intended to be used in the event of an error
     241   * that originated in the current process (a programmer error).
     242   * Logging of a critical error is by definition an indication of a bug
     243   * somewhere in the current program (or its libraries).
     244   *
     245   * g_return_if_fail(), g_return_val_if_fail(), g_return_if_reached() and
     246   * g_return_val_if_reached() log at %G_LOG_LEVEL_CRITICAL.
     247   *
     248   * You can make critical warnings fatal at runtime by
     249   * setting the `G_DEBUG` environment variable (see
     250   * [Running GLib Applications](glib-running.html)):
     251   *
     252   * |[
     253   *   G_DEBUG=fatal-warnings gdb ./my-program
     254   * ]|
     255   *
     256   * You can also use g_log_set_always_fatal().
     257   *
     258   * Any unrelated failures can be skipped over in
     259   * [gdb](https://www.gnu.org/software/gdb/) using the `continue` command.
     260   *
     261   * The message should typically *not* be translated to the
     262   * user's language.
     263   *
     264   * If g_log_default_handler() is used as the log handler function, a new-line
     265   * character will automatically be appended to @..., and need not be entered
     266   * manually.
     267   *
     268   * If structured logging is enabled, this will use g_log_structured();
     269   * otherwise it will use g_log(). See
     270   * [Using Structured Logging][using-structured-logging].
     271   */
     272  
     273  /**
     274   * g_error:
     275   * @...: format string, followed by parameters to insert
     276   *     into the format string (as with printf())
     277   *
     278   * A convenience function/macro to log an error message. The message should
     279   * typically *not* be translated to the user's language.
     280   *
     281   * This is not intended for end user error reporting. Use of #GError is
     282   * preferred for that instead, as it allows calling functions to perform actions
     283   * conditional on the type of error.
     284   *
     285   * Error messages are always fatal, resulting in a call to G_BREAKPOINT()
     286   * to terminate the application. This function will
     287   * result in a core dump; don't use it for errors you expect.
     288   * Using this function indicates a bug in your program, i.e.
     289   * an assertion failure.
     290   *
     291   * If g_log_default_handler() is used as the log handler function, a new-line
     292   * character will automatically be appended to @..., and need not be entered
     293   * manually.
     294   *
     295   * If structured logging is enabled, this will use g_log_structured();
     296   * otherwise it will use g_log(). See
     297   * [Using Structured Logging][using-structured-logging].
     298   */
     299  
     300  /**
     301   * g_info:
     302   * @...: format string, followed by parameters to insert
     303   *     into the format string (as with printf())
     304   *
     305   * A convenience function/macro to log an informational message. Seldom used.
     306   *
     307   * If g_log_default_handler() is used as the log handler function, a new-line
     308   * character will automatically be appended to @..., and need not be entered
     309   * manually.
     310   *
     311   * Such messages are suppressed by the g_log_default_handler() and
     312   * g_log_writer_default() unless the `G_MESSAGES_DEBUG` environment variable is
     313   * set appropriately. If you need to set the allowed domains at runtime, use
     314   * g_log_writer_default_set_debug_domains().
     315   *
     316   * If structured logging is enabled, this will use g_log_structured();
     317   * otherwise it will use g_log(). See
     318   * [Using Structured Logging][using-structured-logging].
     319   *
     320   * Since: 2.40
     321   */
     322  
     323  /**
     324   * g_debug:
     325   * @...: format string, followed by parameters to insert
     326   *     into the format string (as with printf())
     327   *
     328   * A convenience function/macro to log a debug message. The message should
     329   * typically *not* be translated to the user's language.
     330   *
     331   * If g_log_default_handler() is used as the log handler function, a new-line
     332   * character will automatically be appended to @..., and need not be entered
     333   * manually.
     334   *
     335   * Such messages are suppressed by the g_log_default_handler() and
     336   * g_log_writer_default() unless the `G_MESSAGES_DEBUG` environment variable is
     337   * set appropriately. If you need to set the allowed domains at runtime, use
     338   * g_log_writer_default_set_debug_domains().
     339   *
     340   * If structured logging is enabled, this will use g_log_structured();
     341   * otherwise it will use g_log(). See
     342   * [Using Structured Logging][using-structured-logging].
     343   *
     344   * Since: 2.6
     345   */
     346  
     347  /* --- structures --- */
     348  typedef struct _GLogDomain	GLogDomain;
     349  typedef struct _GLogHandler	GLogHandler;
     350  struct _GLogDomain
     351  {
     352    gchar		*log_domain;
     353    GLogLevelFlags fatal_mask;
     354    GLogHandler	*handlers;
     355    GLogDomain	*next;
     356  };
     357  struct _GLogHandler
     358  {
     359    guint		 id;
     360    GLogLevelFlags log_level;
     361    GLogFunc	 log_func;
     362    gpointer	 data;
     363    GDestroyNotify destroy;
     364    GLogHandler	*next;
     365  };
     366  
     367  static void g_default_print_func (const gchar *string);
     368  static void g_default_printerr_func (const gchar *string);
     369  
     370  /* --- variables --- */
     371  static GMutex         g_messages_lock;
     372  static GLogDomain    *g_log_domains = NULL;
     373  static GPrintFunc     glib_print_func = g_default_print_func;
     374  static GPrintFunc     glib_printerr_func = g_default_printerr_func;
     375  static GPrivate       g_log_depth;
     376  static GPrivate       g_log_structured_depth;
     377  static GLogFunc       default_log_func = g_log_default_handler;
     378  static gpointer       default_log_data = NULL;
     379  static GTestLogFatalFunc fatal_log_func = NULL;
     380  static gpointer          fatal_log_data;
     381  static GLogWriterFunc log_writer_func = g_log_writer_default;
     382  static gpointer       log_writer_user_data = NULL;
     383  static GDestroyNotify log_writer_user_data_free = NULL;
     384  static gboolean       g_log_debug_enabled = FALSE;  /* (atomic) */
     385  
     386  /* --- functions --- */
     387  
     388  static void _g_log_abort (gboolean breakpoint);
     389  static inline const char * format_string (const char *format,
     390                                            va_list     args,
     391                                            char      **out_allocated_string)
     392                                            G_GNUC_PRINTF (1, 0);
     393  static inline FILE * log_level_to_file (GLogLevelFlags log_level);
     394  
     395  static void
     396  _g_log_abort (gboolean breakpoint)
     397  {
     398    gboolean debugger_present;
     399  
     400    if (g_test_subprocess ())
     401      {
     402        /* If this is a test case subprocess then it probably caused
     403         * this error message on purpose, so just exit() rather than
     404         * abort()ing, to avoid triggering any system crash-reporting
     405         * daemon.
     406         */
     407        _exit (1);
     408      }
     409  
     410  #ifdef G_OS_WIN32
     411    debugger_present = IsDebuggerPresent ();
     412  #else
     413    /* Assume GDB is attached. */
     414    debugger_present = TRUE;
     415  #endif /* !G_OS_WIN32 */
     416  
     417    if (debugger_present && breakpoint)
     418      G_BREAKPOINT ();
     419    else
     420      g_abort ();
     421  }
     422  
     423  #ifdef G_OS_WIN32
     424  static gboolean win32_keep_fatal_message = FALSE;
     425  
     426  /* This default message will usually be overwritten. */
     427  /* Yes, a fixed size buffer is bad. So sue me. But g_error() is never
     428   * called with huge strings, is it?
     429   */
     430  static gchar  fatal_msg_buf[1000] = "Unspecified fatal error encountered, aborting.";
     431  
     432  #endif
     433  
     434  static void
     435  write_string (FILE        *stream,
     436  	      const gchar *string)
     437  {
     438    if (fputs (string, stream) == EOF)
     439      {
     440        /* Something failed, but it's not an error we can handle at glib level
     441         * so let's just continue without the compiler blaming us
     442         */
     443      }
     444  }
     445  
     446  static void
     447  write_string_sized (FILE        *stream,
     448                      const gchar *string,
     449                      gssize       length)
     450  {
     451    /* Is it nul-terminated? */
     452    if (length < 0)
     453      write_string (stream, string);
     454    else if (fwrite (string, 1, length, stream) < (size_t) length)
     455      {
     456        /* Something failed, but it's not an error we can handle at glib level
     457         * so let's just continue without the compiler blaming us
     458         */
     459      }
     460  }
     461  
     462  static GLogDomain*
     463  g_log_find_domain_L (const gchar *log_domain)
     464  {
     465    GLogDomain *domain;
     466    
     467    domain = g_log_domains;
     468    while (domain)
     469      {
     470        if (strcmp (domain->log_domain, log_domain) == 0)
     471  	return domain;
     472        domain = domain->next;
     473      }
     474    return NULL;
     475  }
     476  
     477  static GLogDomain*
     478  g_log_domain_new_L (const gchar *log_domain)
     479  {
     480    GLogDomain *domain;
     481  
     482    domain = g_new (GLogDomain, 1);
     483    domain->log_domain = g_strdup (log_domain);
     484    domain->fatal_mask = G_LOG_FATAL_MASK;
     485    domain->handlers = NULL;
     486    
     487    domain->next = g_log_domains;
     488    g_log_domains = domain;
     489    
     490    return domain;
     491  }
     492  
     493  static void
     494  g_log_domain_check_free_L (GLogDomain *domain)
     495  {
     496    if (domain->fatal_mask == G_LOG_FATAL_MASK &&
     497        domain->handlers == NULL)
     498      {
     499        GLogDomain *last, *work;
     500        
     501        last = NULL;  
     502  
     503        work = g_log_domains;
     504        while (work)
     505  	{
     506  	  if (work == domain)
     507  	    {
     508  	      if (last)
     509  		last->next = domain->next;
     510  	      else
     511  		g_log_domains = domain->next;
     512  	      g_free (domain->log_domain);
     513  	      g_free (domain);
     514  	      break;
     515  	    }
     516  	  last = work;
     517  	  work = last->next;
     518  	}  
     519      }
     520  }
     521  
     522  static GLogFunc
     523  g_log_domain_get_handler_L (GLogDomain	*domain,
     524  			    GLogLevelFlags log_level,
     525  			    gpointer	*data)
     526  {
     527    if (domain && log_level)
     528      {
     529        GLogHandler *handler;
     530        
     531        handler = domain->handlers;
     532        while (handler)
     533  	{
     534  	  if ((handler->log_level & log_level) == log_level)
     535  	    {
     536  	      *data = handler->data;
     537  	      return handler->log_func;
     538  	    }
     539  	  handler = handler->next;
     540  	}
     541      }
     542  
     543    *data = default_log_data;
     544    return default_log_func;
     545  }
     546  
     547  /**
     548   * g_log_set_always_fatal:
     549   * @fatal_mask: the mask containing bits set for each level
     550   *     of error which is to be fatal
     551   *
     552   * Sets the message levels which are always fatal, in any log domain.
     553   * When a message with any of these levels is logged the program terminates.
     554   * You can only set the levels defined by GLib to be fatal.
     555   * %G_LOG_LEVEL_ERROR is always fatal.
     556   *
     557   * You can also make some message levels fatal at runtime by setting
     558   * the `G_DEBUG` environment variable (see
     559   * [Running GLib Applications](glib-running.html)).
     560   *
     561   * Libraries should not call this function, as it affects all messages logged
     562   * by a process, including those from other libraries.
     563   *
     564   * Structured log messages (using g_log_structured() and
     565   * g_log_structured_array()) are fatal only if the default log writer is used;
     566   * otherwise it is up to the writer function to determine which log messages
     567   * are fatal. See [Using Structured Logging][using-structured-logging].
     568   *
     569   * Returns: the old fatal mask
     570   */
     571  GLogLevelFlags
     572  g_log_set_always_fatal (GLogLevelFlags fatal_mask)
     573  {
     574    GLogLevelFlags old_mask;
     575  
     576    /* restrict the global mask to levels that are known to glib
     577     * since this setting applies to all domains
     578     */
     579    fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1;
     580    /* force errors to be fatal */
     581    fatal_mask |= G_LOG_LEVEL_ERROR;
     582    /* remove bogus flag */
     583    fatal_mask &= ~G_LOG_FLAG_FATAL;
     584  
     585    g_mutex_lock (&g_messages_lock);
     586    old_mask = g_log_always_fatal;
     587    g_log_always_fatal = fatal_mask;
     588    g_mutex_unlock (&g_messages_lock);
     589  
     590    return old_mask;
     591  }
     592  
     593  /**
     594   * g_log_set_fatal_mask:
     595   * @log_domain: the log domain
     596   * @fatal_mask: the new fatal mask
     597   *
     598   * Sets the log levels which are fatal in the given domain.
     599   * %G_LOG_LEVEL_ERROR is always fatal.
     600   *
     601   * This has no effect on structured log messages (using g_log_structured() or
     602   * g_log_structured_array()). To change the fatal behaviour for specific log
     603   * messages, programs must install a custom log writer function using
     604   * g_log_set_writer_func(). See
     605   * [Using Structured Logging][using-structured-logging].
     606   *
     607   * This function is mostly intended to be used with
     608   * %G_LOG_LEVEL_CRITICAL.  You should typically not set
     609   * %G_LOG_LEVEL_WARNING, %G_LOG_LEVEL_MESSAGE, %G_LOG_LEVEL_INFO or
     610   * %G_LOG_LEVEL_DEBUG as fatal except inside of test programs.
     611   *
     612   * Returns: the old fatal mask for the log domain
     613   */
     614  GLogLevelFlags
     615  g_log_set_fatal_mask (const gchar   *log_domain,
     616  		      GLogLevelFlags fatal_mask)
     617  {
     618    GLogLevelFlags old_flags;
     619    GLogDomain *domain;
     620    
     621    if (!log_domain)
     622      log_domain = "";
     623  
     624    /* force errors to be fatal */
     625    fatal_mask |= G_LOG_LEVEL_ERROR;
     626    /* remove bogus flag */
     627    fatal_mask &= ~G_LOG_FLAG_FATAL;
     628    
     629    g_mutex_lock (&g_messages_lock);
     630  
     631    domain = g_log_find_domain_L (log_domain);
     632    if (!domain)
     633      domain = g_log_domain_new_L (log_domain);
     634    old_flags = domain->fatal_mask;
     635    
     636    domain->fatal_mask = fatal_mask;
     637    g_log_domain_check_free_L (domain);
     638  
     639    g_mutex_unlock (&g_messages_lock);
     640  
     641    return old_flags;
     642  }
     643  
     644  /**
     645   * g_log_set_handler:
     646   * @log_domain: (nullable): the log domain, or %NULL for the default ""
     647   *    application domain
     648   * @log_levels: the log levels to apply the log handler for.
     649   *    To handle fatal and recursive messages as well, combine
     650   *    the log levels with the %G_LOG_FLAG_FATAL and
     651   *    %G_LOG_FLAG_RECURSION bit flags.
     652   * @log_func: the log handler function
     653   * @user_data: data passed to the log handler
     654   *
     655   * Sets the log handler for a domain and a set of log levels.
     656   *
     657   * To handle fatal and recursive messages the @log_levels parameter
     658   * must be combined with the %G_LOG_FLAG_FATAL and %G_LOG_FLAG_RECURSION
     659   * bit flags.
     660   *
     661   * Note that since the %G_LOG_LEVEL_ERROR log level is always fatal, if
     662   * you want to set a handler for this log level you must combine it with
     663   * %G_LOG_FLAG_FATAL.
     664   *
     665   * This has no effect if structured logging is enabled; see
     666   * [Using Structured Logging][using-structured-logging].
     667   *
     668   * Here is an example for adding a log handler for all warning messages
     669   * in the default domain:
     670   *
     671   * |[<!-- language="C" --> 
     672   * g_log_set_handler (NULL, G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
     673   *                    | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
     674   * ]|
     675   *
     676   * This example adds a log handler for all critical messages from GTK:
     677   *
     678   * |[<!-- language="C" --> 
     679   * g_log_set_handler ("Gtk", G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL
     680   *                    | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
     681   * ]|
     682   *
     683   * This example adds a log handler for all messages from GLib:
     684   *
     685   * |[<!-- language="C" --> 
     686   * g_log_set_handler ("GLib", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
     687   *                    | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
     688   * ]|
     689   *
     690   * Returns: the id of the new handler
     691   */
     692  guint
     693  g_log_set_handler (const gchar	 *log_domain,
     694                     GLogLevelFlags log_levels,
     695                     GLogFunc       log_func,
     696                     gpointer       user_data)
     697  {
     698    return g_log_set_handler_full (log_domain, log_levels, log_func, user_data, NULL);
     699  }
     700  
     701  /**
     702   * g_log_set_handler_full: (rename-to g_log_set_handler)
     703   * @log_domain: (nullable): the log domain, or %NULL for the default ""
     704   *   application domain
     705   * @log_levels: the log levels to apply the log handler for.
     706   *   To handle fatal and recursive messages as well, combine
     707   *   the log levels with the %G_LOG_FLAG_FATAL and
     708   *   %G_LOG_FLAG_RECURSION bit flags.
     709   * @log_func: the log handler function
     710   * @user_data: data passed to the log handler
     711   * @destroy: destroy notify for @user_data, or %NULL
     712   *
     713   * Like g_log_set_handler(), but takes a destroy notify for the @user_data.
     714   *
     715   * This has no effect if structured logging is enabled; see
     716   * [Using Structured Logging][using-structured-logging].
     717   *
     718   * Returns: the id of the new handler
     719   *
     720   * Since: 2.46
     721   */
     722  guint
     723  g_log_set_handler_full (const gchar    *log_domain,
     724                          GLogLevelFlags  log_levels,
     725                          GLogFunc        log_func,
     726                          gpointer        user_data,
     727                          GDestroyNotify  destroy)
     728  {
     729    static guint handler_id = 0;
     730    GLogDomain *domain;
     731    GLogHandler *handler;
     732    
     733    g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);
     734    g_return_val_if_fail (log_func != NULL, 0);
     735    
     736    if (!log_domain)
     737      log_domain = "";
     738  
     739    handler = g_new (GLogHandler, 1);
     740  
     741    g_mutex_lock (&g_messages_lock);
     742  
     743    domain = g_log_find_domain_L (log_domain);
     744    if (!domain)
     745      domain = g_log_domain_new_L (log_domain);
     746    
     747    handler->id = ++handler_id;
     748    handler->log_level = log_levels;
     749    handler->log_func = log_func;
     750    handler->data = user_data;
     751    handler->destroy = destroy;
     752    handler->next = domain->handlers;
     753    domain->handlers = handler;
     754  
     755    g_mutex_unlock (&g_messages_lock);
     756    
     757    return handler_id;
     758  }
     759  
     760  /**
     761   * g_log_set_default_handler:
     762   * @log_func: the log handler function
     763   * @user_data: data passed to the log handler
     764   *
     765   * Installs a default log handler which is used if no
     766   * log handler has been set for the particular log domain
     767   * and log level combination. By default, GLib uses
     768   * g_log_default_handler() as default log handler.
     769   *
     770   * This has no effect if structured logging is enabled; see
     771   * [Using Structured Logging][using-structured-logging].
     772   *
     773   * Returns: the previous default log handler
     774   *
     775   * Since: 2.6
     776   */
     777  GLogFunc
     778  g_log_set_default_handler (GLogFunc log_func,
     779  			   gpointer user_data)
     780  {
     781    GLogFunc old_log_func;
     782    
     783    g_mutex_lock (&g_messages_lock);
     784    old_log_func = default_log_func;
     785    default_log_func = log_func;
     786    default_log_data = user_data;
     787    g_mutex_unlock (&g_messages_lock);
     788    
     789    return old_log_func;
     790  }
     791  
     792  /**
     793   * g_test_log_set_fatal_handler:
     794   * @log_func: the log handler function.
     795   * @user_data: data passed to the log handler.
     796   *
     797   * Installs a non-error fatal log handler which can be
     798   * used to decide whether log messages which are counted
     799   * as fatal abort the program.
     800   *
     801   * The use case here is that you are running a test case
     802   * that depends on particular libraries or circumstances
     803   * and cannot prevent certain known critical or warning
     804   * messages. So you install a handler that compares the
     805   * domain and message to precisely not abort in such a case.
     806   *
     807   * Note that the handler is reset at the beginning of
     808   * any test case, so you have to set it inside each test
     809   * function which needs the special behavior.
     810   *
     811   * This handler has no effect on g_error messages.
     812   *
     813   * This handler also has no effect on structured log messages (using
     814   * g_log_structured() or g_log_structured_array()). To change the fatal
     815   * behaviour for specific log messages, programs must install a custom log
     816   * writer function using g_log_set_writer_func().See
     817   * [Using Structured Logging][using-structured-logging].
     818   *
     819   * Since: 2.22
     820   **/
     821  void
     822  g_test_log_set_fatal_handler (GTestLogFatalFunc log_func,
     823                                gpointer          user_data)
     824  {
     825    g_mutex_lock (&g_messages_lock);
     826    fatal_log_func = log_func;
     827    fatal_log_data = user_data;
     828    g_mutex_unlock (&g_messages_lock);
     829  }
     830  
     831  /**
     832   * g_log_remove_handler:
     833   * @log_domain: the log domain
     834   * @handler_id: the id of the handler, which was returned
     835   *     in g_log_set_handler()
     836   *
     837   * Removes the log handler.
     838   *
     839   * This has no effect if structured logging is enabled; see
     840   * [Using Structured Logging][using-structured-logging].
     841   */
     842  void
     843  g_log_remove_handler (const gchar *log_domain,
     844  		      guint	   handler_id)
     845  {
     846    GLogDomain *domain;
     847    
     848    g_return_if_fail (handler_id > 0);
     849    
     850    if (!log_domain)
     851      log_domain = "";
     852    
     853    g_mutex_lock (&g_messages_lock);
     854    domain = g_log_find_domain_L (log_domain);
     855    if (domain)
     856      {
     857        GLogHandler *work, *last;
     858        
     859        last = NULL;
     860        work = domain->handlers;
     861        while (work)
     862  	{
     863  	  if (work->id == handler_id)
     864  	    {
     865  	      if (last)
     866  		last->next = work->next;
     867  	      else
     868  		domain->handlers = work->next;
     869  	      g_log_domain_check_free_L (domain); 
     870  	      g_mutex_unlock (&g_messages_lock);
     871                if (work->destroy)
     872                  work->destroy (work->data);
     873  	      g_free (work);
     874  	      return;
     875  	    }
     876  	  last = work;
     877  	  work = last->next;
     878  	}
     879      } 
     880    g_mutex_unlock (&g_messages_lock);
     881    g_warning ("%s: could not find handler with id '%d' for domain \"%s\"",
     882  	     G_STRLOC, handler_id, log_domain);
     883  }
     884  
     885  #define CHAR_IS_SAFE(wc) (!((wc < 0x20 && wc != '\t' && wc != '\n' && wc != '\r') || \
     886  			    (wc == 0x7f) || \
     887  			    (wc >= 0x80 && wc < 0xa0)))
     888       
     889  static gchar*
     890  strdup_convert (const gchar *string,
     891  		const gchar *charset)
     892  {
     893    if (!g_utf8_validate (string, -1, NULL))
     894      {
     895        GString *gstring = g_string_new ("[Invalid UTF-8] ");
     896        guchar *p;
     897  
     898        for (p = (guchar *)string; *p; p++)
     899  	{
     900  	  if (CHAR_IS_SAFE(*p) &&
     901  	      !(*p == '\r' && *(p + 1) != '\n') &&
     902  	      *p < 0x80)
     903  	    g_string_append_c (gstring, *p);
     904  	  else
     905  	    g_string_append_printf (gstring, "\\x%02x", (guint)(guchar)*p);
     906  	}
     907        
     908        return g_string_free (gstring, FALSE);
     909      }
     910    else
     911      {
     912        GError *err = NULL;
     913        
     914        gchar *result = g_convert_with_fallback (string, -1, charset, "UTF-8", "?", NULL, NULL, &err);
     915        if (result)
     916  	return result;
     917        else
     918  	{
     919  	  /* Not thread-safe, but doesn't matter if we print the warning twice
     920  	   */
     921  	  static gboolean warned = FALSE; 
     922  	  if (!warned)
     923  	    {
     924  	      warned = TRUE;
     925  	      _g_fprintf (stderr, "GLib: Cannot convert message: %s\n", err->message);
     926  	    }
     927  	  g_error_free (err);
     928  	  
     929  	  return g_strdup (string);
     930  	}
     931      }
     932  }
     933  
     934  /* For a radix of 8 we need at most 3 output bytes for 1 input
     935   * byte. Additionally we might need up to 2 output bytes for the
     936   * readix prefix and 1 byte for the trailing NULL.
     937   */
     938  #define FORMAT_UNSIGNED_BUFSIZE ((GLIB_SIZEOF_LONG * 3) + 3)
     939  
     940  static void
     941  format_unsigned (gchar  *buf,
     942  		 gulong  num,
     943  		 guint   radix)
     944  {
     945    gulong tmp;
     946    gchar c;
     947    gint i, n;
     948  
     949    /* we may not call _any_ GLib functions here (or macros like g_return_if_fail()) */
     950  
     951    if (radix != 8 && radix != 10 && radix != 16)
     952      {
     953        *buf = '\000';
     954        return;
     955      }
     956    
     957    if (!num)
     958      {
     959        *buf++ = '0';
     960        *buf = '\000';
     961        return;
     962      } 
     963    
     964    if (radix == 16)
     965      {
     966        *buf++ = '0';
     967        *buf++ = 'x';
     968      }
     969    else if (radix == 8)
     970      {
     971        *buf++ = '0';
     972      }
     973  	
     974    n = 0;
     975    tmp = num;
     976    while (tmp)
     977      {
     978        tmp /= radix;
     979        n++;
     980      }
     981  
     982    i = n;
     983  
     984    /* Again we can't use g_assert; actually this check should _never_ fail. */
     985    if (n > FORMAT_UNSIGNED_BUFSIZE - 3)
     986      {
     987        *buf = '\000';
     988        return;
     989      }
     990  
     991    while (num)
     992      {
     993        i--;
     994        c = (num % radix);
     995        if (c < 10)
     996  	buf[i] = c + '0';
     997        else
     998  	buf[i] = c + 'a' - 10;
     999        num /= radix;
    1000      }
    1001    
    1002    buf[n] = '\000';
    1003  }
    1004  
    1005  /* string size big enough to hold level prefix */
    1006  #define	STRING_BUFFER_SIZE	(FORMAT_UNSIGNED_BUFSIZE + 32)
    1007  
    1008  #define	ALERT_LEVELS		(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING)
    1009  
    1010  /* these are emitted by the default log handler */
    1011  #define DEFAULT_LEVELS (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE)
    1012  /* these are filtered by G_MESSAGES_DEBUG by the default log handler */
    1013  #define INFO_LEVELS (G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG)
    1014  
    1015  static const gchar *log_level_to_color (GLogLevelFlags log_level,
    1016                                          gboolean       use_color);
    1017  static const gchar *color_reset        (gboolean       use_color);
    1018  
    1019  static gboolean gmessages_use_stderr = FALSE;
    1020  
    1021  /**
    1022   * g_log_writer_default_set_use_stderr:
    1023   * @use_stderr: If %TRUE, use `stderr` for log messages that would
    1024   *  normally have appeared on `stdout`
    1025   *
    1026   * Configure whether the built-in log functions
    1027   * (g_log_default_handler() for the old-style API, and both
    1028   * g_log_writer_default() and g_log_writer_standard_streams() for the
    1029   * structured API) will output all log messages to `stderr`.
    1030   *
    1031   * By default, log messages of levels %G_LOG_LEVEL_INFO and
    1032   * %G_LOG_LEVEL_DEBUG are sent to `stdout`, and other log messages are
    1033   * sent to `stderr`. This is problematic for applications that intend
    1034   * to reserve `stdout` for structured output such as JSON or XML.
    1035   *
    1036   * This function sets global state. It is not thread-aware, and should be
    1037   * called at the very start of a program, before creating any other threads
    1038   * or creating objects that could create worker threads of their own.
    1039   *
    1040   * Since: 2.68
    1041   */
    1042  void
    1043  g_log_writer_default_set_use_stderr (gboolean use_stderr)
    1044  {
    1045    g_return_if_fail (g_thread_n_created () == 0);
    1046    gmessages_use_stderr = use_stderr;
    1047  }
    1048  
    1049  static FILE *
    1050  mklevel_prefix (gchar          level_prefix[STRING_BUFFER_SIZE],
    1051                  GLogLevelFlags log_level,
    1052                  gboolean       use_color)
    1053  {
    1054    /* we may not call _any_ GLib functions here */
    1055  
    1056    strcpy (level_prefix, log_level_to_color (log_level, use_color));
    1057  
    1058    switch (log_level & G_LOG_LEVEL_MASK)
    1059      {
    1060      case G_LOG_LEVEL_ERROR:
    1061        strcat (level_prefix, "ERROR");
    1062        break;
    1063      case G_LOG_LEVEL_CRITICAL:
    1064        strcat (level_prefix, "CRITICAL");
    1065        break;
    1066      case G_LOG_LEVEL_WARNING:
    1067        strcat (level_prefix, "WARNING");
    1068        break;
    1069      case G_LOG_LEVEL_MESSAGE:
    1070        strcat (level_prefix, "Message");
    1071        break;
    1072      case G_LOG_LEVEL_INFO:
    1073        strcat (level_prefix, "INFO");
    1074        break;
    1075      case G_LOG_LEVEL_DEBUG:
    1076        strcat (level_prefix, "DEBUG");
    1077        break;
    1078      default:
    1079        if (log_level)
    1080  	{
    1081  	  strcat (level_prefix, "LOG-");
    1082  	  format_unsigned (level_prefix + 4, log_level & G_LOG_LEVEL_MASK, 16);
    1083  	}
    1084        else
    1085  	strcat (level_prefix, "LOG");
    1086        break;
    1087      }
    1088  
    1089    strcat (level_prefix, color_reset (use_color));
    1090  
    1091    if (log_level & G_LOG_FLAG_RECURSION)
    1092      strcat (level_prefix, " (recursed)");
    1093    if (log_level & ALERT_LEVELS)
    1094      strcat (level_prefix, " **");
    1095  
    1096  #ifdef G_OS_WIN32
    1097    if ((log_level & G_LOG_FLAG_FATAL) != 0 && !g_test_initialized ())
    1098      win32_keep_fatal_message = TRUE;
    1099  #endif
    1100    return log_level_to_file (log_level);
    1101  }
    1102  
    1103  typedef struct {
    1104    gchar          *log_domain;
    1105    GLogLevelFlags  log_level;
    1106    gchar          *pattern;
    1107  } GTestExpectedMessage;
    1108  
    1109  static GSList *expected_messages = NULL;
    1110  
    1111  /**
    1112   * g_logv:
    1113   * @log_domain: (nullable): the log domain, or %NULL for the default ""
    1114   * application domain
    1115   * @log_level: the log level
    1116   * @format: the message format. See the printf() documentation
    1117   * @args: the parameters to insert into the format string
    1118   *
    1119   * Logs an error or debugging message.
    1120   *
    1121   * If the log level has been set as fatal, G_BREAKPOINT() is called
    1122   * to terminate the program. See the documentation for G_BREAKPOINT() for
    1123   * details of the debugging options this provides.
    1124   *
    1125   * If g_log_default_handler() is used as the log handler function, a new-line
    1126   * character will automatically be appended to @..., and need not be entered
    1127   * manually.
    1128   *
    1129   * If [structured logging is enabled][using-structured-logging] this will
    1130   * output via the structured log writer function (see g_log_set_writer_func()).
    1131   */
    1132  void
    1133  g_logv (const gchar   *log_domain,
    1134  	GLogLevelFlags log_level,
    1135  	const gchar   *format,
    1136  	va_list	       args)
    1137  {
    1138    gboolean was_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
    1139    gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
    1140    char buffer[1025], *msg_alloc = NULL;
    1141    const char *msg;
    1142    gint i;
    1143  
    1144    log_level &= G_LOG_LEVEL_MASK;
    1145    if (!log_level)
    1146      return;
    1147  
    1148    if (log_level & G_LOG_FLAG_RECURSION)
    1149      {
    1150        /* we use a stack buffer of fixed size, since we're likely
    1151         * in an out-of-memory situation
    1152         */
    1153        gsize size G_GNUC_UNUSED;
    1154  
    1155        size = _g_vsnprintf (buffer, 1024, format, args);
    1156        msg = buffer;
    1157      }
    1158    else
    1159      {
    1160        msg = format_string (format, args, &msg_alloc);
    1161      }
    1162  
    1163    if (expected_messages)
    1164      {
    1165        GTestExpectedMessage *expected = expected_messages->data;
    1166  
    1167        if (g_strcmp0 (expected->log_domain, log_domain) == 0 &&
    1168            ((log_level & expected->log_level) == expected->log_level) &&
    1169            g_pattern_match_simple (expected->pattern, msg))
    1170          {
    1171            expected_messages = g_slist_delete_link (expected_messages,
    1172                                                     expected_messages);
    1173            g_free (expected->log_domain);
    1174            g_free (expected->pattern);
    1175            g_free (expected);
    1176            g_free (msg_alloc);
    1177            return;
    1178          }
    1179        else if ((log_level & G_LOG_LEVEL_DEBUG) != G_LOG_LEVEL_DEBUG)
    1180          {
    1181            gchar level_prefix[STRING_BUFFER_SIZE];
    1182            gchar *expected_message;
    1183  
    1184            mklevel_prefix (level_prefix, expected->log_level, FALSE);
    1185            expected_message = g_strdup_printf ("Did not see expected message %s-%s: %s",
    1186                                                expected->log_domain ? expected->log_domain : "**",
    1187                                                level_prefix, expected->pattern);
    1188            g_log_default_handler (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, expected_message, NULL);
    1189            g_free (expected_message);
    1190  
    1191            log_level |= G_LOG_FLAG_FATAL;
    1192          }
    1193      }
    1194  
    1195    for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
    1196      {
    1197        GLogLevelFlags test_level;
    1198  
    1199        test_level = 1L << i;
    1200        if (log_level & test_level)
    1201  	{
    1202  	  GLogDomain *domain;
    1203  	  GLogFunc log_func;
    1204  	  GLogLevelFlags domain_fatal_mask;
    1205  	  gpointer data = NULL;
    1206            gboolean masquerade_fatal = FALSE;
    1207            guint depth;
    1208  
    1209  	  if (was_fatal)
    1210  	    test_level |= G_LOG_FLAG_FATAL;
    1211  	  if (was_recursion)
    1212  	    test_level |= G_LOG_FLAG_RECURSION;
    1213  
    1214  	  /* check recursion and lookup handler */
    1215  	  g_mutex_lock (&g_messages_lock);
    1216            depth = GPOINTER_TO_UINT (g_private_get (&g_log_depth));
    1217  	  domain = g_log_find_domain_L (log_domain ? log_domain : "");
    1218  	  if (depth)
    1219  	    test_level |= G_LOG_FLAG_RECURSION;
    1220  	  depth++;
    1221  	  domain_fatal_mask = domain ? domain->fatal_mask : G_LOG_FATAL_MASK;
    1222  	  if ((domain_fatal_mask | g_log_always_fatal) & test_level)
    1223  	    test_level |= G_LOG_FLAG_FATAL;
    1224  	  if (test_level & G_LOG_FLAG_RECURSION)
    1225  	    log_func = _g_log_fallback_handler;
    1226  	  else
    1227  	    log_func = g_log_domain_get_handler_L (domain, test_level, &data);
    1228  	  domain = NULL;
    1229  	  g_mutex_unlock (&g_messages_lock);
    1230  
    1231  	  g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
    1232  
    1233            log_func (log_domain, test_level, msg, data);
    1234  
    1235            if ((test_level & G_LOG_FLAG_FATAL)
    1236                && !(test_level & G_LOG_LEVEL_ERROR))
    1237              {
    1238                masquerade_fatal = fatal_log_func
    1239                  && !fatal_log_func (log_domain, test_level, msg, fatal_log_data);
    1240              }
    1241  
    1242            if ((test_level & G_LOG_FLAG_FATAL) && !masquerade_fatal)
    1243              {
    1244                /* MessageBox is allowed on UWP apps only when building against
    1245                 * the debug CRT, which will set -D_DEBUG */
    1246  #if defined(G_OS_WIN32) && (defined(_DEBUG) || !defined(G_WINAPI_ONLY_APP))
    1247                if (win32_keep_fatal_message)
    1248                  {
    1249                    WCHAR *wide_msg;
    1250  
    1251                    wide_msg = g_utf8_to_utf16 (fatal_msg_buf, -1, NULL, NULL, NULL);
    1252  
    1253                    MessageBoxW (NULL, wide_msg, NULL,
    1254                                 MB_ICONERROR | MB_SETFOREGROUND);
    1255  
    1256                    g_free (wide_msg);
    1257                  }
    1258  #endif
    1259  
    1260                _g_log_abort (!(test_level & G_LOG_FLAG_RECURSION));
    1261  	    }
    1262  	  
    1263  	  depth--;
    1264  	  g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
    1265  	}
    1266      }
    1267  
    1268    g_free (msg_alloc);
    1269  }
    1270  
    1271  /**
    1272   * g_log:
    1273   * @log_domain: (nullable): the log domain, usually %G_LOG_DOMAIN, or %NULL
    1274   *   for the default
    1275   * @log_level: the log level, either from #GLogLevelFlags
    1276   *   or a user-defined level
    1277   * @format: the message format. See the `printf()` documentation
    1278   * @...: the parameters to insert into the format string
    1279   *
    1280   * Logs an error or debugging message.
    1281   *
    1282   * If the log level has been set as fatal, G_BREAKPOINT() is called
    1283   * to terminate the program. See the documentation for G_BREAKPOINT() for
    1284   * details of the debugging options this provides.
    1285   *
    1286   * If g_log_default_handler() is used as the log handler function, a new-line
    1287   * character will automatically be appended to @..., and need not be entered
    1288   * manually.
    1289   *
    1290   * If [structured logging is enabled][using-structured-logging] this will
    1291   * output via the structured log writer function (see g_log_set_writer_func()).
    1292   */
    1293  void
    1294  g_log (const gchar   *log_domain,
    1295         GLogLevelFlags log_level,
    1296         const gchar   *format,
    1297         ...)
    1298  {
    1299    va_list args;
    1300    
    1301    va_start (args, format);
    1302    g_logv (log_domain, log_level, format, args);
    1303    va_end (args);
    1304  }
    1305  
    1306  /* Return value must be 1 byte long (plus nul byte).
    1307   * Reference: http://man7.org/linux/man-pages/man3/syslog.3.html#DESCRIPTION
    1308   */
    1309  static const gchar *
    1310  log_level_to_priority (GLogLevelFlags log_level)
    1311  {
    1312    if (log_level & G_LOG_LEVEL_ERROR)
    1313      return "3";
    1314    else if (log_level & G_LOG_LEVEL_CRITICAL)
    1315      return "4";
    1316    else if (log_level & G_LOG_LEVEL_WARNING)
    1317      return "4";
    1318    else if (log_level & G_LOG_LEVEL_MESSAGE)
    1319      return "5";
    1320    else if (log_level & G_LOG_LEVEL_INFO)
    1321      return "6";
    1322    else if (log_level & G_LOG_LEVEL_DEBUG)
    1323      return "7";
    1324  
    1325    /* Default to LOG_NOTICE for custom log levels. */
    1326    return "5";
    1327  }
    1328  
    1329  static inline FILE *
    1330  log_level_to_file (GLogLevelFlags log_level)
    1331  {
    1332    if (gmessages_use_stderr)
    1333      return stderr;
    1334  
    1335    if (log_level & (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL |
    1336                     G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE))
    1337      return stderr;
    1338    else
    1339      return stdout;
    1340  }
    1341  
    1342  static const gchar *
    1343  log_level_to_color (GLogLevelFlags log_level,
    1344                      gboolean       use_color)
    1345  {
    1346    /* we may not call _any_ GLib functions here */
    1347  
    1348    if (!use_color)
    1349      return "";
    1350  
    1351    if (log_level & G_LOG_LEVEL_ERROR)
    1352      return "\033[1;31m"; /* red */
    1353    else if (log_level & G_LOG_LEVEL_CRITICAL)
    1354      return "\033[1;35m"; /* magenta */
    1355    else if (log_level & G_LOG_LEVEL_WARNING)
    1356      return "\033[1;33m"; /* yellow */
    1357    else if (log_level & G_LOG_LEVEL_MESSAGE)
    1358      return "\033[1;32m"; /* green */
    1359    else if (log_level & G_LOG_LEVEL_INFO)
    1360      return "\033[1;32m"; /* green */
    1361    else if (log_level & G_LOG_LEVEL_DEBUG)
    1362      return "\033[1;32m"; /* green */
    1363  
    1364    /* No color for custom log levels. */
    1365    return "";
    1366  }
    1367  
    1368  static const gchar *
    1369  color_reset (gboolean use_color)
    1370  {
    1371    /* we may not call _any_ GLib functions here */
    1372  
    1373    if (!use_color)
    1374      return "";
    1375  
    1376    return "\033[0m";
    1377  }
    1378  
    1379  #ifdef G_OS_WIN32
    1380  
    1381  /* We might be using tty emulators such as mintty, so try to detect it, if we passed in a valid FD
    1382   * so we need to check the name of the pipe if _isatty (fd) == 0
    1383   */
    1384  
    1385  static gboolean
    1386  win32_is_pipe_tty (int fd)
    1387  {
    1388    gboolean result = FALSE;
    1389    HANDLE h_fd;
    1390    FILE_NAME_INFO *info = NULL;
    1391    gint info_size = sizeof (FILE_NAME_INFO) + sizeof (WCHAR) * MAX_PATH;
    1392    wchar_t *name = NULL;
    1393    gint length;
    1394  
    1395    h_fd = (HANDLE) _get_osfhandle (fd);
    1396  
    1397    if (h_fd == INVALID_HANDLE_VALUE || GetFileType (h_fd) != FILE_TYPE_PIPE)
    1398      goto done_query;
    1399  
    1400    /* mintty uses a pipe, in the form of \{cygwin|msys}-xxxxxxxxxxxxxxxx-ptyN-{from|to}-master */
    1401  
    1402    info = g_try_malloc (info_size);
    1403  
    1404    if (info == NULL ||
    1405        !GetFileInformationByHandleEx (h_fd, FileNameInfo, info, info_size))
    1406      goto done_query;
    1407  
    1408    info->FileName[info->FileNameLength / sizeof (WCHAR)] = L'\0';
    1409    name = info->FileName;
    1410  
    1411    length = wcslen (L"\\cygwin-");
    1412    if (wcsncmp (name, L"\\cygwin-", length))
    1413      {
    1414        length = wcslen (L"\\msys-");
    1415        if (wcsncmp (name, L"\\msys-", length))
    1416          goto done_query;
    1417      }
    1418  
    1419    name += length;
    1420    length = wcsspn (name, L"0123456789abcdefABCDEF");
    1421    if (length != 16)
    1422      goto done_query;
    1423  
    1424    name += length;
    1425    length = wcslen (L"-pty");
    1426    if (wcsncmp (name, L"-pty", length))
    1427      goto done_query;
    1428  
    1429    name += length;
    1430    length = wcsspn (name, L"0123456789");
    1431    if (length != 1)
    1432      goto done_query;
    1433  
    1434    name += length;
    1435    length = wcslen (L"-to-master");
    1436    if (wcsncmp (name, L"-to-master", length))
    1437      {
    1438        length = wcslen (L"-from-master");
    1439        if (wcsncmp (name, L"-from-master", length))
    1440          goto done_query;
    1441      }
    1442  
    1443    result = TRUE;
    1444  
    1445  done_query:
    1446    if (info != NULL)
    1447      g_free (info);
    1448  
    1449    return result;
    1450  }
    1451  #endif
    1452  
    1453  #pragma GCC diagnostic push
    1454  #pragma GCC diagnostic ignored "-Wformat-nonliteral"
    1455  
    1456  /**
    1457   * g_log_structured:
    1458   * @log_domain: log domain, usually %G_LOG_DOMAIN
    1459   * @log_level: log level, either from #GLogLevelFlags, or a user-defined
    1460   *    level
    1461   * @...: key-value pairs of structured data to add to the log entry, followed
    1462   *    by the key "MESSAGE", followed by a printf()-style message format,
    1463   *    followed by parameters to insert in the format string
    1464   *
    1465   * Log a message with structured data.
    1466   *
    1467   * The message will be passed through to the log writer set by the application
    1468   * using g_log_set_writer_func(). If the message is fatal (i.e. its log level
    1469   * is %G_LOG_LEVEL_ERROR), the program will be aborted by calling
    1470   * G_BREAKPOINT() at the end of this function. If the log writer returns
    1471   * %G_LOG_WRITER_UNHANDLED (failure), no other fallback writers will be tried.
    1472   * See the documentation for #GLogWriterFunc for information on chaining
    1473   * writers.
    1474   *
    1475   * The structured data is provided as key–value pairs, where keys are UTF-8
    1476   * strings, and values are arbitrary pointers — typically pointing to UTF-8
    1477   * strings, but that is not a requirement. To pass binary (non-nul-terminated)
    1478   * structured data, use g_log_structured_array(). The keys for structured data
    1479   * should follow the [systemd journal
    1480   * fields](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
    1481   * specification. It is suggested that custom keys are namespaced according to
    1482   * the code which sets them. For example, custom keys from GLib all have a
    1483   * `GLIB_` prefix.
    1484   *
    1485   * Note that keys that expect UTF-8 strings (specifically `"MESSAGE"` and
    1486   * `"GLIB_DOMAIN"`) must be passed as NUL-terminated UTF-8 strings until GLib
    1487   * version 2.74.1 because the default log handler did not consider the length of
    1488   * the `GLogField`. Starting with GLib 2.74.1 this is fixed and
    1489   * non-NUL-terminated UTF-8 strings can be passed with their correct length.
    1490   *
    1491   * The @log_domain will be converted into a `GLIB_DOMAIN` field. @log_level will
    1492   * be converted into a
    1493   * [`PRIORITY`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#PRIORITY=)
    1494   * field. The format string will have its placeholders substituted for the provided
    1495   * values and be converted into a
    1496   * [`MESSAGE`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#MESSAGE=)
    1497   * field.
    1498   *
    1499   * Other fields you may commonly want to pass into this function:
    1500   *
    1501   *  * [`MESSAGE_ID`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#MESSAGE_ID=)
    1502   *  * [`CODE_FILE`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#CODE_FILE=)
    1503   *  * [`CODE_LINE`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#CODE_LINE=)
    1504   *  * [`CODE_FUNC`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#CODE_FUNC=)
    1505   *  * [`ERRNO`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#ERRNO=)
    1506   *
    1507   * Note that `CODE_FILE`, `CODE_LINE` and `CODE_FUNC` are automatically set by
    1508   * the logging macros, G_DEBUG_HERE(), g_message(), g_warning(), g_critical(),
    1509   * g_error(), etc, if the symbols `G_LOG_USE_STRUCTURED` is defined before including
    1510   * `glib.h`.
    1511   *
    1512   * For example:
    1513   *
    1514   * |[<!-- language="C" -->
    1515   * g_log_structured (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
    1516   *                   "MESSAGE_ID", "06d4df59e6c24647bfe69d2c27ef0b4e",
    1517   *                   "MY_APPLICATION_CUSTOM_FIELD", "some debug string",
    1518   *                   "MESSAGE", "This is a debug message about pointer %p and integer %u.",
    1519   *                   some_pointer, some_integer);
    1520   * ]|
    1521   *
    1522   * Note that each `MESSAGE_ID` must be [uniquely and randomly
    1523   * generated](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#MESSAGE_ID=).
    1524   * If adding a `MESSAGE_ID`, consider shipping a [message
    1525   * catalog](https://www.freedesktop.org/wiki/Software/systemd/catalog/) with
    1526   * your software.
    1527   *
    1528   * To pass a user data pointer to the log writer function which is specific to
    1529   * this logging call, you must use g_log_structured_array() and pass the pointer
    1530   * as a field with #GLogField.length set to zero, otherwise it will be
    1531   * interpreted as a string.
    1532   *
    1533   * For example:
    1534   *
    1535   * |[<!-- language="C" -->
    1536   * const GLogField fields[] = {
    1537   *   { "MESSAGE", "This is a debug message.", -1 },
    1538   *   { "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 },
    1539   *   { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 },
    1540   *   { "MY_APPLICATION_STATE", state_object, 0 },
    1541   * };
    1542   * g_log_structured_array (G_LOG_LEVEL_DEBUG, fields, G_N_ELEMENTS (fields));
    1543   * ]|
    1544   *
    1545   * Note also that, even if no other structured fields are specified, there
    1546   * must always be a `MESSAGE` key before the format string. The `MESSAGE`-format
    1547   * pair has to be the last of the key-value pairs, and `MESSAGE` is the only
    1548   * field for which printf()-style formatting is supported.
    1549   *
    1550   * The default writer function for `stdout` and `stderr` will automatically
    1551   * append a new-line character after the message, so you should not add one
    1552   * manually to the format string.
    1553   *
    1554   * Since: 2.50
    1555   */
    1556  void
    1557  g_log_structured (const gchar    *log_domain,
    1558                    GLogLevelFlags  log_level,
    1559                    ...)
    1560  {
    1561    va_list args;
    1562    gchar buffer[1025], *message_allocated = NULL;
    1563    const char *format;
    1564    const gchar *message;
    1565    gpointer p;
    1566    gsize n_fields, i;
    1567    GLogField stack_fields[16];
    1568    GLogField *fields = stack_fields;
    1569    GLogField *fields_allocated = NULL;
    1570    GArray *array = NULL;
    1571  
    1572    va_start (args, log_level);
    1573  
    1574    /* MESSAGE and PRIORITY are a given */
    1575    n_fields = 2;
    1576  
    1577    if (log_domain)
    1578      n_fields++;
    1579  
    1580    for (p = va_arg (args, gchar *), i = n_fields;
    1581         strcmp (p, "MESSAGE") != 0;
    1582         p = va_arg (args, gchar *), i++)
    1583      {
    1584        GLogField field;
    1585        const gchar *key = p;
    1586        gconstpointer value = va_arg (args, gpointer);
    1587  
    1588        field.key = key;
    1589        field.value = value;
    1590        field.length = -1;
    1591  
    1592        if (i < 16)
    1593          stack_fields[i] = field;
    1594        else
    1595          {
    1596            /* Don't allow dynamic allocation, since we're likely
    1597             * in an out-of-memory situation. For lack of a better solution,
    1598             * just ignore further key-value pairs.
    1599             */
    1600            if (log_level & G_LOG_FLAG_RECURSION)
    1601              continue;
    1602  
    1603            if (i == 16)
    1604              {
    1605                array = g_array_sized_new (FALSE, FALSE, sizeof (GLogField), 32);
    1606                g_array_append_vals (array, stack_fields, 16);
    1607              }
    1608  
    1609            g_array_append_val (array, field);
    1610          }
    1611      }
    1612  
    1613    n_fields = i;
    1614  
    1615    if (array)
    1616      fields = fields_allocated = (GLogField *) g_array_free (array, FALSE);
    1617  
    1618    format = va_arg (args, gchar *);
    1619  
    1620    if (log_level & G_LOG_FLAG_RECURSION)
    1621      {
    1622        /* we use a stack buffer of fixed size, since we're likely
    1623         * in an out-of-memory situation
    1624         */
    1625        gsize size G_GNUC_UNUSED;
    1626  
    1627        size = _g_vsnprintf (buffer, sizeof (buffer), format, args);
    1628        message = buffer;
    1629      }
    1630    else
    1631      {
    1632        message = format_string (format, args, &message_allocated);
    1633      }
    1634  
    1635    /* Add MESSAGE, PRIORITY and GLIB_DOMAIN. */
    1636    fields[0].key = "MESSAGE";
    1637    fields[0].value = message;
    1638    fields[0].length = -1;
    1639  
    1640    fields[1].key = "PRIORITY";
    1641    fields[1].value = log_level_to_priority (log_level);
    1642    fields[1].length = -1;
    1643  
    1644    if (log_domain)
    1645      {
    1646        fields[2].key = "GLIB_DOMAIN";
    1647        fields[2].value = log_domain;
    1648        fields[2].length = -1;
    1649      }
    1650  
    1651    /* Log it. */
    1652    g_log_structured_array (log_level, fields, n_fields);
    1653  
    1654    g_free (fields_allocated);
    1655    g_free (message_allocated);
    1656  
    1657    va_end (args);
    1658  }
    1659  
    1660  /**
    1661   * g_log_variant:
    1662   * @log_domain: (nullable): log domain, usually %G_LOG_DOMAIN
    1663   * @log_level: log level, either from #GLogLevelFlags, or a user-defined
    1664   *    level
    1665   * @fields: a dictionary (#GVariant of the type %G_VARIANT_TYPE_VARDICT)
    1666   * containing the key-value pairs of message data.
    1667   *
    1668   * Log a message with structured data, accepting the data within a #GVariant. This
    1669   * version is especially useful for use in other languages, via introspection.
    1670   *
    1671   * The only mandatory item in the @fields dictionary is the "MESSAGE" which must
    1672   * contain the text shown to the user.
    1673   *
    1674   * The values in the @fields dictionary are likely to be of type String
    1675   * (%G_VARIANT_TYPE_STRING). Array of bytes (%G_VARIANT_TYPE_BYTESTRING) is also
    1676   * supported. In this case the message is handled as binary and will be forwarded
    1677   * to the log writer as such. The size of the array should not be higher than
    1678   * %G_MAXSSIZE. Otherwise it will be truncated to this size. For other types
    1679   * g_variant_print() will be used to convert the value into a string.
    1680   *
    1681   * For more details on its usage and about the parameters, see g_log_structured().
    1682   *
    1683   * Since: 2.50
    1684   */
    1685  
    1686  void
    1687  g_log_variant (const gchar    *log_domain,
    1688                 GLogLevelFlags  log_level,
    1689                 GVariant       *fields)
    1690  {
    1691    GVariantIter iter;
    1692    GVariant *value;
    1693    gchar *key;
    1694    GArray *fields_array;
    1695    GLogField field;
    1696    GSList *values_list, *print_list;
    1697  
    1698    g_return_if_fail (g_variant_is_of_type (fields, G_VARIANT_TYPE_VARDICT));
    1699  
    1700    values_list = print_list = NULL;
    1701    fields_array = g_array_new (FALSE, FALSE, sizeof (GLogField));
    1702  
    1703    field.key = "PRIORITY";
    1704    field.value = log_level_to_priority (log_level);
    1705    field.length = -1;
    1706    g_array_append_val (fields_array, field);
    1707  
    1708    if (log_domain)
    1709      {
    1710        field.key = "GLIB_DOMAIN";
    1711        field.value = log_domain;
    1712        field.length = -1;
    1713        g_array_append_val (fields_array, field);
    1714      }
    1715  
    1716    g_variant_iter_init (&iter, fields);
    1717    while (g_variant_iter_next (&iter, "{&sv}", &key, &value))
    1718      {
    1719        gboolean defer_unref = TRUE;
    1720  
    1721        field.key = key;
    1722        field.length = -1;
    1723  
    1724        if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
    1725          {
    1726            field.value = g_variant_get_string (value, NULL);
    1727          }
    1728        else if (g_variant_is_of_type (value, G_VARIANT_TYPE_BYTESTRING))
    1729          {
    1730            gsize s;
    1731            field.value = g_variant_get_fixed_array (value, &s, sizeof (guchar));
    1732            if (G_LIKELY (s <= G_MAXSSIZE))
    1733              {
    1734                field.length = s;
    1735              }
    1736            else
    1737              {
    1738                 _g_fprintf (stderr,
    1739                             "Byte array too large (%" G_GSIZE_FORMAT " bytes)"
    1740                             " passed to g_log_variant(). Truncating to " G_STRINGIFY (G_MAXSSIZE)
    1741                             " bytes.", s);
    1742                field.length = G_MAXSSIZE;
    1743              }
    1744          }
    1745        else
    1746          {
    1747            char *s = g_variant_print (value, FALSE);
    1748            field.value = s;
    1749            print_list = g_slist_prepend (print_list, s);
    1750            defer_unref = FALSE;
    1751          }
    1752  
    1753        g_array_append_val (fields_array, field);
    1754  
    1755        if (G_LIKELY (defer_unref))
    1756          values_list = g_slist_prepend (values_list, value);
    1757        else
    1758          g_variant_unref (value);
    1759      }
    1760  
    1761    /* Log it. */
    1762    g_log_structured_array (log_level, (GLogField *) fields_array->data, fields_array->len);
    1763  
    1764    g_array_free (fields_array, TRUE);
    1765    g_slist_free_full (values_list, (GDestroyNotify) g_variant_unref);
    1766    g_slist_free_full (print_list, g_free);
    1767  }
    1768  
    1769  
    1770  #pragma GCC diagnostic pop
    1771  
    1772  static GLogWriterOutput _g_log_writer_fallback (GLogLevelFlags   log_level,
    1773                                                  const GLogField *fields,
    1774                                                  gsize            n_fields,
    1775                                                  gpointer         user_data);
    1776  
    1777  /**
    1778   * g_log_structured_array:
    1779   * @log_level: log level, either from #GLogLevelFlags, or a user-defined
    1780   *    level
    1781   * @fields: (array length=n_fields): key–value pairs of structured data to add
    1782   *    to the log message
    1783   * @n_fields: number of elements in the @fields array
    1784   *
    1785   * Log a message with structured data. The message will be passed through to the
    1786   * log writer set by the application using g_log_set_writer_func(). If the
    1787   * message is fatal (i.e. its log level is %G_LOG_LEVEL_ERROR), the program will
    1788   * be aborted at the end of this function.
    1789   *
    1790   * See g_log_structured() for more documentation.
    1791   *
    1792   * This assumes that @log_level is already present in @fields (typically as the
    1793   * `PRIORITY` field).
    1794   *
    1795   * Since: 2.50
    1796   */
    1797  void
    1798  g_log_structured_array (GLogLevelFlags   log_level,
    1799                          const GLogField *fields,
    1800                          gsize            n_fields)
    1801  {
    1802    GLogWriterFunc writer_func;
    1803    gpointer writer_user_data;
    1804    gboolean recursion;
    1805    guint depth;
    1806  
    1807    if (n_fields == 0)
    1808      return;
    1809  
    1810    /* Check for recursion and look up the writer function. */
    1811    depth = GPOINTER_TO_UINT (g_private_get (&g_log_structured_depth));
    1812    recursion = (depth > 0);
    1813  
    1814    g_mutex_lock (&g_messages_lock);
    1815  
    1816    writer_func = recursion ? _g_log_writer_fallback : log_writer_func;
    1817    writer_user_data = log_writer_user_data;
    1818  
    1819    g_mutex_unlock (&g_messages_lock);
    1820  
    1821    /* Write the log entry. */
    1822    g_private_set (&g_log_structured_depth, GUINT_TO_POINTER (++depth));
    1823  
    1824    g_assert (writer_func != NULL);
    1825    writer_func (log_level, fields, n_fields, writer_user_data);
    1826  
    1827    g_private_set (&g_log_structured_depth, GUINT_TO_POINTER (--depth));
    1828  
    1829    /* Abort if the message was fatal. */
    1830    if (log_level & G_LOG_FATAL_MASK)
    1831      _g_log_abort (!(log_level & G_LOG_FLAG_RECURSION));
    1832  }
    1833  
    1834  /* Semi-private helper function to implement the g_message() (etc.) macros
    1835   * with support for G_GNUC_PRINTF so that @message_format can be checked
    1836   * with -Wformat. */
    1837  void
    1838  g_log_structured_standard (const gchar    *log_domain,
    1839                             GLogLevelFlags  log_level,
    1840                             const gchar    *file,
    1841                             const gchar    *line,
    1842                             const gchar    *func,
    1843                             const gchar    *message_format,
    1844                             ...)
    1845  {
    1846    GLogField fields[] =
    1847      {
    1848        { "PRIORITY", log_level_to_priority (log_level), -1 },
    1849        { "CODE_FILE", file, -1 },
    1850        { "CODE_LINE", line, -1 },
    1851        { "CODE_FUNC", func, -1 },
    1852        /* Filled in later: */
    1853        { "MESSAGE", NULL, -1 },
    1854        /* If @log_domain is %NULL, we will not pass this field: */
    1855        { "GLIB_DOMAIN", log_domain, -1 },
    1856      };
    1857    gsize n_fields;
    1858    gchar *message_allocated = NULL;
    1859    gchar buffer[1025];
    1860    va_list args;
    1861  
    1862    va_start (args, message_format);
    1863  
    1864    if (log_level & G_LOG_FLAG_RECURSION)
    1865      {
    1866        /* we use a stack buffer of fixed size, since we're likely
    1867         * in an out-of-memory situation
    1868         */
    1869        gsize size G_GNUC_UNUSED;
    1870  
    1871        size = _g_vsnprintf (buffer, sizeof (buffer), message_format, args);
    1872        fields[4].value = buffer;
    1873      }
    1874    else
    1875      {
    1876        fields[4].value = format_string (message_format, args, &message_allocated);
    1877      }
    1878  
    1879    va_end (args);
    1880  
    1881    n_fields = G_N_ELEMENTS (fields) - ((log_domain == NULL) ? 1 : 0);
    1882    g_log_structured_array (log_level, fields, n_fields);
    1883  
    1884    g_free (message_allocated);
    1885  }
    1886  
    1887  /**
    1888   * g_log_set_writer_func:
    1889   * @func: log writer function, which must not be %NULL
    1890   * @user_data: (closure func): user data to pass to @func
    1891   * @user_data_free: (destroy func): function to free @user_data once it’s
    1892   *    finished with, if non-%NULL
    1893   *
    1894   * Set a writer function which will be called to format and write out each log
    1895   * message. Each program should set a writer function, or the default writer
    1896   * (g_log_writer_default()) will be used.
    1897   *
    1898   * Libraries **must not** call this function — only programs are allowed to
    1899   * install a writer function, as there must be a single, central point where
    1900   * log messages are formatted and outputted.
    1901   *
    1902   * There can only be one writer function. It is an error to set more than one.
    1903   *
    1904   * Since: 2.50
    1905   */
    1906  void
    1907  g_log_set_writer_func (GLogWriterFunc func,
    1908                         gpointer       user_data,
    1909                         GDestroyNotify user_data_free)
    1910  {
    1911    g_return_if_fail (func != NULL);
    1912  
    1913    g_mutex_lock (&g_messages_lock);
    1914  
    1915    if (log_writer_func != g_log_writer_default)
    1916      {
    1917        g_mutex_unlock (&g_messages_lock);
    1918        g_error ("g_log_set_writer_func() called multiple times");
    1919        return;
    1920      }
    1921  
    1922    log_writer_func = func;
    1923    log_writer_user_data = user_data;
    1924    log_writer_user_data_free = user_data_free;
    1925  
    1926    g_mutex_unlock (&g_messages_lock);
    1927  }
    1928  
    1929  /**
    1930   * g_log_writer_supports_color:
    1931   * @output_fd: output file descriptor to check
    1932   *
    1933   * Check whether the given @output_fd file descriptor supports ANSI color
    1934   * escape sequences. If so, they can safely be used when formatting log
    1935   * messages.
    1936   *
    1937   * Returns: %TRUE if ANSI color escapes are supported, %FALSE otherwise
    1938   * Since: 2.50
    1939   */
    1940  gboolean
    1941  g_log_writer_supports_color (gint output_fd)
    1942  {
    1943  #ifdef G_OS_WIN32
    1944    gboolean result = FALSE;
    1945    GWin32InvalidParameterHandler handler;
    1946  #endif
    1947  
    1948    g_return_val_if_fail (output_fd >= 0, FALSE);
    1949  
    1950    /* FIXME: This check could easily be expanded in future to be more robust
    1951     * against different types of terminal, which still vary in their color
    1952     * support. cmd.exe on Windows, for example, supports ANSI colors only
    1953     * from Windows 10 onwards; bash on Windows has always supported ANSI colors.
    1954     * The Windows 10 color support is supported on:
    1955     * -Output in the cmd.exe, MSYS/Cygwin standard consoles.
    1956     * -Output in the cmd.exe, MSYS/Cygwin piped to the less program.
    1957     * but not:
    1958     * -Output in Cygwin via mintty (https://github.com/mintty/mintty/issues/482)
    1959     * -Color code output when output redirected to file (i.e. program 2> some.txt)
    1960     *
    1961     * On UNIX systems, we probably want to use the functions from terminfo to
    1962     * work out whether colors are supported.
    1963     *
    1964     * Some examples:
    1965     *  - https://github.com/chalk/supports-color/blob/9434c93918301a6b47faa01999482adfbf1b715c/index.js#L61
    1966     *  - http://stackoverflow.com/questions/16755142/how-to-make-win32-console-recognize-ansi-vt100-escape-sequences
    1967     *  - http://blog.mmediasys.com/2010/11/24/we-all-love-colors/
    1968     *  - http://unix.stackexchange.com/questions/198794/where-does-the-term-environment-variable-default-get-set
    1969     */
    1970  #ifdef G_OS_WIN32
    1971  
    1972    g_win32_push_empty_invalid_parameter_handler (&handler);
    1973  
    1974    if (g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_ANY))
    1975      {
    1976        HANDLE h_output;
    1977        DWORD dw_mode;
    1978  
    1979        if (_isatty (output_fd))
    1980          {
    1981            h_output = (HANDLE) _get_osfhandle (output_fd);
    1982  
    1983            if (!GetConsoleMode (h_output, &dw_mode))
    1984              goto reset_invalid_param_handler;
    1985  
    1986            if (dw_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)
    1987              result = TRUE;
    1988  
    1989            if (!SetConsoleMode (h_output, dw_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING))
    1990              goto reset_invalid_param_handler;
    1991  
    1992            result = TRUE;
    1993          }
    1994      }
    1995  
    1996    /* FIXME: Support colored outputs for structured logs for pre-Windows 10,
    1997     *        perhaps using WriteConsoleOutput or SetConsoleTextAttribute
    1998     *        (bug 775468), on standard Windows consoles, such as cmd.exe
    1999     */
    2000    if (!result)
    2001      result = win32_is_pipe_tty (output_fd);
    2002  
    2003  reset_invalid_param_handler:
    2004    g_win32_pop_invalid_parameter_handler (&handler);
    2005  
    2006    return result;
    2007  #else
    2008    return isatty (output_fd);
    2009  #endif
    2010  }
    2011  
    2012  #if defined(__linux__) && !defined(__BIONIC__)
    2013  static int journal_fd = -1;
    2014  
    2015  #ifndef SOCK_CLOEXEC
    2016  #define SOCK_CLOEXEC 0
    2017  #else
    2018  #define HAVE_SOCK_CLOEXEC 1
    2019  #endif
    2020  
    2021  static void
    2022  open_journal (void)
    2023  {
    2024    if ((journal_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0)
    2025      return;
    2026  
    2027  #ifndef HAVE_SOCK_CLOEXEC
    2028    if (fcntl (journal_fd, F_SETFD, FD_CLOEXEC) < 0)
    2029      {
    2030        close (journal_fd);
    2031        journal_fd = -1;
    2032      }
    2033  #endif
    2034  }
    2035  #endif
    2036  
    2037  /**
    2038   * g_log_writer_is_journald:
    2039   * @output_fd: output file descriptor to check
    2040   *
    2041   * Check whether the given @output_fd file descriptor is a connection to the
    2042   * systemd journal, or something else (like a log file or `stdout` or
    2043   * `stderr`).
    2044   *
    2045   * Invalid file descriptors are accepted and return %FALSE, which allows for
    2046   * the following construct without needing any additional error handling:
    2047   * |[<!-- language="C" -->
    2048   *   is_journald = g_log_writer_is_journald (fileno (stderr));
    2049   * ]|
    2050   *
    2051   * Returns: %TRUE if @output_fd points to the journal, %FALSE otherwise
    2052   * Since: 2.50
    2053   */
    2054  gboolean
    2055  g_log_writer_is_journald (gint output_fd)
    2056  {
    2057  #if defined(__linux__) && !defined(__BIONIC__)
    2058    return _g_fd_is_journal (output_fd);
    2059  #else
    2060    return FALSE;
    2061  #endif
    2062  }
    2063  
    2064  static void escape_string (GString *string);
    2065  
    2066  /**
    2067   * g_log_writer_format_fields:
    2068   * @log_level: log level, either from #GLogLevelFlags, or a user-defined
    2069   *    level
    2070   * @fields: (array length=n_fields): key–value pairs of structured data forming
    2071   *    the log message
    2072   * @n_fields: number of elements in the @fields array
    2073   * @use_color: %TRUE to use ANSI color escape sequences when formatting the
    2074   *    message, %FALSE to not
    2075   *
    2076   * Format a structured log message as a string suitable for outputting to the
    2077   * terminal (or elsewhere). This will include the values of all fields it knows
    2078   * how to interpret, which includes `MESSAGE` and `GLIB_DOMAIN` (see the
    2079   * documentation for g_log_structured()). It does not include values from
    2080   * unknown fields.
    2081   *
    2082   * The returned string does **not** have a trailing new-line character. It is
    2083   * encoded in the character set of the current locale, which is not necessarily
    2084   * UTF-8.
    2085   *
    2086   * Returns: (transfer full): string containing the formatted log message, in
    2087   *    the character set of the current locale
    2088   * Since: 2.50
    2089   */
    2090  gchar *
    2091  g_log_writer_format_fields (GLogLevelFlags   log_level,
    2092                              const GLogField *fields,
    2093                              gsize            n_fields,
    2094                              gboolean         use_color)
    2095  {
    2096    gsize i;
    2097    const gchar *message = NULL;
    2098    const gchar *log_domain = NULL;
    2099    gssize message_length = -1;
    2100    gssize log_domain_length = -1;
    2101    gchar level_prefix[STRING_BUFFER_SIZE];
    2102    GString *gstring;
    2103    gint64 now;
    2104    time_t now_secs;
    2105    struct tm now_tm;
    2106    gchar time_buf[128];
    2107  
    2108    /* Extract some common fields. */
    2109    for (i = 0; (message == NULL || log_domain == NULL) && i < n_fields; i++)
    2110      {
    2111        const GLogField *field = &fields[i];
    2112  
    2113        if (g_strcmp0 (field->key, "MESSAGE") == 0)
    2114          {
    2115            message = field->value;
    2116            message_length = field->length;
    2117          }
    2118        else if (g_strcmp0 (field->key, "GLIB_DOMAIN") == 0)
    2119          {
    2120            log_domain = field->value;
    2121            log_domain_length = field->length;
    2122          }
    2123      }
    2124  
    2125    /* Format things. */
    2126    mklevel_prefix (level_prefix, log_level, use_color);
    2127  
    2128    gstring = g_string_new (NULL);
    2129    if (log_level & ALERT_LEVELS)
    2130      g_string_append (gstring, "\n");
    2131    if (!log_domain)
    2132      g_string_append (gstring, "** ");
    2133  
    2134    if ((g_log_msg_prefix & (log_level & G_LOG_LEVEL_MASK)) ==
    2135        (log_level & G_LOG_LEVEL_MASK))
    2136      {
    2137        const gchar *prg_name = g_get_prgname ();
    2138        gulong pid = getpid ();
    2139  
    2140        if (prg_name == NULL)
    2141          g_string_append_printf (gstring, "(process:%lu): ", pid);
    2142        else
    2143          g_string_append_printf (gstring, "(%s:%lu): ", prg_name, pid);
    2144      }
    2145  
    2146    if (log_domain != NULL)
    2147      {
    2148        g_string_append_len (gstring, log_domain, log_domain_length);
    2149        g_string_append_c (gstring, '-');
    2150      }
    2151    g_string_append (gstring, level_prefix);
    2152  
    2153    g_string_append (gstring, ": ");
    2154  
    2155    /* Timestamp */
    2156    now = g_get_real_time ();
    2157    now_secs = (time_t) (now / 1000000);
    2158    if (_g_localtime (now_secs, &now_tm))
    2159      strftime (time_buf, sizeof (time_buf), "%H:%M:%S", &now_tm);
    2160    else
    2161      strcpy (time_buf, "(error)");
    2162  
    2163    g_string_append_printf (gstring, "%s%s.%03d%s: ",
    2164                            use_color ? "\033[34m" : "",
    2165                            time_buf, (gint) ((now / 1000) % 1000),
    2166                            color_reset (use_color));
    2167  
    2168    if (message == NULL)
    2169      {
    2170        g_string_append (gstring, "(NULL) message");
    2171      }
    2172    else
    2173      {
    2174        GString *msg;
    2175        const gchar *charset;
    2176  
    2177        msg = g_string_new_len (message, message_length);
    2178        escape_string (msg);
    2179  
    2180        if (g_get_console_charset (&charset))
    2181          {
    2182            /* charset is UTF-8 already */
    2183            g_string_append (gstring, msg->str);
    2184          }
    2185        else
    2186          {
    2187            gchar *lstring = strdup_convert (msg->str, charset);
    2188            g_string_append (gstring, lstring);
    2189            g_free (lstring);
    2190          }
    2191  
    2192        g_string_free (msg, TRUE);
    2193      }
    2194  
    2195    return g_string_free (gstring, FALSE);
    2196  }
    2197  
    2198  /* Enable support for the journal if we're on a recent enough Linux */
    2199  #if defined(__linux__) && !defined(__BIONIC__) && defined(HAVE_MKOSTEMP) && defined(O_CLOEXEC)
    2200  #define ENABLE_JOURNAL_SENDV
    2201  #endif
    2202  
    2203  #ifdef ENABLE_JOURNAL_SENDV
    2204  static int
    2205  journal_sendv (struct iovec *iov,
    2206                 gsize         iovlen)
    2207  {
    2208    int buf_fd = -1;
    2209    struct msghdr mh;
    2210    struct sockaddr_un sa;
    2211    union {
    2212      struct cmsghdr cmsghdr;
    2213      guint8 buf[CMSG_SPACE(sizeof(int))];
    2214    } control;
    2215    struct cmsghdr *cmsg;
    2216    char path[] = "/dev/shm/journal.XXXXXX";
    2217  
    2218    if (journal_fd < 0)
    2219      open_journal ();
    2220  
    2221    if (journal_fd < 0)
    2222      return -1;
    2223  
    2224    memset (&sa, 0, sizeof (sa));
    2225    sa.sun_family = AF_UNIX;
    2226    if (g_strlcpy (sa.sun_path, "/run/systemd/journal/socket", sizeof (sa.sun_path)) >= sizeof (sa.sun_path))
    2227      return -1;
    2228  
    2229    memset (&mh, 0, sizeof (mh));
    2230    mh.msg_name = &sa;
    2231    mh.msg_namelen = offsetof (struct sockaddr_un, sun_path) + strlen (sa.sun_path);
    2232    mh.msg_iov = iov;
    2233    mh.msg_iovlen = iovlen;
    2234  
    2235  retry:
    2236    if (sendmsg (journal_fd, &mh, MSG_NOSIGNAL) >= 0)
    2237      return 0;
    2238  
    2239    if (errno == EINTR)
    2240      goto retry;
    2241  
    2242    if (errno != EMSGSIZE && errno != ENOBUFS)
    2243      return -1;
    2244  
    2245    /* Message was too large, so dump to temporary file
    2246     * and pass an FD to the journal
    2247     */
    2248    if ((buf_fd = mkostemp (path, O_CLOEXEC|O_RDWR)) < 0)
    2249      return -1;
    2250  
    2251    if (unlink (path) < 0)
    2252      {
    2253        close (buf_fd);
    2254        return -1;
    2255      }
    2256  
    2257    if (writev (buf_fd, iov, iovlen) < 0)
    2258      {
    2259        close (buf_fd);
    2260        return -1;
    2261      }
    2262  
    2263    mh.msg_iov = NULL;
    2264    mh.msg_iovlen = 0;
    2265  
    2266    memset (&control, 0, sizeof (control));
    2267    mh.msg_control = &control;
    2268    mh.msg_controllen = sizeof (control);
    2269  
    2270    cmsg = CMSG_FIRSTHDR (&mh);
    2271    cmsg->cmsg_level = SOL_SOCKET;
    2272    cmsg->cmsg_type = SCM_RIGHTS;
    2273    cmsg->cmsg_len = CMSG_LEN (sizeof (int));
    2274    memcpy (CMSG_DATA (cmsg), &buf_fd, sizeof (int));
    2275  
    2276    mh.msg_controllen = cmsg->cmsg_len;
    2277  
    2278  retry2:
    2279    if (sendmsg (journal_fd, &mh, MSG_NOSIGNAL) >= 0)
    2280      return 0;
    2281  
    2282    if (errno == EINTR)
    2283      goto retry2;
    2284  
    2285    return -1;
    2286  }
    2287  #endif /* ENABLE_JOURNAL_SENDV */
    2288  
    2289  /**
    2290   * g_log_writer_journald:
    2291   * @log_level: log level, either from #GLogLevelFlags, or a user-defined
    2292   *    level
    2293   * @fields: (array length=n_fields): key–value pairs of structured data forming
    2294   *    the log message
    2295   * @n_fields: number of elements in the @fields array
    2296   * @user_data: user data passed to g_log_set_writer_func()
    2297   *
    2298   * Format a structured log message and send it to the systemd journal as a set
    2299   * of key–value pairs. All fields are sent to the journal, but if a field has
    2300   * length zero (indicating program-specific data) then only its key will be
    2301   * sent.
    2302   *
    2303   * This is suitable for use as a #GLogWriterFunc.
    2304   *
    2305   * If GLib has been compiled without systemd support, this function is still
    2306   * defined, but will always return %G_LOG_WRITER_UNHANDLED.
    2307   *
    2308   * Returns: %G_LOG_WRITER_HANDLED on success, %G_LOG_WRITER_UNHANDLED otherwise
    2309   * Since: 2.50
    2310   */
    2311  GLogWriterOutput
    2312  g_log_writer_journald (GLogLevelFlags   log_level,
    2313                         const GLogField *fields,
    2314                         gsize            n_fields,
    2315                         gpointer         user_data)
    2316  {
    2317  #ifdef ENABLE_JOURNAL_SENDV
    2318    const char equals = '=';
    2319    const char newline = '\n';
    2320    gsize i, k;
    2321    struct iovec *iov, *v;
    2322    char *buf;
    2323    gint retval;
    2324  
    2325    g_return_val_if_fail (fields != NULL, G_LOG_WRITER_UNHANDLED);
    2326    g_return_val_if_fail (n_fields > 0, G_LOG_WRITER_UNHANDLED);
    2327  
    2328    /* According to systemd.journal-fields(7), the journal allows fields in any
    2329     * format (including arbitrary binary), but expects text fields to be UTF-8.
    2330     * This is great, because we require input strings to be in UTF-8, so no
    2331     * conversion is necessary and we don’t need to care about the current
    2332     * locale’s character set.
    2333     */
    2334  
    2335    iov = g_alloca (sizeof (struct iovec) * 5 * n_fields);
    2336    buf = g_alloca (32 * n_fields);
    2337  
    2338    k = 0;
    2339    v = iov;
    2340    for (i = 0; i < n_fields; i++)
    2341      {
    2342        guint64 length;
    2343        gboolean binary;
    2344  
    2345        if (fields[i].length < 0)
    2346          {
    2347            length = strlen (fields[i].value);
    2348            binary = strchr (fields[i].value, '\n') != NULL;
    2349          }
    2350        else
    2351          {
    2352            length = fields[i].length;
    2353            binary = TRUE;
    2354          }
    2355  
    2356        if (binary)
    2357          {
    2358            guint64 nstr;
    2359  
    2360            v[0].iov_base = (gpointer)fields[i].key;
    2361            v[0].iov_len = strlen (fields[i].key);
    2362  
    2363            v[1].iov_base = (gpointer)&newline;
    2364            v[1].iov_len = 1;
    2365  
    2366            nstr = GUINT64_TO_LE(length);
    2367            memcpy (&buf[k], &nstr, sizeof (nstr));
    2368  
    2369            v[2].iov_base = &buf[k];
    2370            v[2].iov_len = sizeof (nstr);
    2371            v += 3;
    2372            k += sizeof (nstr);
    2373          }
    2374        else
    2375          {
    2376            v[0].iov_base = (gpointer)fields[i].key;
    2377            v[0].iov_len = strlen (fields[i].key);
    2378  
    2379            v[1].iov_base = (gpointer)&equals;
    2380            v[1].iov_len = 1;
    2381            v += 2;
    2382          }
    2383  
    2384        v[0].iov_base = (gpointer)fields[i].value;
    2385        v[0].iov_len = length;
    2386  
    2387        v[1].iov_base = (gpointer)&newline;
    2388        v[1].iov_len = 1;
    2389        v += 2;
    2390      }
    2391  
    2392    retval = journal_sendv (iov, v - iov);
    2393  
    2394    return retval == 0 ? G_LOG_WRITER_HANDLED : G_LOG_WRITER_UNHANDLED;
    2395  #else
    2396    return G_LOG_WRITER_UNHANDLED;
    2397  #endif /* ENABLE_JOURNAL_SENDV */
    2398  }
    2399  
    2400  /**
    2401   * g_log_writer_standard_streams:
    2402   * @log_level: log level, either from #GLogLevelFlags, or a user-defined
    2403   *    level
    2404   * @fields: (array length=n_fields): key–value pairs of structured data forming
    2405   *    the log message
    2406   * @n_fields: number of elements in the @fields array
    2407   * @user_data: user data passed to g_log_set_writer_func()
    2408   *
    2409   * Format a structured log message and print it to either `stdout` or `stderr`,
    2410   * depending on its log level. %G_LOG_LEVEL_INFO and %G_LOG_LEVEL_DEBUG messages
    2411   * are sent to `stdout`, or to `stderr` if requested by
    2412   * g_log_writer_default_set_use_stderr();
    2413   * all other log levels are sent to `stderr`. Only fields
    2414   * which are understood by this function are included in the formatted string
    2415   * which is printed.
    2416   *
    2417   * If the output stream supports ANSI color escape sequences, they will be used
    2418   * in the output.
    2419   *
    2420   * A trailing new-line character is added to the log message when it is printed.
    2421   *
    2422   * This is suitable for use as a #GLogWriterFunc.
    2423   *
    2424   * Returns: %G_LOG_WRITER_HANDLED on success, %G_LOG_WRITER_UNHANDLED otherwise
    2425   * Since: 2.50
    2426   */
    2427  GLogWriterOutput
    2428  g_log_writer_standard_streams (GLogLevelFlags   log_level,
    2429                                 const GLogField *fields,
    2430                                 gsize            n_fields,
    2431                                 gpointer         user_data)
    2432  {
    2433    FILE *stream;
    2434    gchar *out = NULL;  /* in the current locale’s character set */
    2435  
    2436    g_return_val_if_fail (fields != NULL, G_LOG_WRITER_UNHANDLED);
    2437    g_return_val_if_fail (n_fields > 0, G_LOG_WRITER_UNHANDLED);
    2438  
    2439    stream = log_level_to_file (log_level);
    2440    if (!stream || fileno (stream) < 0)
    2441      return G_LOG_WRITER_UNHANDLED;
    2442  
    2443    out = g_log_writer_format_fields (log_level, fields, n_fields,
    2444                                      g_log_writer_supports_color (fileno (stream)));
    2445    _g_fprintf (stream, "%s\n", out);
    2446    fflush (stream);
    2447    g_free (out);
    2448  
    2449    return G_LOG_WRITER_HANDLED;
    2450  }
    2451  
    2452  /* The old g_log() API is implemented in terms of the new structured log API.
    2453   * However, some of the checks do not line up between the two APIs: the
    2454   * structured API only handles fatalness of messages for log levels; the old API
    2455   * handles it per-domain as well. Consequently, we need to disable fatalness
    2456   * handling in the structured log API when called from the old g_log() API.
    2457   *
    2458   * We can guarantee that g_log_default_handler() will pass GLIB_OLD_LOG_API as
    2459   * the first field to g_log_structured_array(), if that is the case.
    2460   */
    2461  static gboolean
    2462  log_is_old_api (const GLogField *fields,
    2463                  gsize            n_fields)
    2464  {
    2465    return (n_fields >= 1 &&
    2466            g_strcmp0 (fields[0].key, "GLIB_OLD_LOG_API") == 0 &&
    2467            g_strcmp0 (fields[0].value, "1") == 0);
    2468  }
    2469  
    2470  static gboolean
    2471  domain_found (const gchar *domains,
    2472                const char  *log_domain)
    2473  {
    2474    guint len;
    2475    const gchar *found;
    2476  
    2477    len = strlen (log_domain);
    2478  
    2479    for (found = strstr (domains, log_domain); found;
    2480         found = strstr (found + 1, log_domain))
    2481      {
    2482        if ((found == domains || found[-1] == ' ')
    2483            && (found[len] == 0 || found[len] == ' '))
    2484          return TRUE;
    2485      }
    2486  
    2487    return FALSE;
    2488  }
    2489  
    2490  static struct {
    2491    GRWLock lock;
    2492    gchar *domains;
    2493    gboolean domains_set;
    2494  } g_log_global;
    2495  
    2496  /**
    2497   * g_log_writer_default_set_debug_domains:
    2498   * @domains: (nullable) (transfer none): `NULL`-terminated array with domains to be printed.
    2499   *   `NULL` or an array with no values means none. Array with a single value `"all"` means all.
    2500  
    2501   * Reset the list of domains to be logged, that might be initially set by the
    2502   * `G_MESSAGES_DEBUG` environment variable. This function is thread-safe.
    2503   *
    2504   * Since: 2.80
    2505   */
    2506  void
    2507  g_log_writer_default_set_debug_domains (const gchar * const *domains)
    2508  {
    2509    g_rw_lock_writer_lock (&g_log_global.lock);
    2510  
    2511    g_free (g_log_global.domains);
    2512    g_log_global.domains = domains ?
    2513        g_strjoinv (" ", (gchar **)domains) : NULL;
    2514  
    2515    g_log_global.domains_set = TRUE;
    2516  
    2517    g_rw_lock_writer_unlock (&g_log_global.lock);
    2518  }
    2519  
    2520  /*
    2521   * Internal version of g_log_writer_default_would_drop(), which can
    2522   * read from either a log_domain or an array of fields. This avoids
    2523   * having to iterate through the fields if the @log_level is sufficient
    2524   * to make the decision.
    2525   */
    2526  static gboolean
    2527  should_drop_message (GLogLevelFlags   log_level,
    2528                       const char      *log_domain,
    2529                       const GLogField *fields,
    2530                       gsize            n_fields)
    2531  {
    2532    /* Disable debug message output unless specified in G_MESSAGES_DEBUG. */
    2533    if (!(log_level & DEFAULT_LEVELS) &&
    2534        !(log_level >> G_LOG_LEVEL_USER_SHIFT) &&
    2535        !g_log_get_debug_enabled ())
    2536      {
    2537        gsize i;
    2538  
    2539        g_rw_lock_reader_lock (&g_log_global.lock);
    2540  
    2541        if (G_UNLIKELY (!g_log_global.domains_set))
    2542          {
    2543            g_log_global.domains = g_strdup (g_getenv ("G_MESSAGES_DEBUG"));
    2544            g_log_global.domains_set = TRUE;
    2545          }
    2546  
    2547        if ((log_level & INFO_LEVELS) == 0 ||
    2548            g_log_global.domains == NULL)
    2549          {
    2550            g_rw_lock_reader_unlock (&g_log_global.lock);
    2551            return TRUE;
    2552          }
    2553  
    2554        if (log_domain == NULL)
    2555          {
    2556            for (i = 0; i < n_fields; i++)
    2557              {
    2558                if (g_strcmp0 (fields[i].key, "GLIB_DOMAIN") == 0)
    2559                  {
    2560                    log_domain = fields[i].value;
    2561                    break;
    2562                  }
    2563              }
    2564          }
    2565  
    2566        if (strcmp (g_log_global.domains, "all") != 0 &&
    2567            (log_domain == NULL || !domain_found (g_log_global.domains, log_domain)))
    2568          {
    2569            g_rw_lock_reader_unlock (&g_log_global.lock);
    2570            return TRUE;
    2571          }
    2572  
    2573        g_rw_lock_reader_unlock (&g_log_global.lock);
    2574      }
    2575  
    2576    return FALSE;
    2577  }
    2578  
    2579  /**
    2580   * g_log_writer_default_would_drop:
    2581   * @log_domain: (nullable): log domain
    2582   * @log_level: log level, either from #GLogLevelFlags, or a user-defined
    2583   *    level
    2584   *
    2585   * Check whether g_log_writer_default() and g_log_default_handler() would
    2586   * ignore a message with the given domain and level.
    2587   *
    2588   * As with g_log_default_handler(), this function drops debug and informational
    2589   * messages unless their log domain (or `all`) is listed in the space-separated
    2590   * `G_MESSAGES_DEBUG` environment variable, or by g_log_writer_default_set_debug_domains().
    2591   *
    2592   * This can be used when implementing log writers with the same filtering
    2593   * behaviour as the default, but a different destination or output format:
    2594   *
    2595   * |[<!-- language="C" -->
    2596   *   if (g_log_writer_default_would_drop (log_level, log_domain))
    2597   *     return G_LOG_WRITER_HANDLED;
    2598   * ]|
    2599   *
    2600   * or to skip an expensive computation if it is only needed for a debugging
    2601   * message, and `G_MESSAGES_DEBUG` is not set:
    2602   *
    2603   * |[<!-- language="C" -->
    2604   *   if (!g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, G_LOG_DOMAIN))
    2605   *     {
    2606   *       gchar *result = expensive_computation (my_object);
    2607   *
    2608   *       g_debug ("my_object result: %s", result);
    2609   *       g_free (result);
    2610   *     }
    2611   * ]|
    2612   *
    2613   * Returns: %TRUE if the log message would be dropped by GLib's
    2614   *  default log handlers
    2615   * Since: 2.68
    2616   */
    2617  gboolean
    2618  g_log_writer_default_would_drop (GLogLevelFlags  log_level,
    2619                                   const char     *log_domain)
    2620  {
    2621    return should_drop_message (log_level, log_domain, NULL, 0);
    2622  }
    2623  
    2624  /**
    2625   * g_log_writer_default:
    2626   * @log_level: log level, either from #GLogLevelFlags, or a user-defined
    2627   *    level
    2628   * @fields: (array length=n_fields): key–value pairs of structured data forming
    2629   *    the log message
    2630   * @n_fields: number of elements in the @fields array
    2631   * @user_data: user data passed to g_log_set_writer_func()
    2632   *
    2633   * Format a structured log message and output it to the default log destination
    2634   * for the platform. On Linux, this is typically the systemd journal, falling
    2635   * back to `stdout` or `stderr` if running from the terminal or if output is
    2636   * being redirected to a file.
    2637   *
    2638   * Support for other platform-specific logging mechanisms may be added in
    2639   * future. Distributors of GLib may modify this function to impose their own
    2640   * (documented) platform-specific log writing policies.
    2641   *
    2642   * This is suitable for use as a #GLogWriterFunc, and is the default writer used
    2643   * if no other is set using g_log_set_writer_func().
    2644   *
    2645   * As with g_log_default_handler(), this function drops debug and informational
    2646   * messages unless their log domain (or `all`) is listed in the space-separated
    2647   * `G_MESSAGES_DEBUG` environment variable, or set at runtime by g_log_writer_default_set_debug_domains().
    2648   *
    2649   * g_log_writer_default() uses the mask set by g_log_set_always_fatal() to
    2650   * determine which messages are fatal. When using a custom writer func instead it is
    2651   * up to the writer function to determine which log messages are fatal.
    2652   *
    2653   * Returns: %G_LOG_WRITER_HANDLED on success, %G_LOG_WRITER_UNHANDLED otherwise
    2654   * Since: 2.50
    2655   */
    2656  GLogWriterOutput
    2657  g_log_writer_default (GLogLevelFlags   log_level,
    2658                        const GLogField *fields,
    2659                        gsize            n_fields,
    2660                        gpointer         user_data)
    2661  {
    2662    static gsize initialized = 0;
    2663    static gboolean stderr_is_journal = FALSE;
    2664  
    2665    g_return_val_if_fail (fields != NULL, G_LOG_WRITER_UNHANDLED);
    2666    g_return_val_if_fail (n_fields > 0, G_LOG_WRITER_UNHANDLED);
    2667  
    2668    if (should_drop_message (log_level, NULL, fields, n_fields))
    2669      return G_LOG_WRITER_HANDLED;
    2670  
    2671    /* Mark messages as fatal if they have a level set in
    2672     * g_log_set_always_fatal().
    2673     */
    2674    if ((log_level & g_log_always_fatal) && !log_is_old_api (fields, n_fields))
    2675      log_level |= G_LOG_FLAG_FATAL;
    2676  
    2677    /* Try logging to the systemd journal as first choice. */
    2678    if (g_once_init_enter (&initialized))
    2679      {
    2680        stderr_is_journal = g_log_writer_is_journald (fileno (stderr));
    2681        g_once_init_leave (&initialized, TRUE);
    2682      }
    2683  
    2684    if (stderr_is_journal &&
    2685        g_log_writer_journald (log_level, fields, n_fields, user_data) ==
    2686        G_LOG_WRITER_HANDLED)
    2687      goto handled;
    2688  
    2689    /* FIXME: Add support for the Windows log. */
    2690  
    2691    if (g_log_writer_standard_streams (log_level, fields, n_fields, user_data) ==
    2692        G_LOG_WRITER_HANDLED)
    2693      goto handled;
    2694  
    2695    return G_LOG_WRITER_UNHANDLED;
    2696  
    2697  handled:
    2698    /* Abort if the message was fatal. */
    2699    if (log_level & G_LOG_FLAG_FATAL)
    2700      {
    2701        /* MessageBox is allowed on UWP apps only when building against
    2702         * the debug CRT, which will set -D_DEBUG */
    2703  #if defined(G_OS_WIN32) && (defined(_DEBUG) || !defined(G_WINAPI_ONLY_APP))
    2704        if (!g_test_initialized ())
    2705          {
    2706            WCHAR *wide_msg;
    2707  
    2708            wide_msg = g_utf8_to_utf16 (fatal_msg_buf, -1, NULL, NULL, NULL);
    2709  
    2710            MessageBoxW (NULL, wide_msg, NULL, MB_ICONERROR | MB_SETFOREGROUND);
    2711  
    2712            g_free (wide_msg);
    2713          }
    2714  #endif /* !G_OS_WIN32 */
    2715  
    2716        _g_log_abort (!(log_level & G_LOG_FLAG_RECURSION));
    2717      }
    2718  
    2719    return G_LOG_WRITER_HANDLED;
    2720  }
    2721  
    2722  static GLogWriterOutput
    2723  _g_log_writer_fallback (GLogLevelFlags   log_level,
    2724                          const GLogField *fields,
    2725                          gsize            n_fields,
    2726                          gpointer         user_data)
    2727  {
    2728    FILE *stream;
    2729    gsize i;
    2730  
    2731    /* we cannot call _any_ GLib functions in this fallback handler,
    2732     * which is why we skip UTF-8 conversion, etc.
    2733     * since we either recursed or ran out of memory, we're in a pretty
    2734     * pathologic situation anyways, what we can do is giving the
    2735     * the process ID unconditionally however.
    2736     */
    2737  
    2738    stream = log_level_to_file (log_level);
    2739  
    2740    for (i = 0; i < n_fields; i++)
    2741      {
    2742        const GLogField *field = &fields[i];
    2743  
    2744        /* Only print fields we definitely recognise, otherwise we could end up
    2745         * printing a random non-string pointer provided by the user to be
    2746         * interpreted by their writer function.
    2747         */
    2748        if (strcmp (field->key, "MESSAGE") != 0 &&
    2749            strcmp (field->key, "MESSAGE_ID") != 0 &&
    2750            strcmp (field->key, "PRIORITY") != 0 &&
    2751            strcmp (field->key, "CODE_FILE") != 0 &&
    2752            strcmp (field->key, "CODE_LINE") != 0 &&
    2753            strcmp (field->key, "CODE_FUNC") != 0 &&
    2754            strcmp (field->key, "ERRNO") != 0 &&
    2755            strcmp (field->key, "SYSLOG_FACILITY") != 0 &&
    2756            strcmp (field->key, "SYSLOG_IDENTIFIER") != 0 &&
    2757            strcmp (field->key, "SYSLOG_PID") != 0 &&
    2758            strcmp (field->key, "GLIB_DOMAIN") != 0)
    2759          continue;
    2760  
    2761        write_string (stream, field->key);
    2762        write_string (stream, "=");
    2763        write_string_sized (stream, field->value, field->length);
    2764      }
    2765  
    2766  #ifndef G_OS_WIN32
    2767    {
    2768      gchar pid_string[FORMAT_UNSIGNED_BUFSIZE];
    2769  
    2770      format_unsigned (pid_string, getpid (), 10);
    2771      write_string (stream, "_PID=");
    2772      write_string (stream, pid_string);
    2773    }
    2774  #endif
    2775  
    2776    return G_LOG_WRITER_HANDLED;
    2777  }
    2778  
    2779  /**
    2780   * g_log_get_debug_enabled:
    2781   *
    2782   * Return whether debug output from the GLib logging system is enabled.
    2783   *
    2784   * Note that this should not be used to conditionalise calls to g_debug() or
    2785   * other logging functions; it should only be used from %GLogWriterFunc
    2786   * implementations.
    2787   *
    2788   * Note also that the value of this does not depend on `G_MESSAGES_DEBUG`, nor
    2789   * g_log_writer_default_set_debug_domains(); see the docs for g_log_set_debug_enabled().
    2790   *
    2791   * Returns: %TRUE if debug output is enabled, %FALSE otherwise
    2792   *
    2793   * Since: 2.72
    2794   */
    2795  gboolean
    2796  g_log_get_debug_enabled (void)
    2797  {
    2798    return g_atomic_int_get (&g_log_debug_enabled);
    2799  }
    2800  
    2801  /**
    2802   * g_log_set_debug_enabled:
    2803   * @enabled: %TRUE to enable debug output, %FALSE otherwise
    2804   *
    2805   * Enable or disable debug output from the GLib logging system for all domains.
    2806   * This value interacts disjunctively with `G_MESSAGES_DEBUG` and
    2807   * g_log_writer_default_set_debug_domains() — if any of them would allow
    2808   * a debug message to be outputted, it will be.
    2809   *
    2810   * Note that this should not be used from within library code to enable debug
    2811   * output — it is intended for external use.
    2812   *
    2813   * Since: 2.72
    2814   */
    2815  void
    2816  g_log_set_debug_enabled (gboolean enabled)
    2817  {
    2818    g_atomic_int_set (&g_log_debug_enabled, enabled);
    2819  }
    2820  
    2821  /**
    2822   * g_return_if_fail_warning: (skip)
    2823   * @log_domain: (nullable): log domain
    2824   * @pretty_function: function containing the assertion
    2825   * @expression: (nullable): expression which failed
    2826   *
    2827   * Internal function used to print messages from the public g_return_if_fail()
    2828   * and g_return_val_if_fail() macros.
    2829   */
    2830  void
    2831  g_return_if_fail_warning (const char *log_domain,
    2832  			  const char *pretty_function,
    2833  			  const char *expression)
    2834  {
    2835    g_log (log_domain,
    2836  	 G_LOG_LEVEL_CRITICAL,
    2837  	 "%s: assertion '%s' failed",
    2838  	 pretty_function,
    2839  	 expression);
    2840  }
    2841  
    2842  /**
    2843   * g_warn_message: (skip)
    2844   * @domain: (nullable): log domain
    2845   * @file: file containing the warning
    2846   * @line: line number of the warning
    2847   * @func: function containing the warning
    2848   * @warnexpr: (nullable): expression which failed
    2849   *
    2850   * Internal function used to print messages from the public g_warn_if_reached()
    2851   * and g_warn_if_fail() macros.
    2852   */
    2853  void
    2854  g_warn_message (const char     *domain,
    2855                  const char     *file,
    2856                  int             line,
    2857                  const char     *func,
    2858                  const char     *warnexpr)
    2859  {
    2860    char *s, lstr[32];
    2861    g_snprintf (lstr, 32, "%d", line);
    2862    if (warnexpr)
    2863      s = g_strconcat ("(", file, ":", lstr, "):",
    2864                       func, func[0] ? ":" : "",
    2865                       " runtime check failed: (", warnexpr, ")", NULL);
    2866    else
    2867      s = g_strconcat ("(", file, ":", lstr, "):",
    2868                       func, func[0] ? ":" : "",
    2869                       " ", "code should not be reached", NULL);
    2870    g_log (domain, G_LOG_LEVEL_WARNING, "%s", s);
    2871    g_free (s);
    2872  }
    2873  
    2874  void
    2875  g_assert_warning (const char *log_domain,
    2876  		  const char *file,
    2877  		  const int   line,
    2878  		  const char *pretty_function,
    2879  		  const char *expression)
    2880  {
    2881    if (expression)
    2882      g_log (log_domain,
    2883  	   G_LOG_LEVEL_ERROR,
    2884  	   "file %s: line %d (%s): assertion failed: (%s)",
    2885  	   file,
    2886  	   line,
    2887  	   pretty_function,
    2888  	   expression);
    2889    else
    2890      g_log (log_domain,
    2891  	   G_LOG_LEVEL_ERROR,
    2892  	   "file %s: line %d (%s): should not be reached",
    2893  	   file,
    2894  	   line,
    2895  	   pretty_function);
    2896    _g_log_abort (FALSE);
    2897    g_abort ();
    2898  }
    2899  
    2900  /**
    2901   * g_test_expect_message:
    2902   * @log_domain: (nullable): the log domain of the message
    2903   * @log_level: the log level of the message
    2904   * @pattern: a glob-style [pattern][glib-Glob-style-pattern-matching]
    2905   *
    2906   * Indicates that a message with the given @log_domain and @log_level,
    2907   * with text matching @pattern, is expected to be logged. When this
    2908   * message is logged, it will not be printed, and the test case will
    2909   * not abort.
    2910   *
    2911   * This API may only be used with the old logging API (g_log() without
    2912   * %G_LOG_USE_STRUCTURED defined). It will not work with the structured logging
    2913   * API. See [Testing for Messages][testing-for-messages].
    2914   *
    2915   * Use g_test_assert_expected_messages() to assert that all
    2916   * previously-expected messages have been seen and suppressed.
    2917   *
    2918   * You can call this multiple times in a row, if multiple messages are
    2919   * expected as a result of a single call. (The messages must appear in
    2920   * the same order as the calls to g_test_expect_message().)
    2921   *
    2922   * For example:
    2923   *
    2924   * |[<!-- language="C" --> 
    2925   *   // g_main_context_push_thread_default() should fail if the
    2926   *   // context is already owned by another thread.
    2927   *   g_test_expect_message (G_LOG_DOMAIN,
    2928   *                          G_LOG_LEVEL_CRITICAL,
    2929   *                          "assertion*acquired_context*failed");
    2930   *   g_main_context_push_thread_default (bad_context);
    2931   *   g_test_assert_expected_messages ();
    2932   * ]|
    2933   *
    2934   * Note that you cannot use this to test g_error() messages, since
    2935   * g_error() intentionally never returns even if the program doesn't
    2936   * abort; use g_test_trap_subprocess() in this case.
    2937   *
    2938   * If messages at %G_LOG_LEVEL_DEBUG are emitted, but not explicitly
    2939   * expected via g_test_expect_message() then they will be ignored.
    2940   *
    2941   * Since: 2.34
    2942   */
    2943  void
    2944  g_test_expect_message (const gchar    *log_domain,
    2945                         GLogLevelFlags  log_level,
    2946                         const gchar    *pattern)
    2947  {
    2948    GTestExpectedMessage *expected;
    2949  
    2950    g_return_if_fail (log_level != 0);
    2951    g_return_if_fail (pattern != NULL);
    2952    g_return_if_fail (~log_level & G_LOG_LEVEL_ERROR);
    2953  
    2954    expected = g_new (GTestExpectedMessage, 1);
    2955    expected->log_domain = g_strdup (log_domain);
    2956    expected->log_level = log_level;
    2957    expected->pattern = g_strdup (pattern);
    2958  
    2959    expected_messages = g_slist_append (expected_messages, expected);
    2960  }
    2961  
    2962  void
    2963  g_test_assert_expected_messages_internal (const char     *domain,
    2964                                            const char     *file,
    2965                                            int             line,
    2966                                            const char     *func)
    2967  {
    2968    if (expected_messages)
    2969      {
    2970        GTestExpectedMessage *expected;
    2971        gchar level_prefix[STRING_BUFFER_SIZE];
    2972        gchar *message;
    2973  
    2974        expected = expected_messages->data;
    2975  
    2976        mklevel_prefix (level_prefix, expected->log_level, FALSE);
    2977        message = g_strdup_printf ("Did not see expected message %s-%s: %s",
    2978                                   expected->log_domain ? expected->log_domain : "**",
    2979                                   level_prefix, expected->pattern);
    2980        g_assertion_message (G_LOG_DOMAIN, file, line, func, message);
    2981        g_free (message);
    2982      }
    2983  }
    2984  
    2985  /**
    2986   * g_test_assert_expected_messages:
    2987   *
    2988   * Asserts that all messages previously indicated via
    2989   * g_test_expect_message() have been seen and suppressed.
    2990   *
    2991   * This API may only be used with the old logging API (g_log() without
    2992   * %G_LOG_USE_STRUCTURED defined). It will not work with the structured logging
    2993   * API. See [Testing for Messages][testing-for-messages].
    2994   *
    2995   * If messages at %G_LOG_LEVEL_DEBUG are emitted, but not explicitly
    2996   * expected via g_test_expect_message() then they will be ignored.
    2997   *
    2998   * Since: 2.34
    2999   */
    3000  
    3001  void
    3002  _g_log_fallback_handler (const gchar   *log_domain,
    3003  			 GLogLevelFlags log_level,
    3004  			 const gchar   *message,
    3005  			 gpointer       unused_data)
    3006  {
    3007    gchar level_prefix[STRING_BUFFER_SIZE];
    3008  #ifndef G_OS_WIN32
    3009    gchar pid_string[FORMAT_UNSIGNED_BUFSIZE];
    3010  #endif
    3011    FILE *stream;
    3012  
    3013    /* we cannot call _any_ GLib functions in this fallback handler,
    3014     * which is why we skip UTF-8 conversion, etc.
    3015     * since we either recursed or ran out of memory, we're in a pretty
    3016     * pathologic situation anyways, what we can do is giving the
    3017     * the process ID unconditionally however.
    3018     */
    3019  
    3020    stream = mklevel_prefix (level_prefix, log_level, FALSE);
    3021    if (!message)
    3022      message = "(NULL) message";
    3023  
    3024  #ifndef G_OS_WIN32
    3025    format_unsigned (pid_string, getpid (), 10);
    3026  #endif
    3027  
    3028    if (log_domain)
    3029      write_string (stream, "\n");
    3030    else
    3031      write_string (stream, "\n** ");
    3032  
    3033  #ifndef G_OS_WIN32
    3034    write_string (stream, "(process:");
    3035    write_string (stream, pid_string);
    3036    write_string (stream, "): ");
    3037  #endif
    3038  
    3039    if (log_domain)
    3040      {
    3041        write_string (stream, log_domain);
    3042        write_string (stream, "-");
    3043      }
    3044    write_string (stream, level_prefix);
    3045    write_string (stream, ": ");
    3046    write_string (stream, message);
    3047    write_string (stream, "\n");
    3048  }
    3049  
    3050  static void
    3051  escape_string (GString *string)
    3052  {
    3053    const char *p = string->str;
    3054    gunichar wc;
    3055  
    3056    while (p < string->str + string->len)
    3057      {
    3058        gboolean safe;
    3059  	    
    3060        wc = g_utf8_get_char_validated (p, -1);
    3061        if (wc == (gunichar)-1 || wc == (gunichar)-2)  
    3062  	{
    3063  	  gchar *tmp;
    3064  	  guint pos;
    3065  
    3066  	  pos = p - string->str;
    3067  
    3068  	  /* Emit invalid UTF-8 as hex escapes 
    3069             */
    3070  	  tmp = g_strdup_printf ("\\x%02x", (guint)(guchar)*p);
    3071  	  g_string_erase (string, pos, 1);
    3072  	  g_string_insert (string, pos, tmp);
    3073  
    3074  	  p = string->str + (pos + 4); /* Skip over escape sequence */
    3075  
    3076  	  g_free (tmp);
    3077  	  continue;
    3078  	}
    3079        if (wc == '\r')
    3080  	{
    3081  	  safe = *(p + 1) == '\n';
    3082  	}
    3083        else
    3084  	{
    3085  	  safe = CHAR_IS_SAFE (wc);
    3086  	}
    3087        
    3088        if (!safe)
    3089  	{
    3090  	  gchar *tmp;
    3091  	  guint pos;
    3092  
    3093  	  pos = p - string->str;
    3094  	  
    3095  	  /* Largest char we escape is 0x0a, so we don't have to worry
    3096  	   * about 8-digit \Uxxxxyyyy
    3097  	   */
    3098  	  tmp = g_strdup_printf ("\\u%04x", wc); 
    3099  	  g_string_erase (string, pos, g_utf8_next_char (p) - p);
    3100  	  g_string_insert (string, pos, tmp);
    3101  	  g_free (tmp);
    3102  
    3103  	  p = string->str + (pos + 6); /* Skip over escape sequence */
    3104  	}
    3105        else
    3106  	p = g_utf8_next_char (p);
    3107      }
    3108  }
    3109  
    3110  /**
    3111   * g_log_default_handler:
    3112   * @log_domain: (nullable): the log domain of the message, or %NULL for the
    3113   * default "" application domain
    3114   * @log_level: the level of the message
    3115   * @message: (nullable): the message
    3116   * @unused_data: (nullable): data passed from g_log() which is unused
    3117   *
    3118   * The default log handler set up by GLib; g_log_set_default_handler()
    3119   * allows to install an alternate default log handler.
    3120   * This is used if no log handler has been set for the particular log
    3121   * domain and log level combination. It outputs the message to stderr
    3122   * or stdout and if the log level is fatal it calls G_BREAKPOINT(). It automatically
    3123   * prints a new-line character after the message, so one does not need to be
    3124   * manually included in @message.
    3125   *
    3126   * The behavior of this log handler can be influenced by a number of
    3127   * environment variables:
    3128   *
    3129   * - `G_MESSAGES_PREFIXED`: A :-separated list of log levels for which
    3130   *   messages should be prefixed by the program name and PID of the
    3131   *   application.
    3132   *
    3133   * - `G_MESSAGES_DEBUG`: A space-separated list of log domains for
    3134   *   which debug and informational messages are printed. By default
    3135   *   these messages are not printed. If you need to set the allowed
    3136   *   domains at runtime, use g_log_writer_default_set_debug_domains().
    3137   *
    3138   * stderr is used for levels %G_LOG_LEVEL_ERROR, %G_LOG_LEVEL_CRITICAL,
    3139   * %G_LOG_LEVEL_WARNING and %G_LOG_LEVEL_MESSAGE. stdout is used for
    3140   * the rest, unless stderr was requested by
    3141   * g_log_writer_default_set_use_stderr().
    3142   *
    3143   * This has no effect if structured logging is enabled; see
    3144   * [Using Structured Logging][using-structured-logging].
    3145   */
    3146  void
    3147  g_log_default_handler (const gchar   *log_domain,
    3148  		       GLogLevelFlags log_level,
    3149  		       const gchar   *message,
    3150  		       gpointer	      unused_data)
    3151  {
    3152    GLogField fields[4];
    3153    int n_fields = 0;
    3154  
    3155    /* we can be called externally with recursion for whatever reason */
    3156    if (log_level & G_LOG_FLAG_RECURSION)
    3157      {
    3158        _g_log_fallback_handler (log_domain, log_level, message, unused_data);
    3159        return;
    3160      }
    3161  
    3162    fields[0].key = "GLIB_OLD_LOG_API";
    3163    fields[0].value = "1";
    3164    fields[0].length = -1;
    3165    n_fields++;
    3166  
    3167    fields[1].key = "MESSAGE";
    3168    fields[1].value = message;
    3169    fields[1].length = -1;
    3170    n_fields++;
    3171  
    3172    fields[2].key = "PRIORITY";
    3173    fields[2].value = log_level_to_priority (log_level);
    3174    fields[2].length = -1;
    3175    n_fields++;
    3176  
    3177    if (log_domain)
    3178      {
    3179        fields[3].key = "GLIB_DOMAIN";
    3180        fields[3].value = log_domain;
    3181        fields[3].length = -1;
    3182        n_fields++;
    3183      }
    3184  
    3185    /* Print out via the structured log API, but drop any fatal flags since we
    3186     * have already handled them. The fatal handling in the structured logging
    3187     * API is more coarse-grained than in the old g_log() API, so we don't want
    3188     * to use it here.
    3189     */
    3190    g_log_structured_array (log_level & ~G_LOG_FLAG_FATAL, fields, n_fields);
    3191  }
    3192  
    3193  /**
    3194   * g_set_print_handler:
    3195   * @func: (nullable): the new print handler or %NULL to
    3196   *   reset to the default
    3197   *
    3198   * Sets the print handler to @func, or resets it to the
    3199   * default GLib handler if %NULL.
    3200   *
    3201   * Any messages passed to g_print() will be output via
    3202   * the new handler. The default handler outputs
    3203   * the encoded message to stdout. By providing your own handler
    3204   * you can redirect the output, to a GTK widget or a
    3205   * log file for example.
    3206   *
    3207   * Since 2.76 this functions always returns a valid
    3208   * #GPrintFunc, and never returns %NULL. If no custom
    3209   * print handler was set, it will return the GLib
    3210   * default print handler and that can be re-used to
    3211   * decorate its output and/or to write to stderr
    3212   * in all platforms. Before GLib 2.76, this was %NULL.
    3213   *
    3214   * Returns: (not nullable): the old print handler
    3215   */
    3216  GPrintFunc
    3217  g_set_print_handler (GPrintFunc func)
    3218  {
    3219    return g_atomic_pointer_exchange (&glib_print_func,
    3220                                      func ? func : g_default_print_func);
    3221  }
    3222  
    3223  static void
    3224  print_string (FILE        *stream,
    3225                const gchar *string)
    3226  {
    3227    const gchar *charset;
    3228    int ret;
    3229  
    3230    if (g_get_console_charset (&charset))
    3231      {
    3232        /* charset is UTF-8 already */
    3233        ret = fputs (string, stream);
    3234      }
    3235    else
    3236      {
    3237        gchar *converted_string = strdup_convert (string, charset);
    3238  
    3239        ret = fputs (converted_string, stream);
    3240        g_free (converted_string);
    3241      }
    3242  
    3243    /* In case of failure we can just return early, but there's nothing else
    3244     * we can do at this level
    3245     */
    3246    if (ret == EOF)
    3247      return;
    3248  
    3249    fflush (stream);
    3250  }
    3251  
    3252  G_ALWAYS_INLINE static inline const char *
    3253  format_string (const char *format,
    3254                 va_list     args,
    3255                 char      **out_allocated_string)
    3256  {
    3257  #ifdef G_ENABLE_DEBUG
    3258    g_assert (out_allocated_string != NULL);
    3259  #endif
    3260  
    3261    /* If there is no formatting to be done, avoid an allocation */
    3262    if (strchr (format, '%') == NULL)
    3263      {
    3264        *out_allocated_string = NULL;
    3265        return format;
    3266      }
    3267    else
    3268      {
    3269        *out_allocated_string = g_strdup_vprintf (format, args);
    3270        return *out_allocated_string;
    3271      }
    3272  }
    3273  
    3274  static void
    3275  g_default_print_func (const gchar *string)
    3276  {
    3277    print_string (stdout, string);
    3278  }
    3279  
    3280  static void
    3281  g_default_printerr_func (const gchar *string)
    3282  {
    3283    print_string (stderr, string);
    3284  }
    3285  
    3286  /**
    3287   * g_print:
    3288   * @format: the message format. See the printf() documentation
    3289   * @...: the parameters to insert into the format string
    3290   *
    3291   * Outputs a formatted message via the print handler.
    3292   * The default print handler outputs the encoded message to stdout, without
    3293   * appending a trailing new-line character. Typically, @format should end with
    3294   * its own new-line character.
    3295   *
    3296   * g_print() should not be used from within libraries for debugging
    3297   * messages, since it may be redirected by applications to special
    3298   * purpose message windows or even files. Instead, libraries should
    3299   * use g_log(), g_log_structured(), or the convenience macros g_message(),
    3300   * g_warning() and g_error().
    3301   */
    3302  void
    3303  g_print (const gchar *format,
    3304           ...)
    3305  {
    3306    va_list args;
    3307    const gchar *string;
    3308    gchar *free_me = NULL;
    3309    GPrintFunc local_glib_print_func;
    3310  
    3311    g_return_if_fail (format != NULL);
    3312  
    3313    va_start (args, format);
    3314    string = format_string (format, args, &free_me);
    3315    va_end (args);
    3316  
    3317    local_glib_print_func = g_atomic_pointer_get (&glib_print_func);
    3318    local_glib_print_func (string);
    3319    g_free (free_me);
    3320  }
    3321  
    3322  /**
    3323   * g_set_printerr_handler:
    3324   * @func: (nullable): he new error message handler or %NULL
    3325   *  to reset to the default
    3326   *
    3327   * Sets the handler for printing error messages to @func,
    3328   * or resets it to the default GLib handler if %NULL.
    3329   *
    3330   * Any messages passed to g_printerr() will be output via
    3331   * the new handler. The default handler outputs the encoded
    3332   * message to stderr. By providing your own handler you can
    3333   * redirect the output, to a GTK widget or a log file for
    3334   * example.
    3335   *
    3336   * Since 2.76 this functions always returns a valid
    3337   * #GPrintFunc, and never returns %NULL. If no custom error
    3338   * print handler was set, it will return the GLib default
    3339   * error print handler and that can be re-used to decorate
    3340   * its output and/or to write to stderr in all platforms.
    3341   * Before GLib 2.76, this was %NULL.
    3342   *
    3343   * Returns: (not nullable): the old error message handler
    3344   */
    3345  GPrintFunc
    3346  g_set_printerr_handler (GPrintFunc func)
    3347  {
    3348    return g_atomic_pointer_exchange (&glib_printerr_func,
    3349                                      func ? func : g_default_printerr_func);
    3350  }
    3351  
    3352  /**
    3353   * g_printerr:
    3354   * @format: the message format. See the printf() documentation
    3355   * @...: the parameters to insert into the format string
    3356   *
    3357   * Outputs a formatted message via the error message handler.
    3358   * The default handler outputs the encoded message to stderr, without appending
    3359   * a trailing new-line character. Typically, @format should end with its own
    3360   * new-line character.
    3361   *
    3362   * g_printerr() should not be used from within libraries.
    3363   * Instead g_log() or g_log_structured() should be used, or the convenience
    3364   * macros g_message(), g_warning() and g_error().
    3365   */
    3366  void
    3367  g_printerr (const gchar *format,
    3368              ...)
    3369  {
    3370    va_list args;
    3371    const char *string;
    3372    char *free_me = NULL;
    3373    GPrintFunc local_glib_printerr_func;
    3374  
    3375    g_return_if_fail (format != NULL);
    3376  
    3377    va_start (args, format);
    3378    string = format_string (format, args, &free_me);
    3379    va_end (args);
    3380  
    3381    local_glib_printerr_func = g_atomic_pointer_get (&glib_printerr_func);
    3382    local_glib_printerr_func (string);
    3383    g_free (free_me);
    3384  }
    3385  
    3386  /**
    3387   * g_printf_string_upper_bound:
    3388   * @format: the format string. See the printf() documentation
    3389   * @args: the parameters to be inserted into the format string
    3390   *
    3391   * Calculates the maximum space needed to store the output
    3392   * of the sprintf() function.
    3393   *
    3394   * If @format or @args are invalid, `0` is returned. This could happen if, for
    3395   * example, @format contains an `%lc` or `%ls` placeholder and @args contains a
    3396   * wide character which cannot be represented in multibyte encoding. `0`
    3397   * can also be returned legitimately if, for example, @format is `%s` and @args
    3398   * is an empty string. The caller is responsible for differentiating these two
    3399   * return cases if necessary. It is recommended to not use `%lc` or `%ls`
    3400   * placeholders in any case, as their behaviour is locale-dependent.
    3401   *
    3402   * Returns: the maximum space needed to store the formatted string, or `0` on error
    3403   */
    3404  gsize
    3405  g_printf_string_upper_bound (const gchar *format,
    3406                               va_list      args)
    3407  {
    3408    gchar c;
    3409    int count = _g_vsnprintf (&c, 1, format, args);
    3410  
    3411    if (count < 0)
    3412      return 0;
    3413  
    3414    return count + 1;
    3415  }