This could potentially eventually become a public GLib API, but there
doesn’t seem to be a huge need for it right now (e.g. this file contains
the only use of `/proc/self/fd/%d` in GLib), so let’s keep it private
for now and avoid committing to API stability just yet.
This gives time for other platforms to add their platform-specific
implementations for it too, if they need. I’ve added a couple of
pointers to what I *think* the right APIs might be, from my research,
but I have not prototyped those implementations.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
The Debian 12.8 point release included a version of ninja that is
equivalent to the one we were building from source here.
This reverts commit dbd7280c5e.
Signed-off-by: Simon McVittie <smcv@debian.org>
When a conversion is finished, the code would return 0 from its write
vfunc. This is disallowed by the API of g_output_stream_write() and
causes g_output_stream_splice() as used by g_converter_convert_bytes()
to turn into an infinite loop.
Instead, raise a G_IO_ERROR_MESSAGE_TOO_LARGE error so that the calling
code can decide how to deal with it.
Testcase included.
Closes#3532
It is unused when compiling with `G_DISABLE_ASSERT`. That’s fine, but we
definitely want the `g_hash_table_remove()` call to still be made.
Fixes this CI failure: https://gitlab.gnome.org/GNOME/glib/-/jobs/4483098
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Testing this in a normal testcaes is a bit tricky, since
triggering a non-fatal assertion has the side-effect of
marking the test as failed.
So just don't run any testcases here, but check the side-effect
manually. Since we don't produce TAP output when not using
g_test_run(), tell meson that we're using the exitcode protocol.
There is a race between releasing and re-acquiring an interned
GRefString if this happens on two threads at the same time. This can
result in already freed memory to be returned from
g_ref_string_new_intern().
| Thread 1 | Thread 2 |
| ------------------------------ | ----------------------------- |
| g_ref_string_release() | g_ref_string_new_intern() |
| g_atomic_rc_box_release_full() | g_mutex_lock() |
| | g_hash_table_lookup() |
| remove_if_interned() | g_ref_string_acquire() |
| g_mutex_lock() | g_mutex_unlock() |
| g_hash_table_remove() | |
| g_mutex_unlock() | |
| g_free() | |
| | return res; // this is freed |
This use-after-free usually also gives a critical warning because
g_atomic_ref_count_inc() checks for the refcount having been 0
before incrementing.
It is not possible to safely implement weak references via garcbox.
To avoid this race do not implement weak references via garcbox but
instead implement the allocation of the string manually with a manually
managed reference count. This allows to safely resurrect the interned
string if the above race happens, and also avoids other races.
As a side-effect this also
* reduces the allocation size in addition to the actual string length
from 32 bytes to 16 bytes on 64 bit platforms and keeps it at 16 bytes
on 32 bit platforms,
* doesn't lock a mutex when freeing non-interned GRefStrings.
We have a mechanism for turning on optional features of the GLib
test harness by passing options to g_test_init(). Use it for the
non-fatal assertions as well.
The documentation for glibc's pthread_setname_np states:
The thread name is a meaningful C language string,
whose length is restricted to 16 characters,
including the terminating null byte ('\0').
The documentation for Solaris' pthread_setname_np states:
The thread name is a string of length 31 bytes or less,
UTF-8 encoded.
Failing to respect this length limitation may lead to no name being
set, which is confusing, since the thread then shows up under the
binary name in gdb. This was happening for the pango worker thread
with the name "[pango] fontconfig".
For g_auto(GVariantBuilder) one needs to initialize it before the
function returns, so it's best to do it when the variable is declared.
G_VARIANT_BUILDER_INIT exists but requires specifying a GVariantType in
the declaration which moves the type away from the usage of the builder
which often results in less readable code. G_VARIANT_BUILDER_INIT also
mentions that it's possible to explicitly zero the variable but this is
hard to find and writing `g_auto(GVariantBuilder) builder = {0,};` is
kind of ugly.
This introduces G_VARIANT_BUILDER_INIT_UNSET which zero initializes the
variable being declared. This gives us documentation and hides the
explicitly zeroing detail:
auto(GVariantBuilder) builder = G_VARIANT_BUILDER_INIT_UNSET ();