blob: 15dbc665c5c2260ea7c09917947110e4621e0fb7 [file] [log] [blame]
/* GLIB - Library of useful routines for C programming
* Copyright (C) 2011 Red Hat, Inc.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Colin Walters <walters@verbum.org>
*/
#include "config.h"
#include "glib-private.h"
#include "glib-init.h"
#include "gutilsprivate.h"
#include "gdatasetprivate.h"
#ifdef USE_INVALID_PARAMETER_HANDLER
#include <crtdbg.h>
#endif
/**
* glib__private__:
* @arg: Do not use this argument
*
* Do not call this function; it is used to share private
* API between glib, gobject, and gio.
*/
const GLibPrivateVTable *
glib__private__ (void)
{
static const GLibPrivateVTable table = {
g_wakeup_new,
g_wakeup_free,
g_wakeup_get_pollfd,
g_wakeup_signal,
g_wakeup_acknowledge,
g_get_worker_context,
g_check_setuid,
g_main_context_new_with_next_id,
g_dir_open_with_errno,
g_dir_new_from_dirp,
glib_init,
#ifdef G_OS_WIN32
g_win32_stat_utf8,
g_win32_lstat_utf8,
g_win32_readlink_utf8,
g_win32_fstat,
g_win32_find_helper_executable_path,
g_win32_reopen_noninherited,
g_win32_handle_is_socket,
#endif
g_win32_push_empty_invalid_parameter_handler,
g_win32_pop_invalid_parameter_handler,
g_find_program_for_path,
g_uri_get_default_scheme_port,
g_set_prgname_once,
g_datalist_id_update_atomic,
};
return &table;
}
#ifdef USE_INVALID_PARAMETER_HANDLER
/*
* This is the (empty) invalid parameter handler
* that is used for Visual C++ 2005 (and later) builds
* so that we can use this instead of the system automatically
* aborting the process, when calling _get_osfhandle(), isatty()
* and _commit() (via g_fsync()) and so on with an invalid file
* descriptor.
*
* This is necessary so that the gspawn helper and the test programs
* will continue to run as expected, since we are purposely or
* forced to use invalid FDs.
*
* Please see https://learn.microsoft.com/en-us/cpp/c-runtime-library/parameter-validation?view=msvc-170
* for an explanation on this.
*/
static void
empty_invalid_parameter_handler (const wchar_t *expression,
const wchar_t *function,
const wchar_t *file,
unsigned int line,
uintptr_t pReserved)
{
}
/* fallback to _set_invalid_parameter_handler() if we don't have _set_thread_local_invalid_parameter_handler() */
#ifndef HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER
# define _set_thread_local_invalid_parameter_handler _set_invalid_parameter_handler
#endif
#endif
/*
* g_win32_push_empty_invalid_parameter_handler:
* @handler: a possibly uninitialized GWin32InvalidParameterHandler
*/
void
g_win32_push_empty_invalid_parameter_handler (GWin32InvalidParameterHandler *handler)
{
#ifdef USE_INVALID_PARAMETER_HANDLER
/* use the empty invalid parameter handler to override the default invalid parameter_handler */
handler->pushed_handler = empty_invalid_parameter_handler;
handler->old_handler = _set_thread_local_invalid_parameter_handler (handler->pushed_handler);
/* Disable the message box for assertions. */
handler->pushed_report_mode = 0;
handler->prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, handler->pushed_report_mode);
#endif
}
/*
* g_win32_pop_invalid_parameter_handler:
* @handler: a GWin32InvalidParameterHandler processed with
* g_win32_push_empty_invalid_parameter_handler()
*/
void
g_win32_pop_invalid_parameter_handler (GWin32InvalidParameterHandler *handler)
{
#ifdef USE_INVALID_PARAMETER_HANDLER
G_GNUC_UNUSED _invalid_parameter_handler popped_handler;
G_GNUC_UNUSED int popped_report_mode;
/* Restore previous/default invalid parameter handler, check the value returned matches the one we previously pushed */
popped_handler = _set_thread_local_invalid_parameter_handler (handler->old_handler);
g_return_if_fail (handler->pushed_handler == popped_handler);
/* Restore the message box for assertions, check the value returned matches the one we previously pushed */
popped_report_mode = _CrtSetReportMode(_CRT_ASSERT, handler->prev_report_mode);
g_return_if_fail (handler->pushed_report_mode == popped_report_mode);
#endif
}