Merge "Fix crashes in various GParamSpec creation functions" into tizen
[platform/upstream/glib.git] / glib / glib-private.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 2011 Red Hat, Inc.
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  * Author: Colin Walters <walters@verbum.org>
20  */
21
22 #include "config.h"
23
24 #include "glib-private.h"
25 #include "glib-init.h"
26
27 #ifdef USE_INVALID_PARAMETER_HANDLER
28 #include <crtdbg.h>
29 #endif
30
31 /**
32  * glib__private__:
33  * @arg: Do not use this argument
34  *
35  * Do not call this function; it is used to share private
36  * API between glib, gobject, and gio.
37  */
38 GLibPrivateVTable *
39 glib__private__ (void)
40 {
41   static GLibPrivateVTable table = {
42     g_wakeup_new,
43     g_wakeup_free,
44     g_wakeup_get_pollfd,
45     g_wakeup_signal,
46     g_wakeup_acknowledge,
47
48     g_get_worker_context,
49
50     g_check_setuid,
51     g_main_context_new_with_next_id,
52
53     g_dir_open_with_errno,
54     g_dir_new_from_dirp,
55
56     glib_init,
57
58 #ifdef G_OS_WIN32
59     g_win32_stat_utf8,
60     g_win32_lstat_utf8,
61     g_win32_readlink_utf8,
62     g_win32_fstat,
63     g_win32_find_helper_executable_path,
64     g_win32_reopen_noninherited,
65     g_win32_handle_is_socket,
66 #endif
67
68     g_win32_push_empty_invalid_parameter_handler,
69     g_win32_pop_invalid_parameter_handler,
70
71     g_find_program_for_path,
72
73     g_uri_get_default_scheme_port,
74   };
75
76   return &table;
77 }
78
79 #ifdef USE_INVALID_PARAMETER_HANDLER
80 /*
81  * This is the (empty) invalid parameter handler
82  * that is used for Visual C++ 2005 (and later) builds
83  * so that we can use this instead of the system automatically
84  * aborting the process, when calling _get_osfhandle(), isatty()
85  * and _commit() (via g_fsync()) and so on with an invalid file
86  * descriptor.
87  *
88  * This is necessary so that the gspawn helper and the test programs
89  * will continue to run as expected, since we are purposely or
90  * forced to use invalid FDs.
91  *
92  * Please see https://learn.microsoft.com/en-us/cpp/c-runtime-library/parameter-validation?view=msvc-170
93  * for an explanation on this.
94  */
95 static void
96 empty_invalid_parameter_handler (const wchar_t *expression,
97                                  const wchar_t *function,
98                                  const wchar_t *file,
99                                  unsigned int   line,
100                                  uintptr_t      pReserved)
101 {
102 }
103
104 /* fallback to _set_invalid_parameter_handler() if we don't have _set_thread_local_invalid_parameter_handler() */
105 #ifndef HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER
106 # define _set_thread_local_invalid_parameter_handler _set_invalid_parameter_handler
107 #endif
108
109 #endif
110 /*
111  * g_win32_push_empty_invalid_parameter_handler:
112  * @handler: a possibly uninitialized GWin32InvalidParameterHandler
113  */
114 void
115 g_win32_push_empty_invalid_parameter_handler (GWin32InvalidParameterHandler *handler)
116 {
117 #ifdef USE_INVALID_PARAMETER_HANDLER
118   /* use the empty invalid parameter handler to override the default invalid parameter_handler */
119   handler->pushed_handler = empty_invalid_parameter_handler;
120   handler->old_handler = _set_thread_local_invalid_parameter_handler (handler->pushed_handler);
121
122   /* Disable the message box for assertions. */
123   handler->pushed_report_mode = 0;
124   handler->prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, handler->pushed_report_mode);
125 #endif
126 }
127
128 /*
129  * g_win32_pop_invalid_parameter_handler:
130  * @handler: a GWin32InvalidParameterHandler processed with
131  * g_win32_push_empty_invalid_parameter_handler()
132  */
133 void
134 g_win32_pop_invalid_parameter_handler (GWin32InvalidParameterHandler *handler)
135 {
136 #ifdef USE_INVALID_PARAMETER_HANDLER
137   G_GNUC_UNUSED _invalid_parameter_handler popped_handler;
138   G_GNUC_UNUSED int popped_report_mode;
139
140   /* Restore previous/default invalid parameter handler, check the value returned matches the one we previously pushed */
141   popped_handler = _set_thread_local_invalid_parameter_handler (handler->old_handler);
142   g_return_if_fail (handler->pushed_handler == popped_handler);
143
144   /* Restore the message box for assertions, check the value returned matches the one we previously pushed */
145   popped_report_mode = _CrtSetReportMode(_CRT_ASSERT, handler->prev_report_mode);
146   g_return_if_fail (handler->pushed_report_mode == popped_report_mode);
147 #endif
148 }