Coverage Report

Created: 2026-09-14 06:25

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