Coverage Report

Created: 2025-12-14 06:30

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