Coverage Report

Created: 2025-12-28 06:39

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