Coverage Report

Created: 2025-08-28 06:48

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