/* 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 . * * Author: Colin Walters */ #include "config.h" #include "glib-private.h" #include "glib-init.h" #ifdef USE_INVALID_PARAMETER_HANDLER #include #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. */ GLibPrivateVTable * glib__private__ (void) { static 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, }; 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 }