2011-09-01 14:32:11 -04:00
|
|
|
/* glib-private.h - GLib-internal private API, shared between glib, gobject, gio
|
|
|
|
* Copyright (C) 2011 Red Hat, Inc.
|
|
|
|
*
|
2022-05-18 09:15:38 +01:00
|
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
*
|
2011-09-01 14:32:11 -04:00
|
|
|
* This library is free software; you can redistribute it and/or
|
2017-01-05 12:47:07 +01:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
2011-09-01 14:32:11 -04:00
|
|
|
* License as published by the Free Software Foundation; either
|
2017-01-05 12:47:07 +01:00
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2011-09-01 14:32:11 -04:00
|
|
|
*
|
|
|
|
* 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
|
2017-01-05 12:47:07 +01:00
|
|
|
* Lesser General Public License for more details.
|
2011-09-01 14:32:11 -04:00
|
|
|
*
|
2017-01-05 12:47:07 +01:00
|
|
|
* 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/>.
|
2011-09-01 14:32:11 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __GLIB_PRIVATE_H__
|
|
|
|
#define __GLIB_PRIVATE_H__
|
|
|
|
|
2011-09-09 16:05:55 -04:00
|
|
|
#include <glib.h>
|
2011-09-01 14:32:11 -04:00
|
|
|
#include "gwakeup.h"
|
W32: Add a stat() implementation for private use
This commit adds new W32-only functions to gstdio.c,
and a new header file, gstdioprivate.h.
These functions are:
g_win32_stat_utf8()
g_win32_lstat_utf8()
g_win32_fstat()
and they fill a private structure, GWin32PrivateStat,
which has all the fields that normal stat has, as well as some
extras.
These functions are then used throughout glib and gio to get better
data about the system. Specifically:
* Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size)
* Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is)
* W32 File attributes (which stat() doesn't report); in particular, this allows
symlinks to be correctly identified
* Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows)
* Allocated file size (as a W32 replacement for the missing st_blocks)
st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to
glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8),
this field does not contain anything unexpected.
g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to.
Also adds the g_win32_readlink_utf8() function, which behaves like readlink()
(including its inability to return 0-terminated strings and inability to say how large
the output buffer should be; these limitations are purely for compatibility with
existing glib code).
Thus, symlink support should now be much better, although far from being complete.
A new W32-only test in gio/tests/file.c highlights the following features:
* allocated size
* 64-bit time
* unique file IDs
https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 10:14:41 +00:00
|
|
|
#include "gstdioprivate.h"
|
glib: add internal g_datalist_id_update_atomic() function
GDataSet is mainly used by GObject. Usually, when we access the private
data there, we already hold another lock around the GObject.
For example, before accessing quark_toggle_refs, we take a
OPTIONAL_BIT_LOCK_TOGGLE_REFS lock. That makes sense, because we anyway
need to protect access to the ToggleRefStack. By holding such an
external mutex around several GData operations, we achieve atomic
updates.
However, there is a (performance) use case to update the qdata
atomically, without such additional lock. The GData already holds a lock
while updating the data. Add a new g_datalist_id_update_atomic()
function, that can invoke a callback while holding that lock.
This will be used by GObject. The benefit is that we can access the
GData atomically, without requiring another mutex around it.
For example, a common pattern is to request some GData entry, and if
it's not yet allocated, to allocate it. This requires to take the GData
bitlock twice. With this API, the callback can allocate the data if no
entry exists yet.
2024-01-12 20:46:27 +01:00
|
|
|
#include "gdatasetprivate.h"
|
2011-09-01 14:32:11 -04:00
|
|
|
|
2024-05-15 12:51:48 +01:00
|
|
|
/*
|
|
|
|
* G_SIGNEDNESS_OF:
|
|
|
|
* @T: a numeric type such as `unsigned int`
|
|
|
|
*
|
|
|
|
* An integer constant expression indicating whether @T is a signed type.
|
|
|
|
*
|
|
|
|
* Returns: 1 if @T is signed, 0 if it is unsigned
|
|
|
|
*/
|
|
|
|
#define G_SIGNEDNESS_OF(T) (((T) -1) <= 0)
|
|
|
|
|
2021-01-28 21:01:51 +00:00
|
|
|
/* gcc defines __SANITIZE_ADDRESS__, clang sets the address_sanitizer
|
2021-10-13 17:28:48 +09:00
|
|
|
* feature flag.
|
|
|
|
*
|
|
|
|
* MSVC defines __SANITIZE_ADDRESS__ as well when AddressSanitizer
|
|
|
|
* is enabled but __lsan_ignore_object() equivalent method is not supported
|
|
|
|
* See also
|
|
|
|
* https://docs.microsoft.com/en-us/cpp/sanitizers/asan-building?view=msvc-160
|
|
|
|
*/
|
|
|
|
#if !defined(_MSC_VER) && (defined(__SANITIZE_ADDRESS__) || g_macro__has_feature(address_sanitizer))
|
2021-01-28 21:01:51 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* %_GLIB_ADDRESS_SANITIZER:
|
|
|
|
*
|
2023-10-27 17:19:31 +02:00
|
|
|
* Private macro defined if the AddressSanitizer is in use by GLib itself.
|
2021-01-28 21:01:51 +00:00
|
|
|
*/
|
|
|
|
#define _GLIB_ADDRESS_SANITIZER
|
|
|
|
|
2021-01-29 19:11:11 +00:00
|
|
|
#include <sanitizer/lsan_interface.h>
|
|
|
|
|
2023-10-27 17:19:31 +02:00
|
|
|
/* If GLib itself is not compiled with ASAN sanitizer we may still want to
|
|
|
|
* control it in case it's linked by the loading application, so we need to
|
|
|
|
* do this check dynamically.
|
2024-07-09 20:34:02 +02:00
|
|
|
* However MinGW/Cygwin doesn't support weak attribute properly (even if it advertises
|
2023-10-27 17:19:31 +02:00
|
|
|
* it), so we ignore it in such case since it's not convenient to go through
|
|
|
|
* dlsym().
|
|
|
|
* Under MSVC we could use alternatename, but it doesn't seem to be as reliable
|
|
|
|
* as we'd like: https://stackoverflow.com/a/11529277/210151 and
|
|
|
|
* https://devblogs.microsoft.com/oldnewthing/20200731-00/?p=104024
|
|
|
|
*/
|
2024-07-09 20:34:02 +02:00
|
|
|
#elif defined (G_OS_UNIX) && !defined (__APPLE__) && !defined(__CYGWIN__) && g_macro__has_attribute (weak)
|
2023-10-27 17:19:31 +02:00
|
|
|
|
|
|
|
#define HAS_DYNAMIC_ASAN_LOADING
|
|
|
|
|
|
|
|
void __lsan_enable (void) __attribute__ ((weak));
|
|
|
|
void __lsan_disable (void) __attribute__ ((weak));
|
|
|
|
void __lsan_ignore_object (const void *p) __attribute__ ((weak));
|
|
|
|
|
2021-01-29 19:11:11 +00:00
|
|
|
#endif
|
|
|
|
|
2023-10-24 15:32:45 +02:00
|
|
|
/**
|
|
|
|
* G_CONTAINER_OF:
|
|
|
|
* @ptr: a pointer to a member @field of type @type.
|
|
|
|
* @type: the type of the container in which @field is embedded.
|
|
|
|
* @field: the name of the field in @type.
|
|
|
|
*
|
|
|
|
* Casts away constness of @ptr.
|
|
|
|
*
|
|
|
|
* Returns: a pointer to the container, so that "&(@container)->field == (@ptr)" holds.
|
|
|
|
*/
|
|
|
|
#define G_CONTAINER_OF(ptr, type, field) ((type *) G_STRUCT_MEMBER_P (ptr, -G_STRUCT_OFFSET (type, field)))
|
|
|
|
|
2023-10-27 17:19:31 +02:00
|
|
|
/*
|
|
|
|
* g_leak_sanitizer_is_supported:
|
|
|
|
*
|
|
|
|
* Checks at runtime if LeakSanitizer is currently supported by the running
|
|
|
|
* binary. This may imply that GLib itself is not compiled with sanitizer
|
|
|
|
* but that the loading program is.
|
|
|
|
*/
|
|
|
|
static inline gboolean
|
|
|
|
g_leak_sanitizer_is_supported (void)
|
|
|
|
{
|
|
|
|
#if defined (_GLIB_ADDRESS_SANITIZER)
|
|
|
|
return TRUE;
|
|
|
|
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
|
|
|
return __lsan_enable != NULL && __lsan_ignore_object != NULL;
|
|
|
|
#else
|
|
|
|
return FALSE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-01-29 19:11:11 +00:00
|
|
|
/*
|
|
|
|
* g_ignore_leak:
|
|
|
|
* @p: any pointer
|
|
|
|
*
|
|
|
|
* Tell AddressSanitizer and similar tools that if the object pointed to
|
|
|
|
* by @p is leaked, it is not a problem. Use this to suppress memory leak
|
|
|
|
* reports when a potentially unreachable pointer is deliberately not
|
|
|
|
* going to be deallocated.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
g_ignore_leak (gconstpointer p)
|
|
|
|
{
|
2023-10-27 17:19:31 +02:00
|
|
|
#if defined (_GLIB_ADDRESS_SANITIZER)
|
2021-01-29 19:11:11 +00:00
|
|
|
if (p != NULL)
|
|
|
|
__lsan_ignore_object (p);
|
2023-10-27 17:19:31 +02:00
|
|
|
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
|
|
|
if (p != NULL && __lsan_ignore_object != NULL)
|
|
|
|
__lsan_ignore_object (p);
|
2021-01-29 19:11:11 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* g_ignore_strv_leak:
|
|
|
|
* @strv: (nullable) (array zero-terminated=1): an array of strings
|
|
|
|
*
|
|
|
|
* The same as g_ignore_leak(), but for the memory pointed to by @strv,
|
|
|
|
* and for each element of @strv.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
g_ignore_strv_leak (GStrv strv)
|
|
|
|
{
|
|
|
|
gchar **item;
|
|
|
|
|
2023-10-27 17:19:31 +02:00
|
|
|
if (!g_leak_sanitizer_is_supported ())
|
|
|
|
return;
|
|
|
|
|
2021-01-29 19:11:11 +00:00
|
|
|
if (strv)
|
|
|
|
{
|
|
|
|
g_ignore_leak (strv);
|
|
|
|
|
|
|
|
for (item = strv; *item != NULL; item++)
|
|
|
|
g_ignore_leak (*item);
|
|
|
|
}
|
|
|
|
}
|
2021-01-28 21:01:51 +00:00
|
|
|
|
2021-09-27 13:12:31 +01:00
|
|
|
/*
|
|
|
|
* g_begin_ignore_leaks:
|
|
|
|
*
|
|
|
|
* Tell AddressSanitizer and similar tools to ignore all leaks from this point
|
|
|
|
* onwards, until g_end_ignore_leaks() is called.
|
|
|
|
*
|
|
|
|
* Try to use g_ignore_leak() where possible to target deliberate leaks more
|
|
|
|
* specifically.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
g_begin_ignore_leaks (void)
|
|
|
|
{
|
2023-10-27 17:19:31 +02:00
|
|
|
#if defined (_GLIB_ADDRESS_SANITIZER)
|
2021-09-27 13:12:31 +01:00
|
|
|
__lsan_disable ();
|
2023-10-27 17:19:31 +02:00
|
|
|
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
|
|
|
if (__lsan_disable != NULL)
|
|
|
|
__lsan_disable ();
|
2021-09-27 13:12:31 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* g_end_ignore_leaks:
|
|
|
|
*
|
|
|
|
* Start ignoring leaks again; this must be paired with a previous call to
|
|
|
|
* g_begin_ignore_leaks().
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
g_end_ignore_leaks (void)
|
|
|
|
{
|
2023-10-27 17:19:31 +02:00
|
|
|
#if defined (_GLIB_ADDRESS_SANITIZER)
|
2021-09-27 13:12:31 +01:00
|
|
|
__lsan_enable ();
|
2023-10-27 17:19:31 +02:00
|
|
|
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
|
|
|
if (__lsan_enable != NULL)
|
|
|
|
__lsan_enable ();
|
2021-09-27 13:12:31 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-10-27 17:19:31 +02:00
|
|
|
#undef HAS_DYNAMIC_ASAN_LOADING
|
|
|
|
|
2011-09-09 14:30:25 -04:00
|
|
|
GMainContext * g_get_worker_context (void);
|
CVE-2012-3524: Hardening for being run in a setuid environment
Some programs attempt to use libglib (or even libgio) when setuid.
For a long time, GTK+ simply aborted if launched in this
configuration, but we never had a real policy for GLib.
I'm not sure whether we should advertise such support. However, given
that there are real-world programs that do this currently, we can make
them safer with not too much effort.
Better to fix a problem caused by an interaction between two
components in *both* places if possible.
This patch adds a private function g_check_setuid() which is used to
first ensure we don't run an external dbus-launch binary if
DBUS_SESSION_BUS_ADDRESS isn't set.
Second, we also ensure the local VFS is used in this case. The
gdaemonvfs extension point will end up talking to the session bus
which is typically undesirable in a setuid context.
Implementing g_check_setuid() is interesting - whether or not we're
running in a privilege-escalated path is operating system specific.
Note that GTK+'s code to check euid versus uid worked historically on
Unix, more modern systems have filesystem capabilities and SELinux
domain transitions, neither of which are captured by the uid
comparison.
On Linux/glibc, the way this works is that the kernel sets an
AT_SECURE flag in the ELF auxiliary vector, and glibc looks for it on
startup. If found, then glibc sets a public-but-undocumented
__libc_enable_secure variable which we can use. Unfortunately, while
it *previously* worked to check this variable, a combination of newer
binutils and RPM break it:
http://www.openwall.com/lists/owl-dev/2012/08/14/1
So for now on Linux/glibc, we fall back to the historical Unix version
until we get glibc fixed.
On some BSD variants, there is a issetugid() function. On other Unix
variants, we fall back to what GTK+ has been doing.
Reported-By: Sebastian Krahmer <krahmer@suse.de>
Signed-off-by: Colin Walters <walters@verbum.org>
2012-08-22 14:26:11 -04:00
|
|
|
gboolean g_check_setuid (void);
|
2012-11-08 09:12:25 -05:00
|
|
|
GMainContext * g_main_context_new_with_next_id (guint next_id);
|
2011-09-09 14:30:25 -04:00
|
|
|
|
2022-11-02 23:55:48 +08:00
|
|
|
#if (defined (HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER) || \
|
|
|
|
defined (HAVE__SET_INVALID_PARAMETER_HANDLER)) && \
|
|
|
|
defined (HAVE__CRT_SET_REPORT_MODE)
|
|
|
|
# define USE_INVALID_PARAMETER_HANDLER
|
|
|
|
#endif
|
|
|
|
|
2022-11-03 00:00:31 +08:00
|
|
|
#ifdef USE_INVALID_PARAMETER_HANDLER
|
|
|
|
struct _GWin32InvalidParameterHandler
|
|
|
|
{
|
|
|
|
_invalid_parameter_handler old_handler;
|
|
|
|
_invalid_parameter_handler pushed_handler;
|
|
|
|
int prev_report_mode;
|
|
|
|
int pushed_report_mode;
|
|
|
|
};
|
|
|
|
#else
|
|
|
|
struct _GWin32InvalidParameterHandler
|
|
|
|
{
|
|
|
|
int unused_really;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2012-11-10 10:51:18 -05:00
|
|
|
#ifdef G_OS_WIN32
|
2013-01-13 15:34:27 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2012-11-10 10:51:18 -05:00
|
|
|
gchar *_glib_get_locale_dir (void);
|
|
|
|
#endif
|
|
|
|
|
2013-09-12 17:00:29 +08:00
|
|
|
GDir * g_dir_open_with_errno (const gchar *path, guint flags);
|
|
|
|
GDir * g_dir_new_from_dirp (gpointer dirp);
|
|
|
|
|
2022-11-03 00:00:31 +08:00
|
|
|
typedef struct _GWin32InvalidParameterHandler GWin32InvalidParameterHandler;
|
|
|
|
void g_win32_push_empty_invalid_parameter_handler (GWin32InvalidParameterHandler *items);
|
|
|
|
void g_win32_pop_invalid_parameter_handler (GWin32InvalidParameterHandler *items);
|
|
|
|
|
2023-02-13 16:12:07 +00:00
|
|
|
char *g_find_program_for_path (const char *program,
|
|
|
|
const char *path,
|
|
|
|
const char *working_dir);
|
|
|
|
|
2023-05-24 17:37:57 -05:00
|
|
|
int g_uri_get_default_scheme_port (const char *scheme);
|
|
|
|
|
2011-09-01 14:32:11 -04:00
|
|
|
#define GLIB_PRIVATE_CALL(symbol) (glib__private__()->symbol)
|
|
|
|
|
2022-11-03 00:00:31 +08:00
|
|
|
|
2011-09-01 14:32:11 -04:00
|
|
|
typedef struct {
|
|
|
|
/* See gwakeup.c */
|
2011-09-09 14:30:25 -04:00
|
|
|
GWakeup * (* g_wakeup_new) (void);
|
|
|
|
void (* g_wakeup_free) (GWakeup *wakeup);
|
|
|
|
void (* g_wakeup_get_pollfd) (GWakeup *wakeup,
|
|
|
|
GPollFD *poll_fd);
|
|
|
|
void (* g_wakeup_signal) (GWakeup *wakeup);
|
|
|
|
void (* g_wakeup_acknowledge) (GWakeup *wakeup);
|
|
|
|
|
|
|
|
/* See gmain.c */
|
|
|
|
GMainContext * (* g_get_worker_context) (void);
|
CVE-2012-3524: Hardening for being run in a setuid environment
Some programs attempt to use libglib (or even libgio) when setuid.
For a long time, GTK+ simply aborted if launched in this
configuration, but we never had a real policy for GLib.
I'm not sure whether we should advertise such support. However, given
that there are real-world programs that do this currently, we can make
them safer with not too much effort.
Better to fix a problem caused by an interaction between two
components in *both* places if possible.
This patch adds a private function g_check_setuid() which is used to
first ensure we don't run an external dbus-launch binary if
DBUS_SESSION_BUS_ADDRESS isn't set.
Second, we also ensure the local VFS is used in this case. The
gdaemonvfs extension point will end up talking to the session bus
which is typically undesirable in a setuid context.
Implementing g_check_setuid() is interesting - whether or not we're
running in a privilege-escalated path is operating system specific.
Note that GTK+'s code to check euid versus uid worked historically on
Unix, more modern systems have filesystem capabilities and SELinux
domain transitions, neither of which are captured by the uid
comparison.
On Linux/glibc, the way this works is that the kernel sets an
AT_SECURE flag in the ELF auxiliary vector, and glibc looks for it on
startup. If found, then glibc sets a public-but-undocumented
__libc_enable_secure variable which we can use. Unfortunately, while
it *previously* worked to check this variable, a combination of newer
binutils and RPM break it:
http://www.openwall.com/lists/owl-dev/2012/08/14/1
So for now on Linux/glibc, we fall back to the historical Unix version
until we get glibc fixed.
On some BSD variants, there is a issetugid() function. On other Unix
variants, we fall back to what GTK+ has been doing.
Reported-By: Sebastian Krahmer <krahmer@suse.de>
Signed-off-by: Colin Walters <walters@verbum.org>
2012-08-22 14:26:11 -04:00
|
|
|
|
|
|
|
gboolean (* g_check_setuid) (void);
|
2012-11-08 09:12:25 -05:00
|
|
|
GMainContext * (* g_main_context_new_with_next_id) (guint next_id);
|
2013-09-12 17:00:29 +08:00
|
|
|
|
|
|
|
GDir * (* g_dir_open_with_errno) (const gchar *path,
|
|
|
|
guint flags);
|
|
|
|
GDir * (* g_dir_new_from_dirp) (gpointer dirp);
|
|
|
|
|
2015-10-06 19:45:38 -04:00
|
|
|
/* See glib-init.c */
|
|
|
|
void (* glib_init) (void);
|
|
|
|
|
W32: Add a stat() implementation for private use
This commit adds new W32-only functions to gstdio.c,
and a new header file, gstdioprivate.h.
These functions are:
g_win32_stat_utf8()
g_win32_lstat_utf8()
g_win32_fstat()
and they fill a private structure, GWin32PrivateStat,
which has all the fields that normal stat has, as well as some
extras.
These functions are then used throughout glib and gio to get better
data about the system. Specifically:
* Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size)
* Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is)
* W32 File attributes (which stat() doesn't report); in particular, this allows
symlinks to be correctly identified
* Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows)
* Allocated file size (as a W32 replacement for the missing st_blocks)
st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to
glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8),
this field does not contain anything unexpected.
g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to.
Also adds the g_win32_readlink_utf8() function, which behaves like readlink()
(including its inability to return 0-terminated strings and inability to say how large
the output buffer should be; these limitations are purely for compatibility with
existing glib code).
Thus, symlink support should now be much better, although far from being complete.
A new W32-only test in gio/tests/file.c highlights the following features:
* allocated size
* 64-bit time
* unique file IDs
https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 10:14:41 +00:00
|
|
|
/* See gstdio.c */
|
|
|
|
#ifdef G_OS_WIN32
|
W32: significant symlink code changes
Put the core readlink() code into a separate
_g_win32_readlink_handle_raw() function that takes a file handle,
can optionally ensure NUL-terminatedness of its output
(for cases where we need a NUL-terminator and do *not* need
to get the exact contents of the symlink as it is stored in FS)
and can either fill a caller-provided buffer *or* allocate
its own buffer, and can also read the reparse tag.
Put the rest of readlink() code into separate
functions that do UTF-16<->UTF-8, strip inconvenient prefix
and open/close the symlink file handle as needed.
Split _g_win32_stat_utf16_no_trailing_slashes() into
two functions - the one that takes a filename and the one
that takes a file descriptor. The part of these functions
that would have been duplicate is now split into the
_g_win32_fill_privatestat() funcion.
Add more comments explaining what each function does.
Only g_win32_readlink_utf8(), which is callable from outside
via private function interface, gets a real doc-comment,
the rest get normal, non-doc comments.
Change all callers to use the new version of the private
g_win32_readlink_utf8() function, which can now NUL-terminate
and allocate on demand - no need to call it in a loop.
Also, the new code should correctly get reparse tag when the
caller does fstat() on a symlink. Do note that this requires
the caller to get a FD for the symlink, not the target. Figuring
out how to do that is up to the caller.
Since symlink info (target path and reparse tag) are now always
read directly, via DeviceIoControl(), we don't need to use
FindFirstFileW() anymore.
2018-08-24 09:16:46 +00:00
|
|
|
int (* g_win32_stat_utf8) (const gchar *filename,
|
|
|
|
GWin32PrivateStat *buf);
|
W32: Add a stat() implementation for private use
This commit adds new W32-only functions to gstdio.c,
and a new header file, gstdioprivate.h.
These functions are:
g_win32_stat_utf8()
g_win32_lstat_utf8()
g_win32_fstat()
and they fill a private structure, GWin32PrivateStat,
which has all the fields that normal stat has, as well as some
extras.
These functions are then used throughout glib and gio to get better
data about the system. Specifically:
* Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size)
* Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is)
* W32 File attributes (which stat() doesn't report); in particular, this allows
symlinks to be correctly identified
* Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows)
* Allocated file size (as a W32 replacement for the missing st_blocks)
st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to
glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8),
this field does not contain anything unexpected.
g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to.
Also adds the g_win32_readlink_utf8() function, which behaves like readlink()
(including its inability to return 0-terminated strings and inability to say how large
the output buffer should be; these limitations are purely for compatibility with
existing glib code).
Thus, symlink support should now be much better, although far from being complete.
A new W32-only test in gio/tests/file.c highlights the following features:
* allocated size
* 64-bit time
* unique file IDs
https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 10:14:41 +00:00
|
|
|
|
W32: significant symlink code changes
Put the core readlink() code into a separate
_g_win32_readlink_handle_raw() function that takes a file handle,
can optionally ensure NUL-terminatedness of its output
(for cases where we need a NUL-terminator and do *not* need
to get the exact contents of the symlink as it is stored in FS)
and can either fill a caller-provided buffer *or* allocate
its own buffer, and can also read the reparse tag.
Put the rest of readlink() code into separate
functions that do UTF-16<->UTF-8, strip inconvenient prefix
and open/close the symlink file handle as needed.
Split _g_win32_stat_utf16_no_trailing_slashes() into
two functions - the one that takes a filename and the one
that takes a file descriptor. The part of these functions
that would have been duplicate is now split into the
_g_win32_fill_privatestat() funcion.
Add more comments explaining what each function does.
Only g_win32_readlink_utf8(), which is callable from outside
via private function interface, gets a real doc-comment,
the rest get normal, non-doc comments.
Change all callers to use the new version of the private
g_win32_readlink_utf8() function, which can now NUL-terminate
and allocate on demand - no need to call it in a loop.
Also, the new code should correctly get reparse tag when the
caller does fstat() on a symlink. Do note that this requires
the caller to get a FD for the symlink, not the target. Figuring
out how to do that is up to the caller.
Since symlink info (target path and reparse tag) are now always
read directly, via DeviceIoControl(), we don't need to use
FindFirstFileW() anymore.
2018-08-24 09:16:46 +00:00
|
|
|
int (* g_win32_lstat_utf8) (const gchar *filename,
|
|
|
|
GWin32PrivateStat *buf);
|
W32: Add a stat() implementation for private use
This commit adds new W32-only functions to gstdio.c,
and a new header file, gstdioprivate.h.
These functions are:
g_win32_stat_utf8()
g_win32_lstat_utf8()
g_win32_fstat()
and they fill a private structure, GWin32PrivateStat,
which has all the fields that normal stat has, as well as some
extras.
These functions are then used throughout glib and gio to get better
data about the system. Specifically:
* Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size)
* Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is)
* W32 File attributes (which stat() doesn't report); in particular, this allows
symlinks to be correctly identified
* Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows)
* Allocated file size (as a W32 replacement for the missing st_blocks)
st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to
glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8),
this field does not contain anything unexpected.
g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to.
Also adds the g_win32_readlink_utf8() function, which behaves like readlink()
(including its inability to return 0-terminated strings and inability to say how large
the output buffer should be; these limitations are purely for compatibility with
existing glib code).
Thus, symlink support should now be much better, although far from being complete.
A new W32-only test in gio/tests/file.c highlights the following features:
* allocated size
* 64-bit time
* unique file IDs
https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 10:14:41 +00:00
|
|
|
|
W32: significant symlink code changes
Put the core readlink() code into a separate
_g_win32_readlink_handle_raw() function that takes a file handle,
can optionally ensure NUL-terminatedness of its output
(for cases where we need a NUL-terminator and do *not* need
to get the exact contents of the symlink as it is stored in FS)
and can either fill a caller-provided buffer *or* allocate
its own buffer, and can also read the reparse tag.
Put the rest of readlink() code into separate
functions that do UTF-16<->UTF-8, strip inconvenient prefix
and open/close the symlink file handle as needed.
Split _g_win32_stat_utf16_no_trailing_slashes() into
two functions - the one that takes a filename and the one
that takes a file descriptor. The part of these functions
that would have been duplicate is now split into the
_g_win32_fill_privatestat() funcion.
Add more comments explaining what each function does.
Only g_win32_readlink_utf8(), which is callable from outside
via private function interface, gets a real doc-comment,
the rest get normal, non-doc comments.
Change all callers to use the new version of the private
g_win32_readlink_utf8() function, which can now NUL-terminate
and allocate on demand - no need to call it in a loop.
Also, the new code should correctly get reparse tag when the
caller does fstat() on a symlink. Do note that this requires
the caller to get a FD for the symlink, not the target. Figuring
out how to do that is up to the caller.
Since symlink info (target path and reparse tag) are now always
read directly, via DeviceIoControl(), we don't need to use
FindFirstFileW() anymore.
2018-08-24 09:16:46 +00:00
|
|
|
int (* g_win32_readlink_utf8) (const gchar *filename,
|
|
|
|
gchar *buf,
|
|
|
|
gsize buf_size,
|
|
|
|
gchar **alloc_buf,
|
|
|
|
gboolean terminate);
|
W32: Add a stat() implementation for private use
This commit adds new W32-only functions to gstdio.c,
and a new header file, gstdioprivate.h.
These functions are:
g_win32_stat_utf8()
g_win32_lstat_utf8()
g_win32_fstat()
and they fill a private structure, GWin32PrivateStat,
which has all the fields that normal stat has, as well as some
extras.
These functions are then used throughout glib and gio to get better
data about the system. Specifically:
* Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size)
* Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is)
* W32 File attributes (which stat() doesn't report); in particular, this allows
symlinks to be correctly identified
* Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows)
* Allocated file size (as a W32 replacement for the missing st_blocks)
st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to
glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8),
this field does not contain anything unexpected.
g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to.
Also adds the g_win32_readlink_utf8() function, which behaves like readlink()
(including its inability to return 0-terminated strings and inability to say how large
the output buffer should be; these limitations are purely for compatibility with
existing glib code).
Thus, symlink support should now be much better, although far from being complete.
A new W32-only test in gio/tests/file.c highlights the following features:
* allocated size
* 64-bit time
* unique file IDs
https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 10:14:41 +00:00
|
|
|
|
W32: significant symlink code changes
Put the core readlink() code into a separate
_g_win32_readlink_handle_raw() function that takes a file handle,
can optionally ensure NUL-terminatedness of its output
(for cases where we need a NUL-terminator and do *not* need
to get the exact contents of the symlink as it is stored in FS)
and can either fill a caller-provided buffer *or* allocate
its own buffer, and can also read the reparse tag.
Put the rest of readlink() code into separate
functions that do UTF-16<->UTF-8, strip inconvenient prefix
and open/close the symlink file handle as needed.
Split _g_win32_stat_utf16_no_trailing_slashes() into
two functions - the one that takes a filename and the one
that takes a file descriptor. The part of these functions
that would have been duplicate is now split into the
_g_win32_fill_privatestat() funcion.
Add more comments explaining what each function does.
Only g_win32_readlink_utf8(), which is callable from outside
via private function interface, gets a real doc-comment,
the rest get normal, non-doc comments.
Change all callers to use the new version of the private
g_win32_readlink_utf8() function, which can now NUL-terminate
and allocate on demand - no need to call it in a loop.
Also, the new code should correctly get reparse tag when the
caller does fstat() on a symlink. Do note that this requires
the caller to get a FD for the symlink, not the target. Figuring
out how to do that is up to the caller.
Since symlink info (target path and reparse tag) are now always
read directly, via DeviceIoControl(), we don't need to use
FindFirstFileW() anymore.
2018-08-24 09:16:46 +00:00
|
|
|
int (* g_win32_fstat) (int fd,
|
|
|
|
GWin32PrivateStat *buf);
|
2022-01-05 18:06:01 +01:00
|
|
|
|
|
|
|
/* See gwin32.c */
|
|
|
|
gchar *(*g_win32_find_helper_executable_path) (const gchar *process_name,
|
|
|
|
void *dll_handle);
|
2022-04-07 17:53:54 +04:00
|
|
|
|
|
|
|
int (* g_win32_reopen_noninherited) (int fd,
|
|
|
|
int mode,
|
|
|
|
GError **err);
|
2022-04-08 14:49:49 +04:00
|
|
|
|
|
|
|
gboolean (* g_win32_handle_is_socket) (void *handle);
|
|
|
|
|
W32: Add a stat() implementation for private use
This commit adds new W32-only functions to gstdio.c,
and a new header file, gstdioprivate.h.
These functions are:
g_win32_stat_utf8()
g_win32_lstat_utf8()
g_win32_fstat()
and they fill a private structure, GWin32PrivateStat,
which has all the fields that normal stat has, as well as some
extras.
These functions are then used throughout glib and gio to get better
data about the system. Specifically:
* Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size)
* Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is)
* W32 File attributes (which stat() doesn't report); in particular, this allows
symlinks to be correctly identified
* Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows)
* Allocated file size (as a W32 replacement for the missing st_blocks)
st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to
glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8),
this field does not contain anything unexpected.
g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to.
Also adds the g_win32_readlink_utf8() function, which behaves like readlink()
(including its inability to return 0-terminated strings and inability to say how large
the output buffer should be; these limitations are purely for compatibility with
existing glib code).
Thus, symlink support should now be much better, although far from being complete.
A new W32-only test in gio/tests/file.c highlights the following features:
* allocated size
* 64-bit time
* unique file IDs
https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 10:14:41 +00:00
|
|
|
#endif
|
|
|
|
|
2022-11-03 00:00:31 +08:00
|
|
|
/* See glib-private.c */
|
|
|
|
void (* g_win32_push_empty_invalid_parameter_handler) (GWin32InvalidParameterHandler *items);
|
|
|
|
|
|
|
|
void (* g_win32_pop_invalid_parameter_handler) (GWin32InvalidParameterHandler *items);
|
W32: Add a stat() implementation for private use
This commit adds new W32-only functions to gstdio.c,
and a new header file, gstdioprivate.h.
These functions are:
g_win32_stat_utf8()
g_win32_lstat_utf8()
g_win32_fstat()
and they fill a private structure, GWin32PrivateStat,
which has all the fields that normal stat has, as well as some
extras.
These functions are then used throughout glib and gio to get better
data about the system. Specifically:
* Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size)
* Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is)
* W32 File attributes (which stat() doesn't report); in particular, this allows
symlinks to be correctly identified
* Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows)
* Allocated file size (as a W32 replacement for the missing st_blocks)
st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to
glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8),
this field does not contain anything unexpected.
g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to.
Also adds the g_win32_readlink_utf8() function, which behaves like readlink()
(including its inability to return 0-terminated strings and inability to say how large
the output buffer should be; these limitations are purely for compatibility with
existing glib code).
Thus, symlink support should now be much better, although far from being complete.
A new W32-only test in gio/tests/file.c highlights the following features:
* allocated size
* 64-bit time
* unique file IDs
https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 10:14:41 +00:00
|
|
|
|
2023-02-13 16:12:07 +00:00
|
|
|
/* See gutils.c */
|
|
|
|
char *(* g_find_program_for_path) (const char *program,
|
|
|
|
const char *path,
|
|
|
|
const char *working_dir);
|
|
|
|
|
2023-05-24 17:37:57 -05:00
|
|
|
/* See guri.c */
|
|
|
|
int (* g_uri_get_default_scheme_port) (const char *scheme);
|
|
|
|
|
2023-11-08 08:48:35 +01:00
|
|
|
/* See gutils.c */
|
|
|
|
gboolean (* g_set_prgname_once) (const gchar *prgname);
|
|
|
|
|
glib: add internal g_datalist_id_update_atomic() function
GDataSet is mainly used by GObject. Usually, when we access the private
data there, we already hold another lock around the GObject.
For example, before accessing quark_toggle_refs, we take a
OPTIONAL_BIT_LOCK_TOGGLE_REFS lock. That makes sense, because we anyway
need to protect access to the ToggleRefStack. By holding such an
external mutex around several GData operations, we achieve atomic
updates.
However, there is a (performance) use case to update the qdata
atomically, without such additional lock. The GData already holds a lock
while updating the data. Add a new g_datalist_id_update_atomic()
function, that can invoke a callback while holding that lock.
This will be used by GObject. The benefit is that we can access the
GData atomically, without requiring another mutex around it.
For example, a common pattern is to request some GData entry, and if
it's not yet allocated, to allocate it. This requires to take the GData
bitlock twice. With this API, the callback can allocate the data if no
entry exists yet.
2024-01-12 20:46:27 +01:00
|
|
|
gpointer (*g_datalist_id_update_atomic) (GData **datalist,
|
|
|
|
GQuark key_id,
|
|
|
|
GDataListUpdateAtomicFunc callback,
|
|
|
|
gpointer user_data);
|
|
|
|
|
2012-11-08 09:12:25 -05:00
|
|
|
/* Add other private functions here, initialize them in glib-private.c */
|
2011-09-01 14:32:11 -04:00
|
|
|
} GLibPrivateVTable;
|
|
|
|
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2024-01-29 16:05:29 +01:00
|
|
|
const GLibPrivateVTable *glib__private__ (void);
|
2011-09-01 14:32:11 -04:00
|
|
|
|
2019-06-05 16:34:57 +08:00
|
|
|
/* Please see following for the use of ".ACP" over ""
|
|
|
|
* on Windows, although both are accepted at compile-time
|
|
|
|
* but "" renders translated console messages unreadable if
|
|
|
|
* built with Visual Studio 2012 and later (this is, unfortunately,
|
|
|
|
* undocumented):
|
|
|
|
*
|
|
|
|
* https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale
|
|
|
|
* https://gitlab.gnome.org/GNOME/glib/merge_requests/895#note_525881
|
|
|
|
* https://gitlab.gnome.org/GNOME/glib/merge_requests/895#note_525900
|
|
|
|
*
|
|
|
|
* Additional related items:
|
|
|
|
* https://stackoverflow.com/questions/22604329/php-5-5-setlocale-not-working-in-cli-on-windows
|
|
|
|
* https://bugs.php.net/bug.php?id=66265
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
# define GLIB_DEFAULT_LOCALE ".ACP"
|
|
|
|
#else
|
|
|
|
# define GLIB_DEFAULT_LOCALE ""
|
|
|
|
#endif
|
|
|
|
|
2023-10-24 14:11:04 +02:00
|
|
|
gboolean g_uint_equal (gconstpointer v1, gconstpointer v2);
|
|
|
|
guint g_uint_hash (gconstpointer v);
|
|
|
|
|
2023-12-21 12:11:37 +01:00
|
|
|
#if defined(__GNUC__)
|
|
|
|
#define G_THREAD_LOCAL __thread
|
|
|
|
#else
|
|
|
|
#undef G_THREAD_LOCAL
|
|
|
|
#endif
|
|
|
|
|
glib: add internal g_datalist_id_update_atomic() function
GDataSet is mainly used by GObject. Usually, when we access the private
data there, we already hold another lock around the GObject.
For example, before accessing quark_toggle_refs, we take a
OPTIONAL_BIT_LOCK_TOGGLE_REFS lock. That makes sense, because we anyway
need to protect access to the ToggleRefStack. By holding such an
external mutex around several GData operations, we achieve atomic
updates.
However, there is a (performance) use case to update the qdata
atomically, without such additional lock. The GData already holds a lock
while updating the data. Add a new g_datalist_id_update_atomic()
function, that can invoke a callback while holding that lock.
This will be used by GObject. The benefit is that we can access the
GData atomically, without requiring another mutex around it.
For example, a common pattern is to request some GData entry, and if
it's not yet allocated, to allocate it. This requires to take the GData
bitlock twice. With this API, the callback can allocate the data if no
entry exists yet.
2024-01-12 20:46:27 +01:00
|
|
|
/* Convenience wrapper to call private g_datalist_id_update_atomic() function. */
|
|
|
|
#define _g_datalist_id_update_atomic(datalist, key_id, callback, user_data) \
|
|
|
|
(GLIB_PRIVATE_CALL (g_datalist_id_update_atomic) ((datalist), (key_id), (callback), (user_data)))
|
|
|
|
|
2014-05-21 07:40:09 -04:00
|
|
|
#endif /* __GLIB_PRIVATE_H__ */
|