summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--CONTRIBUTING.md6
-rw-r--r--README.win32.md6
-rw-r--r--docs/CODEOWNERS6
-rw-r--r--docs/debugging.txt38
-rw-r--r--docs/macros.md73
-rw-r--r--docs/macros.txt58
-rw-r--r--docs/reference/gio/gdbus-codegen.xml2
-rw-r--r--docs/reference/gio/gio-sections-common.txt2
-rw-r--r--docs/reference/gio/meson.build1
-rw-r--r--docs/reference/gio/overview.xml4
-rw-r--r--docs/reference/glib/building.xml4
-rw-r--r--docs/reference/glib/glib-sections.txt.in4
-rw-r--r--docs/reference/glib/meson.build58
-rw-r--r--docs/reference/glib/programming.xml65
-rw-r--r--docs/reference/gobject/tut_gobject.xml2
-rw-r--r--docs/reference/gobject/tut_gsignal.xml12
-rw-r--r--docs/reference/gobject/tut_howto.xml4
-rw-r--r--docs/reference/gobject/tut_intro.xml2
-rw-r--r--docs/reference/gobject/tut_tools.xml4
-rw-r--r--docs/supported-platforms.md16
-rw-r--r--docs/toolchain-requirements.md2
-rw-r--r--gio/gapplication.c2
-rw-r--r--gio/gfile.c163
-rw-r--r--gio/gfileinfo.c8
-rw-r--r--gio/giomodule.c4
-rw-r--r--gio/gregistrysettingsbackend.c3
-rw-r--r--gio/gresolver.c124
-rw-r--r--gio/gresolver.h5
-rw-r--r--gio/gsocket.c2
-rw-r--r--gio/gtask.c72
-rw-r--r--gio/gtask.h6
-rw-r--r--gio/gtestdbus.c5
-rw-r--r--gio/gthreadedresolver.c585
-rw-r--r--gio/gthreadedresolver.h25
-rw-r--r--gio/gunixconnection.c23
-rw-r--r--gio/gunixmounts.c2
-rw-r--r--gio/gwin32networkmonitor.c24
-rw-r--r--gio/inotify/meson.build11
-rw-r--r--gio/kqueue/meson.build9
-rw-r--r--gio/meson.build26
-rw-r--r--gio/tests/appmonitor.c14
-rw-r--r--gio/tests/desktop-files/usr/applications/glade.desktop18
-rw-r--r--gio/tests/file.c86
-rw-r--r--gio/tests/gapplication.c6
-rw-r--r--gio/tests/gdbus-connection-slow.c10
-rw-r--r--gio/tests/gmenumodel.c6
-rw-r--r--gio/tests/gsubprocess.c12
-rw-r--r--gio/tests/meson.build72
-rw-r--r--gio/tests/resolver.c16
-rw-r--r--gio/tests/socket-common.c2
-rw-r--r--gio/tests/socket-testclient.c (renamed from gio/tests/socket-client.c)0
-rw-r--r--gio/tests/socket-testserver.c (renamed from gio/tests/socket-server.c)0
-rw-r--r--gio/win32/meson.build8
-rw-r--r--glib.doap6
-rw-r--r--glib/docs.c2
-rw-r--r--glib/gconvert.c3
-rw-r--r--glib/gerror.c2
-rw-r--r--glib/gfileutils.c24
-rw-r--r--glib/ggettext.c6
-rw-r--r--glib/glib-init.c2
-rw-r--r--glib/glib-unix.c9
-rw-r--r--glib/gmacros.h3
-rw-r--r--glib/gmain.c286
-rw-r--r--glib/gmain.h12
-rw-r--r--glib/gmessages.c8
-rw-r--r--glib/goption.c2
-rw-r--r--glib/gquark.c2
-rw-r--r--glib/grefcount.h54
-rw-r--r--glib/gtestutils.c50
-rw-r--r--glib/gtestutils.h51
-rw-r--r--glib/gthreadpool.c13
-rw-r--r--glib/gthreadprivate.h6
-rw-r--r--glib/gtimer.c3
-rw-r--r--glib/gtypes.h2
-rw-r--r--glib/guri.c2
-rw-r--r--glib/gutf8.c2
-rw-r--r--glib/gutils.c10
-rw-r--r--glib/gvariant.c4
-rw-r--r--glib/gwin32.c4
-rw-r--r--glib/meson.build14
-rw-r--r--glib/tests/assert-msg-test.c38
-rw-r--r--glib/tests/mainloop.c70
-rw-r--r--glib/tests/meson.build31
-rw-r--r--glib/tests/messages-low-memory.c9
-rw-r--r--glib/tests/mutex.c2
-rw-r--r--glib/tests/rec-mutex.c2
-rw-r--r--glib/tests/timeout.c20
-rw-r--r--glib/tests/timer.c24
-rw-r--r--gmodule/meson.build9
-rw-r--r--gmodule/tests/meson.build28
-rw-r--r--gobject/gobject.c3
-rw-r--r--gobject/gtype.c20
-rw-r--r--gobject/gtype.h2
-rw-r--r--gobject/tests/signals.c18
-rw-r--r--gthread/tests/meson.build19
-rw-r--r--meson.build18
-rw-r--r--po/gl.po510
-rw-r--r--po/sv.po523
-rw-r--r--tools/meson.build4
100 files changed, 2537 insertions, 1115 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 182b9c7a7..b05a7098f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -595,7 +595,7 @@ scan-build:
paths:
- "_scan_build/meson-logs/scanbuild"
-coverity:
+.coverity:
extends:
- .build-linux
- .only-schedules
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index efeea85c2..5e28db343 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -114,7 +114,7 @@ development tools appropriate for your operating system, including:
- Meson
- Ninja
- Gettext (19.7 or newer)
- - a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
+ - a [C99 compatible compiler](./docs/toolchain-requirements.md)
Up-to-date instructions about developing GNOME applications and libraries
can be found on [the GNOME Developer Center](https://developer.gnome.org).
@@ -187,7 +187,7 @@ With each code review, we intend to:
adequately tested, either through requiring tests to be submitted at the
same time, or as a follow-up.
0. Ensure that all new APIs are documented and have [introspection
- annotations](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations).
+ annotations](https://gi.readthedocs.io/en/latest/annotations/giannotations.html).
0. Check that the contribution is split into logically separate commits, each
with a good commit message.
0. Encourage further high quality contributions.
@@ -272,4 +272,4 @@ GLib to follow a few rules:
If you have been contributing to GLib for a while and you don’t have commit
access to the repository, you may ask to obtain it following the [GNOME account
-process](https://wiki.gnome.org/AccountsTeam/NewAccounts).
+process](https://wiki.gnome.org/Infrastructure/NewAccounts).
diff --git a/README.win32.md b/README.win32.md
index 7f11e571e..81dee0465 100644
--- a/README.win32.md
+++ b/README.win32.md
@@ -9,7 +9,7 @@ warned.
# General
For prebuilt binaries (DLLs and EXEs) and developer packages (headers,
-import libraries) of GLib, Pango, GTK+ etc for Windows, go to
+import libraries) of GLib, Pango, GTK etc for Windows, go to
https://www.gtk.org/docs/installations/windows/ . They are for "native"
Windows meaning they use the Win32 API and Microsoft C runtime library
only. No POSIX (Unix) emulation layer like Cygwin is involved.
@@ -59,9 +59,9 @@ MinGW](https://mingwpy.github.io/ucrt.html) too.
GLib is not actively tested with the static versions of the UCRT, but if you
need to use those, patches are welcome.
-# Building software that use GLib or GTK+
+# Building software that use GLib or GTK
-Building software that just *uses* GLib or GTK+ also require to have
+Building software that just *uses* GLib or GTK also require to have
the right compiler set up the right way. If you intend to use MinGW-GCC,
follow the relevant instructions below in that case, too.
diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS
index 41e657dfb..cd4ef7391 100644
--- a/docs/CODEOWNERS
+++ b/docs/CODEOWNERS
@@ -38,13 +38,13 @@ subprojects/ @xclaesse @nirbheek @pwithnall
*.m @jralls @pwithnall @sdroege
# Windows support
-*win32* @lrn @creiter @fanc999 @pwithnall @sdroege @nirbheek
+*win32* @lrn @creiter @fanc999 @pwithnall @sdroege @nirbheek @lb90
# Windows support (MSVC-specific)
-*msvc* @fanc999 @creiter @pwithnall @sdroege @nirbheek
+*msvc* @fanc999 @creiter @pwithnall @sdroege @nirbheek @lb90
# Windows support (UWP-specific)
-*uwp* @nirbheek
+*uwp* @nirbheek @lb90
# Android support
*android* @xclaesse @pwithnall @sdroege
diff --git a/docs/debugging.txt b/docs/debugging.txt
deleted file mode 100644
index 2cc600aa9..000000000
--- a/docs/debugging.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-
-Traps (G_BREAKPOINT) and traces for the debugging
-=================================================
-
-Some code portions contain trap variables that can be set during
-debugging time if G_ENABLE_DEBUG has been defined upon compilation
-(use the --buildtype=debug option to configure for this, macros.txt
-covers more details).
-Such traps lead to immediate code halts to examine the current
-program state and backtrace.
-Currently, the following trap variables exist:
-
-static volatile gulong g_trap_free_size;
-static volatile gulong g_trap_realloc_size;
-static volatile gulong g_trap_malloc_size;
- If set to a size > 0, g_free(), g_realloc() and g_malloc()
- respectively, will be intercepted if the size matches the
- size of the corresponding memory block to free/reallocate/allocate.
- This will only work with g_mem_set_vtable (glib_mem_profiler_table)
- upon startup though, because memory profiling is required to match
- on the memory block sizes.
-static volatile GObject *g_trap_object_ref;
- If set to a valid object pointer, ref/unref will be intercepted
- with G_BREAKPOINT ();
-static volatile gpointer *g_trap_instance_signals;
-static volatile gpointer *g_trace_instance_signals;
- If set to a valid instance pointer, debugging messages
- will be spewed about emissions of signals on this instance.
- For g_trap_instance_signals matches, the emissions will
- also be intercepted with G_BREAKPOINT ();
-
-Environment variables for debugging
-===================================
-When G_ENABLE_DEBUG was defined upon compilation, the GObject library
-supports an environment variable GOBJECT_DEBUG that can be set to a
-combination of the flags passed in to g_type_init() (currently
-"objects" and "signals") to trigger debugging messages about
-object bookkeeping and signal emissions during runtime. \ No newline at end of file
diff --git a/docs/macros.md b/docs/macros.md
new file mode 100644
index 000000000..eac9b6db9
--- /dev/null
+++ b/docs/macros.md
@@ -0,0 +1,73 @@
+GLib's configure options and corresponding macros
+=================================================
+
+The following Meson configure options will result in certain macros or options
+being defined at build time:
+
+`--buildtype={plain,release,minsize,custom}`
+ : No special macros or options
+`--buildtype={debug,debugoptimized}` (`debugoptimized` is the default)
+ : `-DG_ENABLE_DEBUG -g`
+`-Dglib_debug=disabled`
+ : Omits `G_ENABLE_DEBUG` when implied by `--buildtype`/`-Ddebug`
+`-Dglib_debug=enabled`
+ : Defines `G_ENABLE_DEBUG` regardless of `--buildtype`/`-Ddebug`
+`-Dglib_asserts=false`
+ : `-DG_DISABLE_ASSERT`
+`-Dglib_checks=false`
+ : `-DG_DISABLE_CHECKS`
+
+Besides these, there are some local feature specific options, but the main
+focus here is to concentrate on macros that affect overall GLib behaviour
+and/or third party code.
+
+
+GLib's internal and global macros
+=================================
+
+`G_DISABLE_ASSERT`
+---
+
+The `g_assert()` and `g_assert_not_reached()` macros become non-functional
+with this define. The motivation is to speed up end-user apps by
+avoiding expensive checks.
+
+This macro can affect third-party code. Defining it when building GLib
+will only disable the assertion macros for GLib itself, but third-party code
+that passes `-DG_DISABLE_ASSERT` to the compiler in its own build
+will end up with the non-functional variants after including `glib.h`
+as well.
+
+Note: Code inside the assertion macros should not have side effects
+that affect the operation of the program, as they may get compiled out.
+
+`G_DISABLE_CHECKS`
+---
+
+This macro is similar to `G_DISABLE_ASSERT`, it affects third-party
+code as mentioned above and the note about `G_DISABLE_ASSERT` applies
+too.
+
+The macros that become non-functional here are `g_return_if_fail()`,
+`g_return_val_if_fail()`, `g_return_if_reached()` and
+`g_return_val_if_reached()`.
+
+This macro also switches off certain checks in the GSignal code.
+
+`G_ENABLE_DEBUG`
+---
+
+Quite a bit of additional debugging code is compiled into GLib when this
+macro is defined, and since it is a globally visible define, third-party code
+may be affected by it similarly to `G_DISABLE_ASSERT`.
+
+The additional code executed/compiled for this macro currently includes the
+following, but this is not an exhaustive list:
+ - extra validity checks for `GDate`
+ - breakpoint abortion for fatal log levels in `gmessages.c` instead of
+ plain `abort()` to allow debuggers trapping and overriding them
+ - added verbosity of `gscanner.c` to catch deprecated code paths
+ - added verbosity of `gutils.c` to catch deprecated code paths
+ - object and type bookkeeping in `gobject.c`
+ - extra validity checks in `gsignal.c`
+ - support for tracking still-alive `GTask`s
diff --git a/docs/macros.txt b/docs/macros.txt
deleted file mode 100644
index ec449f17f..000000000
--- a/docs/macros.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-GLib's configure options and corresponding macros
-=================================================
-
---buildtype={plain,release,minsize,custom}
- none
---buildtype={debug,debugoptimized} [debugoptimized is the default]
- -DG_ENABLE_DEBUG -g
--Dglib_debug=disabled
- Omits G_ENABLE_DEBUG when implied by --buildtype/-Ddebug
--Dglib_debug=enabled
- Defines G_ENABLE_DEBUG regardless of --buildtype/-Ddebug
--Dglib_asserts=false
- -DG_DISABLE_ASSERT
--Dglib_checks=false
- -DG_DISABLE_CHECKS
-
-Besides these, there are some local feature specific options, but my main
-focus here is to concentrate on macros that affect overall GLib behaviour
-and/or third party code.
-
-
-Notes on GLib's internal and global macros
-==========================================
-
-G_DISABLE_ASSERT
- The g_assert() and g_assert_not_reached() become non-functional
- with this define. The motivation is to speed up end-user apps by
- avoiding expensive checks.
- This macro can affect third-party code. Defining it when building GLib
- will only disable the assertion macros for GLib itself, but third-party code
- that passes -DG_DISABLE_ASSERT to the compiler upon its own build
- will end up with the non-functional variants after including glib.h
- as well.
- NOTE: Code inside the assertion macros should not have side effects
- that affect the operation of the program.
-G_DISABLE_CHECKS
- This macro is similar to G_DISABLE_ASSERT, it affects third-party
- code as mentioned above and the NOTE about G_DISABLE_ASSERT applies
- too. The macros that become non-functional here are
- g_return_if_fail(), g_return_val_if_fail(), g_return_if_reached() and
- g_return_val_if_reached().
- Additionally the glib_mem_profiler_table and g_mem_profile() from
- gmem.h become non-functional if this macro is supplied.
- This macro also switches off certain checks in the GSignal code.
-G_ENABLE_DEBUG
- Quite a bit of additional debugging code is compiled into GLib for this
- macro, and since it is a globally visible define, third-party code may
- be affected by it similar to G_DISABLE_ASSERT.
- The additional code executed/compiled for this macro currently involve:
- - extra validity checks for GDate
- - memory profiling traps in gmem.c (consult debugging.txt for details)
- - BREAKPOINT abortion for fatal log levels in gmessage.c instead of
- plain abort() to allow debuggers trapping and overriding them
- - added verbosity of gscanner.c to catch deprecated code paths
- - added verbosity of gutils.c to catch deprecated code paths
- - object ref/unref traps (consult debugging.txt) and object bookkeeping
- in gobject.c
- - extra validity checks in gsignal.c \ No newline at end of file
diff --git a/docs/reference/gio/gdbus-codegen.xml b/docs/reference/gio/gdbus-codegen.xml
index 5860fed97..7feed9124 100644
--- a/docs/reference/gio/gdbus-codegen.xml
+++ b/docs/reference/gio/gdbus-codegen.xml
@@ -1156,7 +1156,7 @@ on_handle_hello_world (MyAppFrobber *interface,
<para>
The generated C code currently happens to be annotated with <ulink
url="http://www.gtk.org/gtk-doc/">gtk-doc</ulink> / <ulink
- url="https://wiki.gnome.org/Projects/GObjectIntrospection">GObject
+ url="https://gi.readthedocs.io/en/latest/">GObject
Introspection</ulink> comments / annotations. The layout and
contents might change in the future so no guarantees about
e.g. <literal>SECTION</literal> usage etc. is given.
diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt
index 63d167678..f5737ef42 100644
--- a/docs/reference/gio/gio-sections-common.txt
+++ b/docs/reference/gio/gio-sections-common.txt
@@ -1934,6 +1934,8 @@ g_resolver_lookup_service
g_resolver_lookup_service_async
g_resolver_lookup_service_finish
g_resolver_free_targets
+g_resolver_get_timeout
+g_resolver_set_timeout
<SUBSECTION>
GResolverRecordType
g_resolver_lookup_records
diff --git a/docs/reference/gio/meson.build b/docs/reference/gio/meson.build
index 35f0ba552..38696a1c6 100644
--- a/docs/reference/gio/meson.build
+++ b/docs/reference/gio/meson.build
@@ -108,7 +108,6 @@ if get_option('gtk_doc')
ignore_headers += [
'gfiledescriptorbased.h',
'gunixmounts.h',
- 'gunixfdlist.h',
'gunixfdmessage.h',
'gunixinputstream.h',
'gunixoutputstream.h',
diff --git a/docs/reference/gio/overview.xml b/docs/reference/gio/overview.xml
index 5f2afc65e..b93a17a09 100644
--- a/docs/reference/gio/overview.xml
+++ b/docs/reference/gio/overview.xml
@@ -154,7 +154,7 @@
</para>
<figure id="gvfs-overview">
- <title>GIO in the GTK+ library stack</title>
+ <title>GIO in the GTK library stack</title>
<graphic fileref="gvfs-overview.png" format="PNG"></graphic>
</figure>
@@ -166,7 +166,7 @@
</para>
<para>
One of the big advantages of putting the VFS in the GLib layer
- is that GTK+ can directly use it, e.g. in the filechooser.
+ is that GTK can directly use it, e.g. in the filechooser.
</para>
</chapter>
diff --git a/docs/reference/glib/building.xml b/docs/reference/glib/building.xml
index dd1a4495b..2ae52e8dd 100644
--- a/docs/reference/glib/building.xml
+++ b/docs/reference/glib/building.xml
@@ -49,7 +49,7 @@
aliasing and cannot be guaranteed to work.
</para>
<para>
- The GTK+ documentation contains
+ The GTK documentation contains
<ulink url="https://developer.gnome.org/gtk3/stable/gtk-building.html">further details</ulink>
about the build process and ways to influence it.
</para>
@@ -60,7 +60,7 @@
Before you can compile the GLib library, you need to have
various other tools and libraries installed on your system.
If you are building from a release archive, you will need
- <ulink url="https://wiki.gnome.org/Projects/GLib/CompilerRequirements">a compliant C toolchain</ulink>,
+ <ulink url="https://gitlab.gnome.org/GNOME/glib/-/blob/main/docs/toolchain-requirements.md">a compliant C toolchain</ulink>,
<application>Meson</application>, and <application>pkg-config</application>;
the requirements are the same when building from a Git repository clone
of GLib.
diff --git a/docs/reference/glib/glib-sections.txt.in b/docs/reference/glib/glib-sections.txt.in
index 3703198bd..60e87af5b 100644
--- a/docs/reference/glib/glib-sections.txt.in
+++ b/docs/reference/glib/glib-sections.txt.in
@@ -586,6 +586,7 @@ g_timeout_add_once
g_timeout_add_full
g_timeout_add_seconds
g_timeout_add_seconds_full
+g_timeout_add_seconds_once
<SUBSECTION>
g_idle_source_new
@@ -3401,6 +3402,7 @@ g_test_trap_assertions
g_assertion_message
g_assertion_message_expr
g_assertion_message_cmpstr
+g_assertion_message_cmpint
g_assertion_message_cmpnum
g_assertion_message_error
g_test_assert_expected_messages_internal
@@ -3689,12 +3691,14 @@ g_ref_count_init
g_ref_count_inc
g_ref_count_dec
g_ref_count_compare
+G_REF_COUNT_INIT
<SUBSECTION>
gatomicrefcount
g_atomic_ref_count_init
g_atomic_ref_count_inc
g_atomic_ref_count_dec
g_atomic_ref_count_compare
+G_ATOMIC_REF_COUNT_INIT
</SECTION>
<SECTION>
diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build
index 114de49da..3cfff2f0b 100644
--- a/docs/reference/glib/meson.build
+++ b/docs/reference/glib/meson.build
@@ -113,35 +113,37 @@ if get_option('man')
endforeach
endif
-# GVariant specification is currently standalone
-rst2html5 = find_program('rst2html5', 'rst2html5.py', required: false)
+if get_option('gtk_doc')
+ # GVariant specification is currently standalone
+ rst2html5 = find_program('rst2html5', 'rst2html5.py', required: false)
-if rst2html5.found()
- spec_path = glib_datadir / 'doc' / 'glib-2.0'
+ if rst2html5.found()
+ spec_path = glib_datadir / 'doc' / 'glib-2.0'
- figures = files(
- 'gvariant-byte-boundaries.svg',
- 'gvariant-integer-and-string-structure.svg',
- 'gvariant-integer-array.svg',
- 'gvariant-string-array.svg',
- )
+ figures = files(
+ 'gvariant-byte-boundaries.svg',
+ 'gvariant-integer-and-string-structure.svg',
+ 'gvariant-integer-array.svg',
+ 'gvariant-string-array.svg',
+ )
- custom_target('gvariant-specification-1.0',
- input: 'gvariant-specification-1.0.rst',
- output: 'gvariant-specification-1.0.html',
- command: [
- rst2html5,
- '@INPUT@',
- ],
- capture: true,
- install: true,
- install_dir: spec_path,
- install_tag: 'doc',
- depend_files: figures,
- )
+ custom_target('gvariant-specification-1.0',
+ input: 'gvariant-specification-1.0.rst',
+ output: 'gvariant-specification-1.0.html',
+ command: [
+ rst2html5,
+ '@INPUT@',
+ ],
+ capture: true,
+ install: true,
+ install_dir: spec_path,
+ install_tag: 'doc',
+ depend_files: figures,
+ )
- install_data(figures,
- install_dir : spec_path,
- install_tag : 'doc',
- )
-endif \ No newline at end of file
+ install_data(figures,
+ install_dir : spec_path,
+ install_tag : 'doc',
+ )
+ endif
+endif
diff --git a/docs/reference/glib/programming.xml b/docs/reference/glib/programming.xml
index 52df907e8..9efa19d33 100644
--- a/docs/reference/glib/programming.xml
+++ b/docs/reference/glib/programming.xml
@@ -20,6 +20,47 @@ General considerations when programming with GLib
<title>Writing GLib Applications</title>
<refsect2>
+<title>Memory Allocations</title>
+
+<para>
+Unless otherwise specified, all functions which allocate memory in GLib will
+abort the process if heap allocation fails. This is because it is too hard to
+recover from allocation failures in any non-trivial program and, in particular,
+to test all the allocation failure code paths.
+</para>
+</refsect2>
+
+<refsect2>
+<title>UTF-8 and String Encoding</title>
+
+<para>
+All GLib, GObject and GIO functions accept and return strings in
+<ulink url="https://en.wikipedia.org/wiki/UTF-8">UTF-8 encoding</ulink>
+unless otherwise specified.
+</para>
+
+<para>
+Input strings to function calls are <emphasis>not</emphasis> checked to see if
+they are valid UTF-8: it is the application developer’s responsibility to
+validate input strings at the time of input, either at the program or library
+boundary, and to only use valid UTF-8 string constants in their application.
+If GLib were to UTF-8 validate all string inputs to all functions, there would
+be a significant drop in performance.
+</para>
+
+<para>Similarly, output strings from functions are guaranteed to be in UTF-8,
+and this does not need to be validated by the calling function. If a function
+returns invalid UTF-8 (and is not documented as doing so), that’s a bug.
+</para>
+
+<para>
+See <link linkend='g-utf8-validate'><function>g_utf8_validate()</function></link>
+and <link linkend='g-utf8-make-valid'><function>g_utf8_make_valid()</function></link>
+for validating UTF-8 input.
+</para>
+</refsect2>
+
+<refsect2>
<title>Threads</title>
<para>
@@ -35,15 +76,22 @@ will always have at least 2 threads.
</para>
<para>
+In particular, this means that programs must only use
+<ulink url="man:signal-safety(7)">async-signal-safe functions</ulink> between
+calling <function>fork()</function> and <function>exec()</function>, even if
+they haven’t explicitly spawned another thread yet.
+</para>
+
+<para>
See the sections on <link linkend="glib-Threads">threads</link> and
-<link linkend="glib-Thread-Pools">threadpools</link> for GLib APIs that
+<link linkend="glib-Thread-Pools">thread pools</link> for GLib APIs that
support multithreaded applications.
</para>
</refsect2>
<refsect2>
-<title>Security</title>
+<title>Security and setuid use</title>
<para>
When writing code that runs with elevated privileges, it is important
@@ -56,8 +104,17 @@ excellent book on this topic,
When it comes to GLib and its associated libraries, GLib and
GObject are generally fine to use in code that runs with elevated
privileges; they don't load modules (executable code in shared objects)
-or run other programs 'behind your back'. GIO has to be used
-carefully in privileged programs, see the <ulink url="http://developer.gnome.org/gio/stable/ch02.html">GIO documentation</ulink> for details.
+or run other programs ‘behind your back’. GIO, however, is not designed to be
+used in privileged programs, either ones which are spawned by a privileged
+process, or ones which are run with a setuid bit set.
+</para>
+
+<para>
+setuid programs should always reset their environment to contain only
+known-safe values before calling into non-trivial libraries such as GIO. This
+reduces the risk of an attacker-controlled environment variable being used to
+get a privileged GIO process to run arbitrary code via loading a GIO module or
+similar.
</para>
</refsect2>
diff --git a/docs/reference/gobject/tut_gobject.xml b/docs/reference/gobject/tut_gobject.xml
index 7754fec1e..53f38abb2 100644
--- a/docs/reference/gobject/tut_gobject.xml
+++ b/docs/reference/gobject/tut_gobject.xml
@@ -19,7 +19,7 @@
<listitem><para>Generic per-object properties with set/get function pairs</para></listitem>
<listitem><para>Easy use of signals</para></listitem>
</itemizedlist>
- All the GNOME libraries which use the GLib type system (like GTK+ and GStreamer)
+ All the GNOME libraries which use the GLib type system (like GTK and GStreamer)
inherit from <link linkend="GObject"><type>GObject</type></link> which is why it is important to understand
the details of how it works.
</para>
diff --git a/docs/reference/gobject/tut_gsignal.xml b/docs/reference/gobject/tut_gsignal.xml
index 5559673cb..d690d1690 100644
--- a/docs/reference/gobject/tut_gsignal.xml
+++ b/docs/reference/gobject/tut_gsignal.xml
@@ -10,7 +10,7 @@
<para>
Closures are central to the concept of asynchronous signal delivery
- which is widely used throughout GTK+ and GNOME applications. A closure is an
+ which is widely used throughout GTK and GNOME applications. A closure is an
abstraction, a generic representation of a callback. It is a small structure
which contains three objects:
<itemizedlist>
@@ -37,9 +37,9 @@ return_type function_callback (… , gpointer user_data);
<footnote><para>
In practice, closures sit at the boundary of language runtimes: if you are
writing Python code and one of your Python callbacks receives a signal from
- a GTK+ widget, the C code in GTK+ needs to execute your Python
- code. The closure invoked by the GTK+ object invokes the Python callback:
- it behaves as a normal C object for GTK+ and as a normal Python object for
+ a GTK widget, the C code in GTK needs to execute your Python
+ code. The closure invoked by the GTK object invokes the Python callback:
+ it behaves as a normal C object for GTK and as a normal Python object for
Python code.
</para></footnote>
The GObject library provides a simple <link linkend="GCClosure"><type>GCClosure</type></link> type which
@@ -179,8 +179,8 @@ g_cclosure_marshal_VOID__INT (GClosure *closure,
<para>
GObject's signals have nothing to do with standard UNIX signals: they connect
arbitrary application-specific events with any number of listeners.
- For example, in GTK+, every user event (keystroke or mouse move) is received
- from the windowing system and generates a GTK+ event in the form of a signal emission
+ For example, in GTK, every user event (keystroke or mouse move) is received
+ from the windowing system and generates a GTK event in the form of a signal emission
on the widget object instance.
</para>
diff --git a/docs/reference/gobject/tut_howto.xml b/docs/reference/gobject/tut_howto.xml
index 9bff49b56..82419239a 100644
--- a/docs/reference/gobject/tut_howto.xml
+++ b/docs/reference/gobject/tut_howto.xml
@@ -17,7 +17,7 @@
<para>
This chapter focuses on the implementation of a subtype of GObject, for
- example to create a custom class hierarchy, or to subclass a GTK+ widget.
+ example to create a custom class hierarchy, or to subclass a GTK widget.
</para>
<para>
@@ -55,7 +55,7 @@
<filename>viewer_file.c</filename>.</para></listitem>
<listitem><para>Do not separate the prefix from the typename:
<filename>viewerfile.h</filename> and <filename>viewerfile.c</filename>.
- (this is the convention used by GTK+)</para></listitem>
+ (this is the convention used by GTK)</para></listitem>
</itemizedlist>
Some people like the first two solutions better: it makes reading file
names easier for those with poor eyesight.
diff --git a/docs/reference/gobject/tut_intro.xml b/docs/reference/gobject/tut_intro.xml
index 7614bf013..87e8a4984 100644
--- a/docs/reference/gobject/tut_intro.xml
+++ b/docs/reference/gobject/tut_intro.xml
@@ -6,7 +6,7 @@
<title>Background</title>
<para>
- GObject, and its lower-level type system, GType, are used by GTK+ and most GNOME libraries to
+ GObject, and its lower-level type system, GType, are used by GTK and most GNOME libraries to
provide:
<itemizedlist>
<listitem><para>object-oriented C-based APIs and</para></listitem>
diff --git a/docs/reference/gobject/tut_tools.xml b/docs/reference/gobject/tut_tools.xml
index f1076e832..c56431eaa 100644
--- a/docs/reference/gobject/tut_tools.xml
+++ b/docs/reference/gobject/tut_tools.xml
@@ -62,7 +62,7 @@
Yet another tool that you may find helpful when working with
GObjects is <ulink
url="http://sourceforge.net/projects/g-inspector">G-Inspector</ulink>. It
- is able to display GLib/GTK+ objects and their properties.
+ is able to display GLib/GTK objects and their properties.
</para>
</chapter>
@@ -90,7 +90,7 @@ break g_object_unref if _object == 0xcafebabe
<chapter id="tools-gtkdoc">
<title>Writing API docs</title>
- <para>The API documentation for most of the GLib, GObject, GTK+ and GNOME
+ <para>The API documentation for most of the GLib, GObject, GTK and GNOME
libraries is built with a combination of complex tools. Typically, the part of
the documentation which describes the behavior of each function is extracted
from the specially-formatted source code comments by a tool named gtk-doc which
diff --git a/docs/supported-platforms.md b/docs/supported-platforms.md
index fbda4266c..43b652d8f 100644
--- a/docs/supported-platforms.md
+++ b/docs/supported-platforms.md
@@ -32,14 +32,14 @@ GLib is regularly built on at least the following systems:
* FreeBSD: https://wiki.gnome.org/Projects/Jhbuild/FreeBSD
* openSUSE: https://build.opensuse.org/package/show/GNOME:Factory/glib2
* CI runners, https://gitlab.gnome.org/GNOME/glib/blob/main/.gitlab-ci.yml:
- * Fedora (34, https://gitlab.gnome.org/GNOME/glib/-/blob/main/.gitlab-ci/fedora.Dockerfile)
- * Debian (Bullseye, https://gitlab.gnome.org/GNOME/glib/-/blob/main/.gitlab-ci/debian-stable.Dockerfile)
- * Windows (MinGW64)
- * Windows (msys2-mingw32)
- * Windows (Visual Studio 2017, and a static linking version)
- * Android (NDK r23b, API 31, arm64, https://gitlab.gnome.org/GNOME/glib/-/blob/main/.gitlab-ci/android-ndk.sh)
- * FreeBSD (12 and 13)
- * macOS
+ - Fedora (34, https://gitlab.gnome.org/GNOME/glib/-/blob/main/.gitlab-ci/fedora.Dockerfile)
+ - Debian (Bullseye, https://gitlab.gnome.org/GNOME/glib/-/blob/main/.gitlab-ci/debian-stable.Dockerfile)
+ - Windows (MinGW64)
+ - Windows (msys2-mingw32)
+ - Windows (Visual Studio 2017, and a static linking version)
+ - Android (NDK r23b, API 31, arm64, https://gitlab.gnome.org/GNOME/glib/-/blob/main/.gitlab-ci/android-ndk.sh)
+ - FreeBSD (12 and 13)
+ - macOS
If other platforms are to be supported, we need to set up regular CI testing for
them. Please contact us if you want to help.
diff --git a/docs/toolchain-requirements.md b/docs/toolchain-requirements.md
index 8028cd509..b432be510 100644
--- a/docs/toolchain-requirements.md
+++ b/docs/toolchain-requirements.md
@@ -139,7 +139,7 @@ Selected C99 features
_Hard requirement._
-Starting with GLib 2.52 and GTK+ 3.90, we will be using the following C99
+Starting with GLib 2.52 and GTK 3.90, we will be using the following C99
features where appropriate:
* Compound literals
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 3708e812c..c52f94cba 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -2230,7 +2230,7 @@ g_application_register (GApplication *application,
* Increases the use count of @application.
*
* Use this function to indicate that the application has a reason to
- * continue to run. For example, g_application_hold() is called by GTK+
+ * continue to run. For example, g_application_hold() is called by GTK
* when a toplevel window is on the screen.
*
* To cancel the hold, call g_application_release().
diff --git a/gio/gfile.c b/gio/gfile.c
index 94786c84a..31da0b05e 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -2807,6 +2807,11 @@ g_file_build_attribute_list_for_copy (GFile *file,
first = TRUE;
s = g_string_new ("");
+ /* Always query the source file size, even though we can’t set that on the
+ * destination. This is useful for the copy functions. */
+ first = FALSE;
+ g_string_append (s, G_FILE_ATTRIBUTE_STANDARD_SIZE);
+
if (attributes)
{
for (i = 0; i < attributes->n_infos; i++)
@@ -3002,6 +3007,122 @@ copy_stream_with_progress (GInputStream *in,
return res;
}
+#ifdef HAVE_COPY_FILE_RANGE
+static gboolean
+do_copy_file_range (int fd_in,
+ loff_t *off_in,
+ int fd_out,
+ loff_t *off_out,
+ size_t len,
+ size_t *bytes_transferred,
+ GError **error)
+{
+ ssize_t result;
+
+ do
+ {
+ result = copy_file_range (fd_in, off_in, fd_out, off_out, len, 0);
+
+ if (result == -1)
+ {
+ int errsv = errno;
+
+ if (errsv == EINTR)
+ {
+ continue;
+ }
+ else if (errsv == ENOSYS || errsv == EINVAL || errsv == EOPNOTSUPP || errsv == EXDEV)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Copy file range not supported"));
+ }
+ else
+ {
+ g_set_error (error, G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ _("Error splicing file: %s"),
+ g_strerror (errsv));
+ }
+
+ return FALSE;
+ }
+ } while (result == -1);
+
+ g_assert (result >= 0);
+ *bytes_transferred = result;
+
+ return TRUE;
+}
+
+static gboolean
+copy_file_range_with_progress (GInputStream *in,
+ GFileInfo *in_info,
+ GOutputStream *out,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GError **error)
+{
+ goffset total_size, last_notified_size;
+ size_t copy_len;
+ loff_t offset_in;
+ loff_t offset_out;
+ int fd_in, fd_out;
+
+ fd_in = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (in));
+ fd_out = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (out));
+
+ g_assert (g_file_info_has_attribute (in_info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
+ total_size = g_file_info_get_size (in_info);
+
+ /* Bail out if the reported size of the file is zero. It might be zero, but it
+ * might also just be a kernel file in /proc. They report their file size as
+ * zero, but then have data when you start reading. Go to the fallback code
+ * path for those. */
+ if (total_size == 0)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Copy file range not supported"));
+ return FALSE;
+ }
+
+ offset_in = offset_out = 0;
+ copy_len = total_size;
+ last_notified_size = 0;
+
+ /* Call copy_file_range() in a loop until the whole contents are copied. For
+ * smaller files, this loop will iterate only once. For larger files, the
+ * kernel (at least, kernel 6.1.6) will return after 2GB anyway, so that gives
+ * us more loop iterations and more progress reporting. */
+ while (copy_len > 0)
+ {
+ size_t n_copied;
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error) ||
+ !do_copy_file_range (fd_in, &offset_in, fd_out, &offset_out, copy_len, &n_copied, error))
+ return FALSE;
+
+ if (n_copied == 0)
+ break;
+
+ g_assert (n_copied <= copy_len);
+ copy_len -= n_copied;
+
+ if (progress_callback)
+ {
+ progress_callback (offset_in, total_size, progress_callback_data);
+ last_notified_size = total_size;
+ }
+ }
+
+ /* Make sure we send full copied size */
+ if (progress_callback && last_notified_size != total_size)
+ progress_callback (offset_in, total_size, progress_callback_data);
+
+ return TRUE;
+}
+#endif /* HAVE_COPY_FILE_RANGE */
+
#ifdef HAVE_SPLICE
static gboolean
@@ -3042,6 +3163,7 @@ retry:
static gboolean
splice_stream_with_progress (GInputStream *in,
+ GFileInfo *in_info,
GOutputStream *out,
GCancellable *cancellable,
GFileProgressCallback progress_callback,
@@ -3085,10 +3207,8 @@ splice_stream_with_progress (GInputStream *in,
/* avoid performance impact of querying total size when it's not needed */
if (progress_callback)
{
- struct stat sbuf;
-
- if (fstat (fd_in, &sbuf) == 0)
- total_size = sbuf.st_size;
+ g_assert (g_file_info_has_attribute (in_info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
+ total_size = g_file_info_get_size (in_info);
}
if (total_size == -1)
@@ -3151,6 +3271,7 @@ splice_stream_with_progress (GInputStream *in,
#ifdef __linux__
static gboolean
btrfs_reflink_with_progress (GInputStream *in,
+ GFileInfo *in_info,
GOutputStream *out,
GFileInfo *info,
GCancellable *cancellable,
@@ -3169,10 +3290,8 @@ btrfs_reflink_with_progress (GInputStream *in,
/* avoid performance impact of querying total size when it's not needed */
if (progress_callback)
{
- struct stat sbuf;
-
- if (fstat (fd_in, &sbuf) == 0)
- total_size = sbuf.st_size;
+ g_assert (g_file_info_has_attribute (in_info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
+ total_size = g_file_info_get_size (in_info);
}
if (total_size == -1)
@@ -3376,7 +3495,7 @@ file_copy_fallback (GFile *source,
{
GError *reflink_err = NULL;
- if (!btrfs_reflink_with_progress (in, out, info, cancellable,
+ if (!btrfs_reflink_with_progress (in, info, out, info, cancellable,
progress_callback, progress_callback_data,
&reflink_err))
{
@@ -3398,12 +3517,36 @@ file_copy_fallback (GFile *source,
}
#endif
+#ifdef HAVE_COPY_FILE_RANGE
+ if (G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out))
+ {
+ GError *copy_file_range_error = NULL;
+
+ if (copy_file_range_with_progress (in, info, out, cancellable,
+ progress_callback, progress_callback_data,
+ &copy_file_range_error))
+ {
+ ret = TRUE;
+ goto out;
+ }
+ else if (!g_error_matches (copy_file_range_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
+ {
+ g_propagate_error (error, g_steal_pointer (&copy_file_range_error));
+ goto out;
+ }
+ else
+ {
+ g_clear_error (&copy_file_range_error);
+ }
+ }
+#endif /* HAVE_COPY_FILE_RANGE */
+
#ifdef HAVE_SPLICE
if (G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out))
{
GError *splice_err = NULL;
- if (!splice_stream_with_progress (in, out, cancellable,
+ if (!splice_stream_with_progress (in, info, out, cancellable,
progress_callback, progress_callback_data,
&splice_err))
{
diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c
index d9c7d70f9..ca42add8e 100644
--- a/gio/gfileinfo.c
+++ b/gio/gfileinfo.c
@@ -1500,8 +1500,8 @@ g_file_info_set_attribute_int64 (GFileInfo *info,
*value_ptr = g_file_info_find_value (info, attr); \
if (G_UNLIKELY (*value_ptr == NULL)) \
{ \
- g_debug ("GFileInfo created without " attribute_name); \
- return error_value; \
+ g_critical ("GFileInfo created without " attribute_name); \
+ g_return_val_if_reached (error_value); \
} \
} G_STMT_END
@@ -1837,9 +1837,9 @@ g_file_info_get_modification_time (GFileInfo *info,
if (G_UNLIKELY (value == NULL))
{
- g_debug ("GFileInfo created without " G_FILE_ATTRIBUTE_TIME_MODIFIED);
+ g_critical ("GFileInfo created without " G_FILE_ATTRIBUTE_TIME_MODIFIED);
result->tv_sec = result->tv_usec = 0;
- return;
+ g_return_if_reached ();
}
result->tv_sec = _g_file_attribute_value_get_uint64 (value);
diff --git a/gio/giomodule.c b/gio/giomodule.c
index 47b8de27e..17fabe640 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -1273,7 +1273,9 @@ get_gio_module_dir (void)
module_dir = g_strdup (GIO_MODULE_DIR);
#ifdef __APPLE__
#include "TargetConditionals.h"
-#if TARGET_OS_OSX
+/* Only auto-relocate on macOS, not watchOS etc; older macOS SDKs only define TARGET_OS_MAC */
+#if (defined (TARGET_OS_OSX) && TARGET_OS_OSX) || \
+ (!defined (TARGET_OS_OSX) && defined (TARGET_OS_MAC) && TARGET_OS_MAC)
#include <dlfcn.h>
{
g_autofree gchar *path = NULL;
diff --git a/gio/gregistrysettingsbackend.c b/gio/gregistrysettingsbackend.c
index 772fae037..88ae913ce 100644
--- a/gio/gregistrysettingsbackend.c
+++ b/gio/gregistrysettingsbackend.c
@@ -2319,8 +2319,7 @@ g_registry_settings_backend_class_init (GRegistrySettingsBackendClass *class)
g_object_class_install_property (object_class,
PROP_REGISTRY_KEY,
g_param_spec_string ("registry-key",
- P_("Root registry key"),
- P_("The path to the registry key where settings are stored"),
+ NULL, NULL,
"HKEY_CURRENT_USER\\Software\\GSettings",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
diff --git a/gio/gresolver.c b/gio/gresolver.c
index 6a735e8d9..676f1e271 100644
--- a/gio/gresolver.c
+++ b/gio/gresolver.c
@@ -55,8 +55,18 @@
* #GNetworkAddress and #GNetworkService provide wrappers around
* #GResolver functionality that also implement #GSocketConnectable,
* making it easy to connect to a remote host/service.
+ *
+ * The default resolver (see g_resolver_get_default()) has a timeout of 30s set
+ * on it since GLib 2.78. Earlier versions of GLib did not support resolver
+ * timeouts.
*/
+typedef enum {
+ PROP_TIMEOUT = 1,
+} GResolverProperty;
+
+static GParamSpec *props[PROP_TIMEOUT + 1] = { NULL, };
+
enum {
RELOAD,
LAST_SIGNAL
@@ -65,11 +75,11 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
struct _GResolverPrivate {
+ unsigned timeout_ms;
+
#ifdef G_OS_UNIX
GMutex mutex;
time_t resolv_conf_timestamp; /* protected by @mutex */
-#else
- int dummy;
#endif
};
@@ -152,6 +162,42 @@ g_resolver_real_lookup_service_finish (GResolver *resolver,
}
static void
+g_resolver_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GResolver *self = G_RESOLVER (object);
+
+ switch ((GResolverProperty) prop_id)
+ {
+ case PROP_TIMEOUT:
+ g_value_set_uint (value, g_resolver_get_timeout (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_resolver_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GResolver *self = G_RESOLVER (object);
+
+ switch ((GResolverProperty) prop_id)
+ {
+ case PROP_TIMEOUT:
+ g_resolver_set_timeout (self, g_value_get_uint (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
g_resolver_finalize (GObject *object)
{
#ifdef G_OS_UNIX
@@ -168,6 +214,8 @@ g_resolver_class_init (GResolverClass *resolver_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (resolver_class);
+ object_class->get_property = g_resolver_get_property;
+ object_class->set_property = g_resolver_set_property;
object_class->finalize = g_resolver_finalize;
/* Automatically pass these over to the lookup_records methods */
@@ -176,6 +224,31 @@ g_resolver_class_init (GResolverClass *resolver_class)
resolver_class->lookup_service_finish = g_resolver_real_lookup_service_finish;
/**
+ * GResolver:timeout:
+ *
+ * The timeout applied to all resolver lookups, in milliseconds.
+ *
+ * This may be changed through the lifetime of the #GResolver. The new value
+ * will apply to any lookups started after the change, but not to any
+ * already-ongoing lookups.
+ *
+ * If this is `0`, no timeout is applied to lookups.
+ *
+ * No timeout was applied to lookups before this property was added in
+ * GLib 2.78.
+ *
+ * Since: 2.78
+ */
+ props[PROP_TIMEOUT] =
+ g_param_spec_uint ("timeout",
+ P_("Timeout"),
+ P_("Timeout (ms) applied to all resolver lookups"),
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (object_class, G_N_ELEMENTS (props), props);
+
+ /**
* GResolver::reload:
* @resolver: a #GResolver
*
@@ -230,7 +303,9 @@ g_resolver_get_default (void)
G_LOCK (default_resolver);
if (!default_resolver)
- default_resolver = g_object_new (G_TYPE_THREADED_RESOLVER, NULL);
+ default_resolver = g_object_new (G_TYPE_THREADED_RESOLVER,
+ "timeout", 30000,
+ NULL);
ret = g_object_ref (default_resolver);
G_UNLOCK (default_resolver);
@@ -1245,6 +1320,49 @@ g_resolver_get_serial (GResolver *resolver)
}
/**
+ * g_resolver_get_timeout:
+ * @resolver: a #GResolver
+ *
+ * Get the timeout applied to all resolver lookups. See #GResolver:timeout.
+ *
+ * Returns: the resolver timeout, in milliseconds, or `0` for no timeout
+ * Since: 2.78
+ */
+unsigned
+g_resolver_get_timeout (GResolver *resolver)
+{
+ GResolverPrivate *priv = g_resolver_get_instance_private (resolver);
+
+ g_return_val_if_fail (G_IS_RESOLVER (resolver), 0);
+
+ return priv->timeout_ms;
+}
+
+/**
+ * g_resolver_set_timeout:
+ * @resolver: a #GResolver
+ * @timeout_ms: timeout in milliseconds, or `0` for no timeouts
+ *
+ * Set the timeout applied to all resolver lookups. See #GResolver:timeout.
+ *
+ * Since: 2.78
+ */
+void
+g_resolver_set_timeout (GResolver *resolver,
+ unsigned timeout_ms)
+{
+ GResolverPrivate *priv = g_resolver_get_instance_private (resolver);
+
+ g_return_if_fail (G_IS_RESOLVER (resolver));
+
+ if (priv->timeout_ms == timeout_ms)
+ return;
+
+ priv->timeout_ms = timeout_ms;
+ g_object_notify_by_pspec (G_OBJECT (resolver), props[PROP_TIMEOUT]);
+}
+
+/**
* g_resolver_error_quark:
*
* Gets the #GResolver Error Quark.
diff --git a/gio/gresolver.h b/gio/gresolver.h
index 2dffeadbf..9b9a8a81a 100644
--- a/gio/gresolver.h
+++ b/gio/gresolver.h
@@ -277,6 +277,11 @@ GList *g_resolver_lookup_records_finish (GResolver
GIO_AVAILABLE_IN_ALL
void g_resolver_free_targets (GList *targets);
+GIO_AVAILABLE_IN_2_78
+unsigned g_resolver_get_timeout (GResolver *resolver);
+GIO_AVAILABLE_IN_2_78
+void g_resolver_set_timeout (GResolver *resolver,
+ unsigned timeout_ms);
/**
* G_RESOLVER_ERROR:
diff --git a/gio/gsocket.c b/gio/gsocket.c
index d25591a17..3411b7785 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -3400,7 +3400,7 @@ g_socket_receive_with_blocking (GSocket *socket,
* pointer, or %NULL
* @buffer: (array length=size) (element-type guint8) (out caller-allocates):
* a buffer to read data into (which should be at least @size bytes long).
- * @size: the number of bytes you want to read from the socket
+ * @size: (in): the number of bytes you want to read from the socket
* @cancellable: (nullable): a %GCancellable or %NULL
* @error: #GError for error reporting, or %NULL to ignore.
*
diff --git a/gio/gtask.c b/gio/gtask.c
index 80df75286..c436110aa 100644
--- a/gio/gtask.c
+++ b/gio/gtask.c
@@ -676,6 +676,58 @@ g_task_init (GTask *task)
task->check_cancellable = TRUE;
}
+#ifdef G_ENABLE_DEBUG
+G_LOCK_DEFINE_STATIC (task_list);
+static GPtrArray *task_list = NULL;
+
+void
+g_task_print_alive_tasks (void)
+{
+ GString *message_str = g_string_new ("");
+
+ G_LOCK (task_list);
+
+ if (task_list != NULL)
+ {
+ g_string_append_printf (message_str, "%u GTasks still alive:", task_list->len);
+ for (guint i = 0; i < task_list->len; i++)
+ {
+ GTask *task = g_ptr_array_index (task_list, i);
+ const gchar *name = g_task_get_name (task);
+ g_string_append_printf (message_str,
+ "\n • GTask %p, %s, ref count: %u, ever_returned: %u, completed: %u",
+ task, (name != NULL) ? name : "(no name set)",
+ ((GObject *) task)->ref_count,
+ task->ever_returned, task->completed);
+ }
+ }
+ else
+ {
+ g_string_append (message_str, "No GTasks still alive");
+ }
+
+ G_UNLOCK (task_list);
+
+ g_message ("%s", message_str->str);
+ g_string_free (message_str, TRUE);
+}
+
+static void
+g_task_constructed (GObject *object)
+{
+ GTask *task = G_TASK (object);
+
+ G_OBJECT_CLASS (g_task_parent_class)->constructed (object);
+
+ /* Track pending tasks for debugging purposes */
+ G_LOCK (task_list);
+ if (G_UNLIKELY (task_list == NULL))
+ task_list = g_ptr_array_new ();
+ g_ptr_array_add (task_list, task);
+ G_UNLOCK (task_list);
+}
+#endif /* G_ENABLE_DEBUG */
+
static void
g_task_finalize (GObject *object)
{
@@ -732,6 +784,16 @@ g_task_finalize (GObject *object)
g_cond_clear (&task->cond);
}
+ /* Track pending tasks for debugging purposes */
+#ifdef G_ENABLE_DEBUG
+ G_LOCK (task_list);
+ g_assert (task_list != NULL);
+ g_ptr_array_remove_fast (task_list, task);
+ if (G_UNLIKELY (task_list->len == 0))
+ g_clear_pointer (&task_list, g_ptr_array_unref);
+ G_UNLOCK (task_list);
+#endif /* G_ENABLE_DEBUG */
+
G_OBJECT_CLASS (g_task_parent_class)->finalize (object);
}
@@ -1634,6 +1696,13 @@ g_task_start_task_thread (GTask *task,
* tasks), but don't want them to all run at once, you should only queue a
* limited number of them (around ten) at a time.
*
+ * Be aware that if your task depends on other tasks to complete, use of this
+ * function could lead to a livelock if the other tasks also use this function
+ * and enough of them (around 10) execute in a dependency chain, as that will
+ * exhaust the thread pool. If this situation is possible, consider using a
+ * separate worker thread or thread pool explicitly, rather than using
+ * g_task_run_in_thread().
+ *
* Since: 2.36
*/
void
@@ -2309,6 +2378,9 @@ g_task_class_init (GTaskClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+#ifdef G_ENABLE_DEBUG
+ gobject_class->constructed = g_task_constructed;
+#endif
gobject_class->get_property = g_task_get_property;
gobject_class->finalize = g_task_finalize;
diff --git a/gio/gtask.h b/gio/gtask.h
index 1c2490fab..7642d2c68 100644
--- a/gio/gtask.h
+++ b/gio/gtask.h
@@ -194,6 +194,12 @@ gboolean g_task_had_error (GTask *task);
GIO_AVAILABLE_IN_2_44
gboolean g_task_get_completed (GTask *task);
+/*< private >*/
+#ifndef __GTK_DOC_IGNORE__
+/* Debugging API, not part of the public API */
+void g_task_print_alive_tasks (void);
+#endif /* !__GTK_DOC_IGNORE__ */
+
G_END_DECLS
#endif /* __G_TASK_H__ */
diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c
index 8c5de3355..9ff74e653 100644
--- a/gio/gtestdbus.c
+++ b/gio/gtestdbus.c
@@ -62,13 +62,12 @@ typedef struct
gboolean timed_out;
} WeakNotifyData;
-static gboolean
+static void
on_weak_notify_timeout (gpointer user_data)
{
WeakNotifyData *data = user_data;
data->timed_out = TRUE;
g_main_loop_quit (data->loop);
- return FALSE;
}
static gboolean
@@ -95,7 +94,7 @@ _g_object_unref_and_wait_weak_notify (gpointer object)
g_idle_add (unref_on_idle, object);
/* Make sure we don't block forever */
- timeout_id = g_timeout_add_seconds (30, on_weak_notify_timeout, &data);
+ timeout_id = g_timeout_add_seconds_once (30, on_weak_notify_timeout, &data);
g_main_loop_run (data.loop);
diff --git a/gio/gthreadedresolver.c b/gio/gthreadedresolver.c
index 68b5c20d7..2d94531bf 100644
--- a/gio/gthreadedresolver.c
+++ b/gio/gthreadedresolver.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <string.h>
+#include "glib/glib-private.h"
#include "gthreadedresolver.h"
#include "gnetworkingprivate.h"
@@ -38,12 +39,83 @@
#include "gsocketaddress.h"
#include "gsrvtarget.h"
+/*
+ * GThreadedResolver is a threaded wrapper around the system libc’s
+ * `getaddrinfo()`.
+ *
+ * It has to be threaded, as `getaddrinfo()` is synchronous. libc does provide
+ * `getaddrinfo_a()` as an asynchronous version of `getaddrinfo()`, but it does
+ * not integrate with a poll loop. It requires use of sigevent to notify of
+ * completion of an asynchronous operation. That either emits a signal, or calls
+ * a callback function in a newly spawned thread.
+ *
+ * A signal (`SIGEV_SIGNAL`) can’t be used for completion as (aside from being
+ * another expensive round trip into the kernel) GLib cannot pick a `SIG*`
+ * number which is guaranteed to not be in use elsewhere in the process. Various
+ * other things could be interfering with signal dispositions, such as gdb or
+ * other libraries in the process. Using a `signalfd()`
+ * [cannot improve this situation](https://ldpreload.com/blog/signalfd-is-useless).
+ *
+ * A callback function in a newly spawned thread (`SIGEV_THREAD`) could be used,
+ * but that is very expensive. Internally, glibc currently also just implements
+ * `getaddrinfo_a()`
+ * [using its own thread pool](https://github.com/bminor/glibc/blob/master/resolv/gai_misc.c),
+ * and then
+ * [spawns an additional thread for each completion callback](https://github.com/bminor/glibc/blob/master/resolv/gai_notify.c).
+ * That is very expensive.
+ *
+ * No other appropriate sigevent callback types
+ * [currently exist](https://sourceware.org/bugzilla/show_bug.cgi?id=30287), and
+ * [others agree that sigevent is not great](http://davmac.org/davpage/linux/async-io.html#posixaio).
+ *
+ * Hence, #GThreadedResolver calls the normal synchronous `getaddrinfo()` in its
+ * own thread pool. Previously, #GThreadedResolver used the thread pool which is
+ * internal to #GTask by calling g_task_run_in_thread(). That lead to exhaustion
+ * of the #GTask thread pool in some situations, though, as DNS lookups are
+ * quite frequent leaf operations in some use cases. Now, #GThreadedResolver
+ * uses its own private thread pool.
+ *
+ * This is similar to what
+ * [libasyncns](http://git.0pointer.net/libasyncns.git/tree/libasyncns/asyncns.h)
+ * and other multi-threaded users of `getaddrinfo()` do.
+ */
+
+struct _GThreadedResolver
+{
+ GResolver parent_instance;
+
+ GThreadPool *thread_pool; /* (owned) */
+};
G_DEFINE_TYPE (GThreadedResolver, g_threaded_resolver, G_TYPE_RESOLVER)
+static void run_task_in_thread_pool_async (GThreadedResolver *self,
+ GTask *task);
+static void run_task_in_thread_pool_sync (GThreadedResolver *self,
+ GTask *task);
+static void threaded_resolver_worker_cb (gpointer task_data,
+ gpointer user_data);
+
static void
-g_threaded_resolver_init (GThreadedResolver *gtr)
+g_threaded_resolver_init (GThreadedResolver *self)
{
+ self->thread_pool = g_thread_pool_new_full (threaded_resolver_worker_cb,
+ self,
+ (GDestroyNotify) g_object_unref,
+ 20,
+ FALSE,
+ NULL);
+}
+
+static void
+g_threaded_resolver_finalize (GObject *object)
+{
+ GThreadedResolver *self = G_THREADED_RESOLVER (object);
+
+ g_thread_pool_free (self->thread_pool, TRUE, FALSE);
+ self->thread_pool = NULL;
+
+ G_OBJECT_CLASS (g_threaded_resolver_parent_class)->finalize (object);
}
static GResolverError
@@ -67,35 +139,127 @@ g_resolver_error_from_addrinfo_error (gint err)
}
typedef struct {
- char *hostname;
- int address_family;
+ enum {
+ LOOKUP_BY_NAME,
+ LOOKUP_BY_ADDRESS,
+ LOOKUP_RECORDS,
+ } lookup_type;
+
+ union {
+ struct {
+ char *hostname;
+ int address_family;
+ } lookup_by_name;
+ struct {
+ GInetAddress *address; /* (owned) */
+ } lookup_by_address;
+ struct {
+ char *rrname;
+ GResolverRecordType record_type;
+ } lookup_records;
+ };
+
+ GCond cond; /* used for signalling completion of the task when running it sync */
+ GMutex lock;
+
+ GSource *timeout_source; /* (nullable) (owned) */
+ GSource *cancellable_source; /* (nullable) (owned) */
+
+ /* This enum indicates that a particular code path has claimed the
+ * task and is shortly about to call g_task_return_*() on it.
+ * This must be accessed with GThreadedResolver.lock held. */
+ enum
+ {
+ NOT_YET,
+ COMPLETED, /* libc lookup call has completed successfully or errored */
+ TIMED_OUT,
+ CANCELLED,
+ } will_return;
+
+ /* Whether the thread pool thread executing this lookup has finished executing
+ * it and g_task_return_*() has been called on it already.
+ * This must be accessed with GThreadedResolver.lock held. */
+ gboolean has_returned;
} LookupData;
static LookupData *
-lookup_data_new (const char *hostname,
- int address_family)
+lookup_data_new_by_name (const char *hostname,
+ int address_family)
{
- LookupData *data = g_new (LookupData, 1);
- data->hostname = g_strdup (hostname);
- data->address_family = address_family;
- return data;
+ LookupData *data = g_new0 (LookupData, 1);
+ data->lookup_type = LOOKUP_BY_NAME;
+ g_cond_init (&data->cond);
+ g_mutex_init (&data->lock);
+ data->lookup_by_name.hostname = g_strdup (hostname);
+ data->lookup_by_name.address_family = address_family;
+ return g_steal_pointer (&data);
+}
+
+static LookupData *
+lookup_data_new_by_address (GInetAddress *address)
+{
+ LookupData *data = g_new0 (LookupData, 1);
+ data->lookup_type = LOOKUP_BY_ADDRESS;
+ g_cond_init (&data->cond);
+ g_mutex_init (&data->lock);
+ data->lookup_by_address.address = g_object_ref (address);
+ return g_steal_pointer (&data);
+}
+
+static LookupData *
+lookup_data_new_records (const gchar *rrname,
+ GResolverRecordType record_type)
+{
+ LookupData *data = g_new0 (LookupData, 1);
+ data->lookup_type = LOOKUP_RECORDS;
+ g_cond_init (&data->cond);
+ g_mutex_init (&data->lock);
+ data->lookup_records.rrname = g_strdup (rrname);
+ data->lookup_records.record_type = record_type;
+ return g_steal_pointer (&data);
}
static void
lookup_data_free (LookupData *data)
{
- g_free (data->hostname);
+ switch (data->lookup_type) {
+ case LOOKUP_BY_NAME:
+ g_free (data->lookup_by_name.hostname);
+ break;
+ case LOOKUP_BY_ADDRESS:
+ g_clear_object (&data->lookup_by_address.address);
+ break;
+ case LOOKUP_RECORDS:
+ g_free (data->lookup_records.rrname);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (data->timeout_source != NULL)
+ {
+ g_source_destroy (data->timeout_source);
+ g_clear_pointer (&data->timeout_source, g_source_unref);
+ }
+
+ if (data->cancellable_source != NULL)
+ {
+ g_source_destroy (data->cancellable_source);
+ g_clear_pointer (&data->cancellable_source, g_source_unref);
+ }
+
+ g_mutex_clear (&data->lock);
+ g_cond_clear (&data->cond);
+
g_free (data);
}
-static void
-do_lookup_by_name (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
+static GList *
+do_lookup_by_name (const gchar *hostname,
+ int address_family,
+ GCancellable *cancellable,
+ GError **error)
{
- LookupData *lookup_data = task_data;
- const char *hostname = lookup_data->hostname;
struct addrinfo *res = NULL;
GList *addresses;
gint retval;
@@ -111,7 +275,7 @@ do_lookup_by_name (GTask *task,
addrinfo_hints.ai_socktype = SOCK_STREAM;
addrinfo_hints.ai_protocol = IPPROTO_TCP;
- addrinfo_hints.ai_family = lookup_data->address_family;
+ addrinfo_hints.ai_family = address_family;
retval = getaddrinfo (hostname, NULL, &addrinfo_hints, &res);
if (retval == 0)
@@ -137,21 +301,23 @@ do_lookup_by_name (GTask *task,
g_object_unref (sockaddr);
}
+ g_clear_pointer (&res, freeaddrinfo);
+
if (addresses != NULL)
{
addresses = g_list_reverse (addresses);
- g_task_return_pointer (task, addresses,
- (GDestroyNotify)g_resolver_free_addresses);
+ return g_steal_pointer (&addresses);
}
else
{
/* All addresses failed to be converted to GSocketAddresses. */
- g_task_return_new_error (task,
- G_RESOLVER_ERROR,
- G_RESOLVER_ERROR_NOT_FOUND,
- _("Error resolving “%s”: %s"),
- hostname,
- _("No valid addresses were found"));
+ g_set_error (error,
+ G_RESOLVER_ERROR,
+ G_RESOLVER_ERROR_NOT_FOUND,
+ _("Error resolving “%s”: %s"),
+ hostname,
+ _("No valid addresses were found"));
+ return NULL;
}
}
else
@@ -164,16 +330,17 @@ do_lookup_by_name (GTask *task,
error_message = g_strdup ("[Invalid UTF-8]");
#endif
- g_task_return_new_error (task,
- G_RESOLVER_ERROR,
- g_resolver_error_from_addrinfo_error (retval),
- _("Error resolving “%s”: %s"),
- hostname, error_message);
+ g_clear_pointer (&res, freeaddrinfo);
+
+ g_set_error (error,
+ G_RESOLVER_ERROR,
+ g_resolver_error_from_addrinfo_error (retval),
+ _("Error resolving “%s”: %s"),
+ hostname, error_message);
g_free (error_message);
- }
- if (res)
- freeaddrinfo (res);
+ return NULL;
+ }
}
static GList *
@@ -182,17 +349,19 @@ lookup_by_name (GResolver *resolver,
GCancellable *cancellable,
GError **error)
{
+ GThreadedResolver *self = G_THREADED_RESOLVER (resolver);
GTask *task;
GList *addresses;
LookupData *data;
- data = lookup_data_new (hostname, AF_UNSPEC);
+ data = lookup_data_new_by_name (hostname, AF_UNSPEC);
task = g_task_new (resolver, cancellable, NULL, NULL);
g_task_set_source_tag (task, lookup_by_name);
g_task_set_name (task, "[gio] resolver lookup");
- g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free);
- g_task_set_return_on_cancel (task, TRUE);
- g_task_run_in_thread_sync (task, do_lookup_by_name);
+ g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
+
+ run_task_in_thread_pool_sync (self, task);
+
addresses = g_task_propagate_pointer (task, error);
g_object_unref (task);
@@ -224,17 +393,19 @@ lookup_by_name_with_flags (GResolver *resolver,
GCancellable *cancellable,
GError **error)
{
+ GThreadedResolver *self = G_THREADED_RESOLVER (resolver);
GTask *task;
GList *addresses;
LookupData *data;
- data = lookup_data_new (hostname, flags_to_family (flags));
+ data = lookup_data_new_by_name (hostname, flags_to_family (flags));
task = g_task_new (resolver, cancellable, NULL, NULL);
g_task_set_source_tag (task, lookup_by_name_with_flags);
g_task_set_name (task, "[gio] resolver lookup");
- g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free);
- g_task_set_return_on_cancel (task, TRUE);
- g_task_run_in_thread_sync (task, do_lookup_by_name);
+ g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
+
+ run_task_in_thread_pool_sync (self, task);
+
addresses = g_task_propagate_pointer (task, error);
g_object_unref (task);
@@ -249,16 +420,22 @@ lookup_by_name_with_flags_async (GResolver *resolver,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GThreadedResolver *self = G_THREADED_RESOLVER (resolver);
GTask *task;
LookupData *data;
- data = lookup_data_new (hostname, flags_to_family (flags));
+ data = lookup_data_new_by_name (hostname, flags_to_family (flags));
task = g_task_new (resolver, cancellable, callback, user_data);
+
+ g_debug ("%s: starting new lookup for %s with GTask %p, LookupData %p",
+ G_STRFUNC, hostname, task, data);
+
g_task_set_source_tag (task, lookup_by_name_with_flags_async);
g_task_set_name (task, "[gio] resolver lookup");
- g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free);
- g_task_set_return_on_cancel (task, TRUE);
- g_task_run_in_thread (task, do_lookup_by_name);
+ g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
+
+ run_task_in_thread_pool_async (self, task);
+
g_object_unref (task);
}
@@ -297,13 +474,11 @@ lookup_by_name_with_flags_finish (GResolver *resolver,
return g_task_propagate_pointer (G_TASK (result), error);
}
-static void
-do_lookup_by_address (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
+static gchar *
+do_lookup_by_address (GInetAddress *address,
+ GCancellable *cancellable,
+ GError **error)
{
- GInetAddress *address = task_data;
struct sockaddr_storage sockaddr_address;
gsize sockaddr_address_size;
GSocketAddress *gsockaddr;
@@ -319,7 +494,7 @@ do_lookup_by_address (GTask *task,
retval = getnameinfo ((struct sockaddr *) &sockaddr_address, sockaddr_address_size,
name, sizeof (name), NULL, 0, NI_NAMEREQD);
if (retval == 0)
- g_task_return_pointer (task, g_strdup (name), g_free);
+ return g_strdup (name);
else
{
gchar *phys;
@@ -333,14 +508,16 @@ do_lookup_by_address (GTask *task,
#endif
phys = g_inet_address_to_string (address);
- g_task_return_new_error (task,
- G_RESOLVER_ERROR,
- g_resolver_error_from_addrinfo_error (retval),
- _("Error reverse-resolving “%s”: %s"),
- phys ? phys : "(unknown)",
- error_message);
+ g_set_error (error,
+ G_RESOLVER_ERROR,
+ g_resolver_error_from_addrinfo_error (retval),
+ _("Error reverse-resolving “%s”: %s"),
+ phys ? phys : "(unknown)",
+ error_message);
g_free (phys);
g_free (error_message);
+
+ return NULL;
}
}
@@ -350,15 +527,19 @@ lookup_by_address (GResolver *resolver,
GCancellable *cancellable,
GError **error)
{
+ GThreadedResolver *self = G_THREADED_RESOLVER (resolver);
+ LookupData *data = NULL;
GTask *task;
gchar *name;
+ data = lookup_data_new_by_address (address);
task = g_task_new (resolver, cancellable, NULL, NULL);
g_task_set_source_tag (task, lookup_by_address);
g_task_set_name (task, "[gio] resolver lookup");
- g_task_set_task_data (task, g_object_ref (address), g_object_unref);
- g_task_set_return_on_cancel (task, TRUE);
- g_task_run_in_thread_sync (task, do_lookup_by_address);
+ g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
+
+ run_task_in_thread_pool_sync (self, task);
+
name = g_task_propagate_pointer (task, error);
g_object_unref (task);
@@ -372,14 +553,18 @@ lookup_by_address_async (GResolver *resolver,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GThreadedResolver *self = G_THREADED_RESOLVER (resolver);
+ LookupData *data = NULL;
GTask *task;
+ data = lookup_data_new_by_address (address);
task = g_task_new (resolver, cancellable, callback, user_data);
g_task_set_source_tag (task, lookup_by_address_async);
g_task_set_name (task, "[gio] resolver lookup");
- g_task_set_task_data (task, g_object_ref (address), g_object_unref);
- g_task_set_return_on_cancel (task, TRUE);
- g_task_run_in_thread (task, do_lookup_by_address);
+ g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
+
+ run_task_in_thread_pool_async (self, task);
+
g_object_unref (task);
}
@@ -1066,18 +1251,6 @@ g_resolver_records_from_DnsQuery (const gchar *rrname,
#endif
-typedef struct {
- char *rrname;
- GResolverRecordType record_type;
-} LookupRecordsData;
-
-static void
-free_lookup_records_data (LookupRecordsData *lrd)
-{
- g_free (lrd->rrname);
- g_slice_free (LookupRecordsData, lrd);
-}
-
static void
free_records (GList *records)
{
@@ -1093,15 +1266,13 @@ int res_query(const char *, int, int, u_char *, int);
#endif
#endif
-static void
-do_lookup_records (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
+static GList *
+do_lookup_records (const gchar *rrname,
+ GResolverRecordType record_type,
+ GCancellable *cancellable,
+ GError **error)
{
- LookupRecordsData *lrd = task_data;
GList *records;
- GError *error = NULL;
#if defined(G_OS_UNIX)
gint len = 512;
@@ -1125,21 +1296,21 @@ do_lookup_records (GTask *task,
struct __res_state res = { 0, };
if (res_ninit (&res) != 0)
{
- g_task_return_new_error (task, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL,
- _("Error resolving “%s”"), lrd->rrname);
- return;
+ g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL,
+ _("Error resolving “%s”"), rrname);
+ return NULL;
}
#endif
- rrtype = g_resolver_record_type_to_rrtype (lrd->record_type);
+ rrtype = g_resolver_record_type_to_rrtype (record_type);
answer = g_byte_array_new ();
for (;;)
{
g_byte_array_set_size (answer, len * 2);
#if defined(HAVE_RES_NQUERY)
- len = res_nquery (&res, lrd->rrname, C_IN, rrtype, answer->data, answer->len);
+ len = res_nquery (&res, rrname, C_IN, rrtype, answer->data, answer->len);
#else
- len = res_query (lrd->rrname, C_IN, rrtype, answer->data, answer->len);
+ len = res_query (rrname, C_IN, rrtype, answer->data, answer->len);
#endif
/* If answer fit in the buffer then we're done */
@@ -1153,7 +1324,7 @@ do_lookup_records (GTask *task,
}
herr = h_errno;
- records = g_resolver_records_from_res_query (lrd->rrname, rrtype, answer->data, len, herr, &error);
+ records = g_resolver_records_from_res_query (rrname, rrtype, answer->data, len, herr, error);
g_byte_array_free (answer, TRUE);
#ifdef HAVE_RES_NQUERY
@@ -1174,18 +1345,15 @@ do_lookup_records (GTask *task,
DNS_RECORD *results = NULL;
WORD dnstype;
- dnstype = g_resolver_record_type_to_dnstype (lrd->record_type);
- status = DnsQuery_A (lrd->rrname, dnstype, DNS_QUERY_STANDARD, NULL, &results, NULL);
- records = g_resolver_records_from_DnsQuery (lrd->rrname, dnstype, status, results, &error);
+ dnstype = g_resolver_record_type_to_dnstype (record_type);
+ status = DnsQuery_A (rrname, dnstype, DNS_QUERY_STANDARD, NULL, &results, NULL);
+ records = g_resolver_records_from_DnsQuery (rrname, dnstype, status, results, error);
if (results != NULL)
DnsRecordListFree (results, DnsFreeRecordList);
#endif
- if (records)
- g_task_return_pointer (task, records, (GDestroyNotify) free_records);
- else
- g_task_return_error (task, error);
+ return g_steal_pointer (&records);
}
static GList *
@@ -1195,21 +1363,20 @@ lookup_records (GResolver *resolver,
GCancellable *cancellable,
GError **error)
{
+ GThreadedResolver *self = G_THREADED_RESOLVER (resolver);
GTask *task;
GList *records;
- LookupRecordsData *lrd;
+ LookupData *data = NULL;
task = g_task_new (resolver, cancellable, NULL, NULL);
g_task_set_source_tag (task, lookup_records);
g_task_set_name (task, "[gio] resolver lookup records");
- lrd = g_slice_new (LookupRecordsData);
- lrd->rrname = g_strdup (rrname);
- lrd->record_type = record_type;
- g_task_set_task_data (task, lrd, (GDestroyNotify) free_lookup_records_data);
+ data = lookup_data_new_records (rrname, record_type);
+ g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
+
+ run_task_in_thread_pool_sync (self, task);
- g_task_set_return_on_cancel (task, TRUE);
- g_task_run_in_thread_sync (task, do_lookup_records);
records = g_task_propagate_pointer (task, error);
g_object_unref (task);
@@ -1224,20 +1391,19 @@ lookup_records_async (GResolver *resolver,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GThreadedResolver *self = G_THREADED_RESOLVER (resolver);
GTask *task;
- LookupRecordsData *lrd;
+ LookupData *data = NULL;
task = g_task_new (resolver, cancellable, callback, user_data);
g_task_set_source_tag (task, lookup_records_async);
g_task_set_name (task, "[gio] resolver lookup records");
- lrd = g_slice_new (LookupRecordsData);
- lrd->rrname = g_strdup (rrname);
- lrd->record_type = record_type;
- g_task_set_task_data (task, lrd, (GDestroyNotify) free_lookup_records_data);
+ data = lookup_data_new_records (rrname, record_type);
+ g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
+
+ run_task_in_thread_pool_async (self, task);
- g_task_set_return_on_cancel (task, TRUE);
- g_task_run_in_thread (task, do_lookup_records);
g_object_unref (task);
}
@@ -1251,12 +1417,207 @@ lookup_records_finish (GResolver *resolver,
return g_task_propagate_pointer (G_TASK (result), error);
}
+/* Will be called in the GLib worker thread, so must lock all accesses to shared
+ * data. */
+static gboolean
+timeout_cb (gpointer user_data)
+{
+ GTask *task = G_TASK (user_data);
+ LookupData *data = g_task_get_task_data (task);
+ gboolean should_return;
+
+ g_mutex_lock (&data->lock);
+
+ should_return = g_atomic_int_compare_and_exchange (&data->will_return, NOT_YET, TIMED_OUT);
+ g_clear_pointer (&data->timeout_source, g_source_unref);
+
+ g_mutex_unlock (&data->lock);
+
+ if (should_return)
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
+ _("Socket I/O timed out"));
+
+ /* Signal completion of the task. */
+ g_mutex_lock (&data->lock);
+ data->has_returned = TRUE;
+ g_cond_broadcast (&data->cond);
+ g_mutex_unlock (&data->lock);
+
+ return G_SOURCE_REMOVE;
+}
+
+/* Will be called in the GLib worker thread, so must lock all accesses to shared
+ * data. */
+static gboolean
+cancelled_cb (GCancellable *cancellable,
+ gpointer user_data)
+{
+ GTask *task = G_TASK (user_data);
+ LookupData *data = g_task_get_task_data (task);
+ gboolean should_return;
+
+ g_mutex_lock (&data->lock);
+
+ g_assert (g_cancellable_is_cancelled (cancellable));
+ should_return = g_atomic_int_compare_and_exchange (&data->will_return, NOT_YET, CANCELLED);
+ g_clear_pointer (&data->cancellable_source, g_source_unref);
+
+ g_mutex_unlock (&data->lock);
+
+ if (should_return)
+ g_task_return_error_if_cancelled (task);
+
+ /* Signal completion of the task. */
+ g_mutex_lock (&data->lock);
+ data->has_returned = TRUE;
+ g_cond_broadcast (&data->cond);
+ g_mutex_unlock (&data->lock);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+run_task_in_thread_pool_async (GThreadedResolver *self,
+ GTask *task)
+{
+ LookupData *data = g_task_get_task_data (task);
+ guint timeout_ms = g_resolver_get_timeout (G_RESOLVER (self));
+ GCancellable *cancellable = g_task_get_cancellable (task);
+
+ g_mutex_lock (&data->lock);
+
+ g_thread_pool_push (self->thread_pool, g_object_ref (task), NULL);
+
+ if (timeout_ms != 0)
+ {
+ data->timeout_source = g_timeout_source_new (timeout_ms);
+ g_source_set_static_name (data->timeout_source, "[gio] threaded resolver timeout");
+ g_source_set_callback (data->timeout_source, G_SOURCE_FUNC (timeout_cb), task, NULL);
+ g_source_attach (data->timeout_source, GLIB_PRIVATE_CALL (g_get_worker_context) ());
+ }
+
+ if (cancellable != NULL)
+ {
+ data->cancellable_source = g_cancellable_source_new (cancellable);
+ g_source_set_static_name (data->cancellable_source, "[gio] threaded resolver cancellable");
+ g_source_set_callback (data->cancellable_source, G_SOURCE_FUNC (cancelled_cb), task, NULL);
+ g_source_attach (data->cancellable_source, GLIB_PRIVATE_CALL (g_get_worker_context) ());
+ }
+
+ g_mutex_unlock (&data->lock);
+}
+
+static void
+run_task_in_thread_pool_sync (GThreadedResolver *self,
+ GTask *task)
+{
+ LookupData *data = g_task_get_task_data (task);
+
+ run_task_in_thread_pool_async (self, task);
+
+ g_mutex_lock (&data->lock);
+ while (!data->has_returned)
+ g_cond_wait (&data->cond, &data->lock);
+ g_mutex_unlock (&data->lock);
+}
+
+static void
+threaded_resolver_worker_cb (gpointer task_data,
+ gpointer user_data)
+{
+ GTask *task = G_TASK (g_steal_pointer (&task_data));
+ LookupData *data = g_task_get_task_data (task);
+ GCancellable *cancellable = g_task_get_cancellable (task);
+ GError *local_error = NULL;
+ gboolean should_return;
+
+ switch (data->lookup_type) {
+ case LOOKUP_BY_NAME:
+ {
+ GList *addresses = do_lookup_by_name (data->lookup_by_name.hostname,
+ data->lookup_by_name.address_family,
+ cancellable,
+ &local_error);
+
+ g_mutex_lock (&data->lock);
+ should_return = g_atomic_int_compare_and_exchange (&data->will_return, NOT_YET, COMPLETED);
+ g_mutex_unlock (&data->lock);
+
+ if (should_return)
+ {
+ if (addresses != NULL)
+ g_task_return_pointer (task, g_steal_pointer (&addresses), (GDestroyNotify) g_resolver_free_addresses);
+ else
+ g_task_return_error (task, g_steal_pointer (&local_error));
+ }
+
+ g_clear_pointer (&addresses, g_resolver_free_addresses);
+ }
+ break;
+ case LOOKUP_BY_ADDRESS:
+ {
+ gchar *name = do_lookup_by_address (data->lookup_by_address.address,
+ cancellable,
+ &local_error);
+
+ g_mutex_lock (&data->lock);
+ should_return = g_atomic_int_compare_and_exchange (&data->will_return, NOT_YET, COMPLETED);
+ g_mutex_unlock (&data->lock);
+
+ if (should_return)
+ {
+ if (name != NULL)
+ g_task_return_pointer (task, g_steal_pointer (&name), g_free);
+ else
+ g_task_return_error (task, g_steal_pointer (&local_error));
+ }
+
+ g_clear_pointer (&name, g_free);
+ }
+ break;
+ case LOOKUP_RECORDS:
+ {
+ GList *records = do_lookup_records (data->lookup_records.rrname,
+ data->lookup_records.record_type,
+ cancellable,
+ &local_error);
+
+ g_mutex_lock (&data->lock);
+ should_return = g_atomic_int_compare_and_exchange (&data->will_return, NOT_YET, COMPLETED);
+ g_mutex_unlock (&data->lock);
+
+ if (should_return)
+ {
+ if (records != NULL)
+ g_task_return_pointer (task, g_steal_pointer (&records), (GDestroyNotify) free_records);
+ else
+ g_task_return_error (task, g_steal_pointer (&local_error));
+ }
+
+ g_clear_pointer (&records, free_records);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ /* Signal completion of a task. */
+ g_mutex_lock (&data->lock);
+ data->has_returned = TRUE;
+ g_cond_broadcast (&data->cond);
+ g_mutex_unlock (&data->lock);
+
+ g_object_unref (task);
+}
static void
g_threaded_resolver_class_init (GThreadedResolverClass *threaded_class)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (threaded_class);
GResolverClass *resolver_class = G_RESOLVER_CLASS (threaded_class);
+ object_class->finalize = g_threaded_resolver_finalize;
+
resolver_class->lookup_by_name = lookup_by_name;
resolver_class->lookup_by_name_async = lookup_by_name_async;
resolver_class->lookup_by_name_finish = lookup_by_name_finish;
diff --git a/gio/gthreadedresolver.h b/gio/gthreadedresolver.h
index ea76e4bfd..099df5b84 100644
--- a/gio/gthreadedresolver.h
+++ b/gio/gthreadedresolver.h
@@ -21,28 +21,23 @@
#ifndef __G_THREADED_RESOLVER_H__
#define __G_THREADED_RESOLVER_H__
+#include <gio/gio.h>
#include <gio/gresolver.h>
G_BEGIN_DECLS
+/**
+ * GThreadedResolver:
+ *
+ * #GThreadedResolver is an implementation of #GResolver which calls the libc
+ * lookup functions in threads to allow them to run asynchronously.
+ *
+ * Since: 2.20
+ */
#define G_TYPE_THREADED_RESOLVER (g_threaded_resolver_get_type ())
-#define G_THREADED_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_THREADED_RESOLVER, GThreadedResolver))
-#define G_THREADED_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_THREADED_RESOLVER, GThreadedResolverClass))
-#define G_IS_THREADED_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_THREADED_RESOLVER))
-#define G_IS_THREADED_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_THREADED_RESOLVER))
-#define G_THREADED_RESOLVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_THREADED_RESOLVER, GThreadedResolverClass))
-
-typedef struct {
- GResolver parent_instance;
-} GThreadedResolver;
-
-typedef struct {
- GResolverClass parent_class;
-
-} GThreadedResolverClass;
GIO_AVAILABLE_IN_ALL
-GType g_threaded_resolver_get_type (void) G_GNUC_CONST;
+G_DECLARE_FINAL_TYPE (GThreadedResolver, g_threaded_resolver, G, THREADED_RESOLVER, GResolver)
/* Used for a private test API */
#ifdef G_OS_UNIX
diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c
index b3f2b1c04..7b466cdf9 100644
--- a/gio/gunixconnection.c
+++ b/gio/gunixconnection.c
@@ -177,10 +177,11 @@ g_unix_connection_receive_fd (GUnixConnection *connection,
gint i;
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- ngettext("Expecting 1 control message, got %d",
- "Expecting 1 control message, got %d",
- nscm),
- nscm);
+ g_dngettext (NULL,
+ "Expecting 1 control message, got %d",
+ "Expecting 1 control message, got %d",
+ nscm),
+ nscm);
for (i = 0; i < nscm; i++)
g_object_unref (scms[i]);
@@ -211,9 +212,10 @@ g_unix_connection_receive_fd (GUnixConnection *connection,
gint i;
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- ngettext("Expecting one fd, but got %d\n",
- "Expecting one fd, but got %d\n",
- nfd),
+ g_dngettext (NULL,
+ "Expecting one fd, but got %d\n",
+ "Expecting one fd, but got %d\n",
+ nfd),
nfd);
for (i = 0; i < nfd; i++)
@@ -595,9 +597,10 @@ g_unix_connection_receive_credentials (GUnixConnection *connection,
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
- ngettext("Expecting 1 control message, got %d",
- "Expecting 1 control message, got %d",
- nscm),
+ g_dngettext (NULL,
+ "Expecting 1 control message, got %d",
+ "Expecting 1 control message, got %d",
+ nscm),
nscm);
goto out;
}
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index 9e97ef1c9..6477ee3a4 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -3036,7 +3036,7 @@ g_unix_mount_point_guess_can_eject (GUnixMountPoint *mount_point)
/* Utility functions {{{1 */
#ifdef HAVE_MNTENT_H
-/* borrowed from gtk/gtkfilesystemunix.c in GTK+ on 02/23/2006 */
+/* borrowed from gtk/gtkfilesystemunix.c in GTK on 02/23/2006 */
static void
_canonicalize_filename (gchar *filename)
{
diff --git a/gio/gwin32networkmonitor.c b/gio/gwin32networkmonitor.c
index 9dd5da757..e219225f0 100644
--- a/gio/gwin32networkmonitor.c
+++ b/gio/gwin32networkmonitor.c
@@ -78,24 +78,24 @@ g_win32_network_monitor_init (GWin32NetworkMonitor *win)
}
static gboolean
-win_network_monitor_get_ip_info (IP_ADDRESS_PREFIX prefix,
- GSocketFamily *family,
- const guint8 **dest,
- gsize *len)
+win_network_monitor_get_ip_info (const IP_ADDRESS_PREFIX *prefix,
+ GSocketFamily *family,
+ const guint8 **dest,
+ gsize *len)
{
- switch (prefix.Prefix.si_family)
+ switch (prefix->Prefix.si_family)
{
case AF_UNSPEC:
/* Fall-through: AF_UNSPEC deliveres both IPV4 and IPV6 infos, let`s stick with IPV4 here */
case AF_INET:
*family = G_SOCKET_FAMILY_IPV4;
- *dest = (guint8 *) &prefix.Prefix.Ipv4.sin_addr;
- *len = prefix.PrefixLength;
+ *dest = (guint8 *) &(prefix->Prefix.Ipv4.sin_addr);
+ *len = prefix->PrefixLength;
break;
case AF_INET6:
*family = G_SOCKET_FAMILY_IPV6;
- *dest = (guint8 *) &prefix.Prefix.Ipv6.sin6_addr;
- *len = prefix.PrefixLength;
+ *dest = (guint8 *) &(prefix->Prefix.Ipv6.sin6_addr);
+ *len = prefix->PrefixLength;
break;
default:
return FALSE;
@@ -152,7 +152,7 @@ win_network_monitor_process_table (GWin32NetworkMonitor *win,
route = routes->Table + i;
- if (!win_network_monitor_get_ip_info (route->DestinationPrefix, &family, &dest, &len))
+ if (!win_network_monitor_get_ip_info (&route->DestinationPrefix, &family, &dest, &len))
continue;
network = get_network_mask (family, dest, len);
@@ -218,13 +218,13 @@ win_network_monitor_invoke_route_changed (gpointer user_data)
switch (route_data->type)
{
case MibDeleteInstance:
- if (!win_network_monitor_get_ip_info (route_data->route->DestinationPrefix, &family, &dest, &len))
+ if (!win_network_monitor_get_ip_info (&route_data->route->DestinationPrefix, &family, &dest, &len))
break;
remove_network (route_data->win, family, dest, len);
break;
case MibAddInstance:
- if (!win_network_monitor_get_ip_info (route_data->route->DestinationPrefix, &family, &dest, &len))
+ if (!win_network_monitor_get_ip_info (&route_data->route->DestinationPrefix, &family, &dest, &len))
break;
add_network (route_data->win, family, dest, len);
diff --git a/gio/inotify/meson.build b/gio/inotify/meson.build
index e5c811520..8c7d6aaa0 100644
--- a/gio/inotify/meson.build
+++ b/gio/inotify/meson.build
@@ -8,9 +8,14 @@ inotify_sources = [
]
inotify_lib = static_library('inotify',
- sources : [inotify_sources, gmodule_visibility_h],
- include_directories : [configinc, glibinc, gmoduleinc],
- dependencies : [gioenumtypes_dep, libglib_dep, libgobject_dep],
+ sources : [inotify_sources],
+ include_directories : [configinc, glibinc],
+ dependencies : [
+ gioenumtypes_dep,
+ libglib_dep,
+ libgobject_dep,
+ gmodule_inc_dep,
+ ],
gnu_symbol_visibility : 'hidden',
pic : true,
c_args : [gio_c_args, gio_c_args_internal])
diff --git a/gio/kqueue/meson.build b/gio/kqueue/meson.build
index 04e48aad3..7447e5631 100644
--- a/gio/kqueue/meson.build
+++ b/gio/kqueue/meson.build
@@ -6,9 +6,12 @@ kqueue_sources = [
]
kqueue_lib = static_library('kqueue',
- sources : kqueue_sources,
- include_directories : [configinc, glibinc, gmoduleinc],
- dependencies : [gioenumtypes_dep],
+ sources : [kqueue_sources],
+ include_directories : [configinc, glibinc],
+ dependencies : [
+ gioenumtypes_dep,
+ gmodule_inc_dep,
+ ],
gnu_symbol_visibility : 'hidden',
pic : true,
c_args : [gio_c_args, gio_c_args_internal])
diff --git a/gio/meson.build b/gio/meson.build
index c9f63ea95..b19c59fa0 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -875,18 +875,20 @@ libgio_dep = declare_dependency(link_with : libgio,
pkg.generate(libgio,
requires : ['glib-2.0', 'gobject-2.0'],
- variables : ['datadir=' + join_paths('${prefix}', get_option('datadir')),
- 'schemasdir=' + join_paths('${datadir}', schemas_subdir),
- 'bindir=' + join_paths('${prefix}', get_option('bindir')),
- 'giomoduledir=' + pkgconfig_giomodulesdir,
- 'gio=' + join_paths('${bindir}', 'gio'),
- 'gio_querymodules=@0@'.format(pkgconfig_multiarch_bindir / 'gio-querymodules'),
- 'glib_compile_schemas=@0@'.format(pkgconfig_multiarch_bindir / 'glib-compile-schemas'),
- 'glib_compile_resources=' + join_paths('${bindir}', 'glib-compile-resources'),
- 'gdbus=' + join_paths('${bindir}', 'gdbus'),
- 'gdbus_codegen=' + join_paths('${bindir}', 'gdbus-codegen'),
- 'gresource=' + join_paths('${bindir}', 'gresource'),
- 'gsettings=' + join_paths('${bindir}', 'gsettings')],
+ variables : [
+ 'datadir=' + '${prefix}' / get_option('datadir'),
+ 'schemasdir=' + '${datadir}' / schemas_subdir,
+ 'bindir=' + '${prefix}' / get_option('bindir'),
+ 'giomoduledir=' + pkgconfig_giomodulesdir,
+ 'gio=' + '${bindir}' / 'gio',
+ 'gio_querymodules=' + pkgconfig_multiarch_bindir / 'gio-querymodules',
+ 'glib_compile_schemas=' + pkgconfig_multiarch_bindir / 'glib-compile-schemas',
+ 'glib_compile_resources=' + '${bindir}' / 'glib-compile-resources',
+ 'gdbus=' + '${bindir}' /'gdbus',
+ 'gdbus_codegen=' + '${bindir}' / 'gdbus-codegen',
+ 'gresource=' + '${bindir}' / 'gresource',
+ 'gsettings=' + '${bindir}' / 'gsettings',
+ ],
version : glib_version,
install_dir : glib_pkgconfigreldir,
filebase : 'gio-2.0',
diff --git a/gio/tests/appmonitor.c b/gio/tests/appmonitor.c
index c1d68b889..0123ea59c 100644
--- a/gio/tests/appmonitor.c
+++ b/gio/tests/appmonitor.c
@@ -22,7 +22,7 @@
#include <gio/gio.h>
#include <gstdio.h>
-#ifdef G_OS_UNIX
+#if defined (G_OS_UNIX) && !defined (__APPLE__)
#include <gio/gdesktopappinfo.h>
#endif
@@ -49,7 +49,7 @@ teardown (Fixture *fixture,
g_clear_pointer (&fixture->applications_dir, g_free);
}
-#ifdef G_OS_UNIX
+#if defined (G_OS_UNIX) && !defined (__APPLE__)
static gboolean
create_app (gpointer data)
{
@@ -97,13 +97,13 @@ timeout_cb (gpointer user_data)
return G_SOURCE_REMOVE;
}
-#endif /* G_OS_UNIX */
+#endif /* defined (G_OS_UNIX) && !defined (__APPLE__) */
static void
test_app_monitor (Fixture *fixture,
gconstpointer user_data)
{
-#ifdef G_OS_UNIX
+#if defined (G_OS_UNIX) && !defined (__APPLE__)
gchar *app_path;
GAppInfoMonitor *monitor;
GMainContext *context = NULL; /* use the global default main context */
@@ -162,9 +162,11 @@ test_app_monitor (Fixture *fixture,
g_object_unref (monitor);
g_free (app_path);
-#else /* if !G_OS_UNIX */
+#elif defined (__APPLE__)
+ g_test_skip (".desktop monitor on macos");
+#else /* if !(defined (G_OS_UNIX) && !defined (__APPLE__)) */
g_test_skip (".desktop monitor on win32");
-#endif /* !G_OS_UNIX */
+#endif /* !(defined (G_OS_UNIX) && !defined (__APPLE__)) */
}
int
diff --git a/gio/tests/desktop-files/usr/applications/glade.desktop b/gio/tests/desktop-files/usr/applications/glade.desktop
index dcede22a1..987f8dc0f 100644
--- a/gio/tests/desktop-files/usr/applications/glade.desktop
+++ b/gio/tests/desktop-files/usr/applications/glade.desktop
@@ -27,15 +27,15 @@ X-GNOME-FullName[en_GB]=Glade Interface Designer
X-GNOME-FullName[eo]=Uzantointerfaca dizajnilo Glado
X-GNOME-FullName[pt]=Designer de Interfaces Glade
X-GNOME-FullName[pt_BR]=Construtor de interfaces Glade
-Comment=Create or open user interface designs for GTK+ applications
-Comment[ca]=Creeu o obriu dissenys d'interfície d'usuari per a aplicacions GTK+
-Comment[ca@valencia]=Creeu o obriu dissenys d'interfície d'usuari per a aplicacions GTK+
-Comment[en@shaw]=𐑒𐑮𐑦𐑱𐑑 𐑹 𐑴𐑐𐑩𐑯 𐑿𐑟𐑼 𐑦𐑯𐑑𐑼𐑓𐑱𐑕 𐑛𐑩𐑟𐑲𐑯𐑟 𐑓𐑹 GTK+ 𐑩𐑐𐑤𐑦𐑒𐑱𐑕𐑩𐑯𐑟
-Comment[en_CA]=Create or open user interface designs for GTK+ applications
-Comment[en_GB]=Create or open user interface designs for GTK+ applications
-Comment[eo]=Krei aŭ malfermi uzantointerfacan dizajnon por aplikaĵoj de GTK+
-Comment[pt]=Criar ou abrir um desenho de interface de utilizador para aplicações GTK+
-Comment[pt_BR]=Crie ou abra projetos de interface com o usuário para aplicativos GTK+
+Comment=Create or open user interface designs for GTK applications
+Comment[ca]=Creeu o obriu dissenys d'interfície d'usuari per a aplicacions GTK
+Comment[ca@valencia]=Creeu o obriu dissenys d'interfície d'usuari per a aplicacions GTK
+Comment[en@shaw]=𐑒𐑮𐑦𐑱𐑑 𐑹 𐑴𐑐𐑩𐑯 𐑿𐑟𐑼 𐑦𐑯𐑑𐑼𐑓𐑱𐑕 𐑛𐑩𐑟𐑲𐑯𐑟 𐑓𐑹 GTK 𐑩𐑐𐑤𐑦𐑒𐑱𐑕𐑩𐑯𐑟
+Comment[en_CA]=Create or open user interface designs for GTK applications
+Comment[en_GB]=Create or open user interface designs for GTK applications
+Comment[eo]=Krei aŭ malfermi uzantointerfacan dizajnon por aplikaĵoj de GTK
+Comment[pt]=Criar ou abrir um desenho de interface de utilizador para aplicações GTK
+Comment[pt_BR]=Crie ou abra projetos de interface com o usuário para aplicativos GTK
Keywords=GUI designer;user interface;ui builder;
Keywords[ca]=dissenyador d'interfícies d'usuari gràfiques;interfície d'usuari;constructor d'interfícies d'usuari;
Keywords[ca@valencia]=dissenyador d'interfícies d'usuari gràfiques;interfície d'usuari;constructor d'interfícies d'usuari;
diff --git a/gio/tests/file.c b/gio/tests/file.c
index ad2f945f9..5ca2e678d 100644
--- a/gio/tests/file.c
+++ b/gio/tests/file.c
@@ -452,15 +452,13 @@ created_cb (GObject *source,
data);
}
-static gboolean
+static void
stop_timeout (gpointer user_data)
{
CreateDeleteData *data = user_data;
data->timed_out = TRUE;
g_main_context_wakeup (data->context);
-
- return G_SOURCE_REMOVE;
}
/*
@@ -518,7 +516,7 @@ test_create_delete (gconstpointer d)
/* Use the global default main context */
data->context = NULL;
- data->timeout = g_timeout_add_seconds (10, stop_timeout, data);
+ data->timeout = g_timeout_add_seconds_once (10, stop_timeout, data);
g_file_create_async (data->file, 0, 0, NULL, created_cb, data);
@@ -2515,6 +2513,80 @@ test_copy_preserve_mode (void)
#endif
}
+typedef struct
+{
+ goffset current_num_bytes;
+ goffset total_num_bytes;
+} CopyProgressData;
+
+static void
+file_copy_progress_cb (goffset current_num_bytes,
+ goffset total_num_bytes,
+ gpointer user_data)
+{
+ CopyProgressData *prev_data = user_data;
+
+ g_assert_cmpuint (total_num_bytes, ==, prev_data->total_num_bytes);
+ g_assert_cmpuint (current_num_bytes, >=, prev_data->current_num_bytes);
+
+ /* Update it for the next callback. */
+ prev_data->current_num_bytes = current_num_bytes;
+}
+
+static void
+test_copy_progress (void)
+{
+ GFile *src_tmpfile = NULL;
+ GFile *dest_tmpfile = NULL;
+ GFileIOStream *iostream;
+ GOutputStream *ostream;
+ GError *local_error = NULL;
+ const guint8 buffer[] = { 1, 2, 3, 4, 5 };
+ CopyProgressData progress_data;
+
+ src_tmpfile = g_file_new_tmp ("tmp-copy-progressXXXXXX",
+ &iostream, &local_error);
+ g_assert_no_error (local_error);
+
+ /* Write some content to the file for testing. */
+ ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+ g_output_stream_write (ostream, buffer, sizeof (buffer), NULL, &local_error);
+ g_assert_no_error (local_error);
+
+ g_io_stream_close ((GIOStream *) iostream, NULL, &local_error);
+ g_assert_no_error (local_error);
+ g_clear_object (&iostream);
+
+ /* Grab a unique destination filename. */
+ dest_tmpfile = g_file_new_tmp ("tmp-copy-progressXXXXXX",
+ &iostream, &local_error);
+ g_assert_no_error (local_error);
+ g_io_stream_close ((GIOStream *) iostream, NULL, &local_error);
+ g_assert_no_error (local_error);
+ g_clear_object (&iostream);
+
+ /* Set the progress data to an initial offset of zero. The callback will
+ * assert that progress is non-decreasing and reaches the total length of
+ * the file. */
+ progress_data.current_num_bytes = 0;
+ progress_data.total_num_bytes = sizeof (buffer);
+
+ /* Copy the file with progress reporting. */
+ g_file_copy (src_tmpfile, dest_tmpfile, G_FILE_COPY_OVERWRITE,
+ NULL, file_copy_progress_cb, &progress_data, &local_error);
+ g_assert_no_error (local_error);
+
+ g_assert_cmpuint (progress_data.current_num_bytes, ==, progress_data.total_num_bytes);
+ g_assert_cmpuint (progress_data.total_num_bytes, ==, sizeof (buffer));
+
+ /* Clean up. */
+ (void) g_file_delete (src_tmpfile, NULL, NULL);
+ (void) g_file_delete (dest_tmpfile, NULL, NULL);
+
+ g_clear_object (&src_tmpfile);
+ g_clear_object (&dest_tmpfile);
+}
+
static void
test_measure (void)
{
@@ -2541,7 +2613,7 @@ test_measure (void)
g_assert_true (ok);
g_assert_no_error (error);
- g_assert_cmpuint (num_bytes, ==, 74478);
+ g_assert_cmpuint (num_bytes, ==, 74469);
g_assert_cmpuint (num_dirs, ==, 6);
g_assert_cmpuint (num_files, ==, 32);
@@ -2624,7 +2696,7 @@ test_measure_async (void)
file = g_file_new_for_path (path);
g_free (path);
- data->expected_bytes = 74478;
+ data->expected_bytes = 74469;
data->expected_dirs = 6;
data->expected_files = 32;
@@ -3846,6 +3918,7 @@ main (int argc, char *argv[])
g_test_add_func ("/file/async-delete", test_async_delete);
g_test_add_func ("/file/async-make-symlink", test_async_make_symlink);
g_test_add_func ("/file/copy-preserve-mode", test_copy_preserve_mode);
+ g_test_add_func ("/file/copy/progress", test_copy_progress);
g_test_add_func ("/file/measure", test_measure);
g_test_add_func ("/file/measure-async", test_measure_async);
g_test_add_func ("/file/load-bytes", test_load_bytes);
@@ -3871,3 +3944,4 @@ main (int argc, char *argv[])
return g_test_run ();
}
+
diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c
index 1a2600099..b0584eb5f 100644
--- a/gio/tests/gapplication.c
+++ b/gio/tests/gapplication.c
@@ -1117,15 +1117,13 @@ activate (gpointer data)
/* GApplication complains if we don't connect to ::activate */
}
-static gboolean
+static void
quit_already (gpointer user_data)
{
TestReplaceData *data = user_data;
g_application_quit (data->app);
data->timeout_id = 0;
-
- return G_SOURCE_REMOVE;
}
static void
@@ -1177,7 +1175,7 @@ test_replace (gconstpointer data)
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
if (!allow)
- data.timeout_id = g_timeout_add_seconds (1, quit_already, &data);
+ data.timeout_id = g_timeout_add_seconds_once (1, quit_already, &data);
g_application_run (app, G_N_ELEMENTS (argv) - 1, argv);
diff --git a/gio/tests/gdbus-connection-slow.c b/gio/tests/gdbus-connection-slow.c
index 5a3479234..06f59493c 100644
--- a/gio/tests/gdbus-connection-slow.c
+++ b/gio/tests/gdbus-connection-slow.c
@@ -128,14 +128,12 @@ test_connection_flush (void)
/* the test will fail if the service name has not appeared after this amount of seconds */
#define LARGE_MESSAGE_TIMEOUT_SECONDS 10
-static gboolean
+static void
large_message_timeout_cb (gpointer data)
{
(void)data;
g_error ("Error: timeout waiting for dbus name to appear");
-
- return G_SOURCE_REMOVE;
}
static void
@@ -200,9 +198,9 @@ test_connection_large_message (void)
/* this is safe; testserver will exit once the bus goes away */
g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL));
- timeout_id = g_timeout_add_seconds (LARGE_MESSAGE_TIMEOUT_SECONDS,
- large_message_timeout_cb,
- NULL);
+ timeout_id = g_timeout_add_seconds_once (LARGE_MESSAGE_TIMEOUT_SECONDS,
+ large_message_timeout_cb,
+ NULL);
watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
"com.example.TestService",
diff --git a/gio/tests/gmenumodel.c b/gio/tests/gmenumodel.c
index fb52b4c6d..d75f36a29 100644
--- a/gio/tests/gmenumodel.c
+++ b/gio/tests/gmenumodel.c
@@ -7,12 +7,10 @@
#include "glib/glib-private.h"
-static gboolean
+static void
time_out (gpointer unused G_GNUC_UNUSED)
{
g_error ("Timed out");
- /* not reached */
- return FALSE;
}
static guint
@@ -22,7 +20,7 @@ add_timeout (guint seconds)
/* Safety-catch against the main loop having blocked */
alarm (seconds + 5);
#endif
- return g_timeout_add_seconds (seconds, time_out, NULL);
+ return g_timeout_add_seconds_once (seconds, time_out, NULL);
}
static void
diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c
index 515a11267..30947596e 100644
--- a/gio/tests/gsubprocess.c
+++ b/gio/tests/gsubprocess.c
@@ -1288,14 +1288,12 @@ test_communicate_utf8_invalid (void)
g_object_unref (proc);
}
-static gboolean
+static void
send_terminate (gpointer user_data)
{
GSubprocess *proc = user_data;
g_subprocess_force_exit (proc);
-
- return FALSE;
}
static void
@@ -1341,7 +1339,7 @@ test_terminate (void)
g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop);
- g_timeout_add_seconds (3, send_terminate, proc);
+ g_timeout_add_seconds_once (3, send_terminate, proc);
g_main_loop_run (loop);
@@ -1350,14 +1348,12 @@ test_terminate (void)
}
#ifdef G_OS_UNIX
-static gboolean
+static void
send_signal (gpointer user_data)
{
GSubprocess *proc = user_data;
g_subprocess_send_signal (proc, SIGKILL);
-
- return FALSE;
}
static void
@@ -1378,7 +1374,7 @@ test_signal (void)
g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop);
- g_timeout_add_seconds (3, send_signal, proc);
+ g_timeout_add_seconds_once (3, send_signal, proc);
g_main_loop_run (loop);
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index 2f312e056..2ff34a5d0 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -590,8 +590,8 @@ test_extra_programs += {
'proxy' : {'install' : false},
'resolver' : {'install' : false},
'send-data' : {'install' : false},
- 'socket-server' : {'install' : false},
- 'socket-client' : {
+ 'socket-testserver' : {'install' : false},
+ 'socket-testclient' : {
'extra_sources' : ['gtlsconsoleinteraction.c'],
'install' : false,
},
@@ -1096,4 +1096,72 @@ if installed_tests_enabled
)
endif
+if have_bash and have_pkg_config
+ prefix = get_option('prefix')
+ if prefix.endswith(':/')
+ prefix += '/'
+ endif
+
+ pkg_config_tests = [
+ 'pkg-config --validate gio-2.0',
+ 'test "$(pkg-config --modversion gio-2.0)" = "@0@"'.format(glib_version),
+ 'test "$(pkg-config --variable=prefix gio-2.0)" = "@0@"'.format(
+ get_option('prefix')),
+ 'test "$(pkg-config --variable=datadir gio-2.0)" = "@0@"'.format(
+ prefix / get_option('datadir')),
+ 'test "$(pkg-config --variable=schemasdir gio-2.0)" = "@0@"'.format(
+ prefix / get_option('datadir') / schemas_subdir),
+ 'test "$(pkg-config --variable=giomoduledir gio-2.0)" = "@0@"'.format(
+ get_option('gio_module_dir') != '' ?
+ prefix / get_option('gio_module_dir') :
+ prefix / get_option('libdir') / 'gio' / 'modules'),
+ ]
+
+ gio_binaries = [
+ 'gio',
+ 'gio-querymodules',
+ 'glib-compile-schemas',
+ 'glib-compile-resources',
+ 'gdbus',
+ 'gdbus-codegen',
+ 'gresource',
+ 'gsettings',
+ ]
+
+ foreach binary: gio_binaries
+ pkg_config_tests += [
+ 'test "$(pkg-config --variable=@0@ gio-2.0)" = "@1@"'.format(
+ binary.underscorify(),
+ prefix / get_option('bindir') / binary)
+ ]
+ endforeach
+
+ test('gio-2.0-pkg-config',
+ bash,
+ args: [ '-xe', '-c', '\n'.join(pkg_config_tests) ],
+ suite: ['gio', 'no-valgrind', 'pkg-config'],
+ env: {
+ 'PKG_CONFIG_PATH': meson.project_build_root() / 'meson-private',
+ },
+ )
+
+ platform_module = host_system == 'windows' ? 'gio-windows-2.0' : 'gio-unix-2.0'
+ pkg_config_tests = [
+ 'pkg-config --validate ' + platform_module,
+ 'test "$(pkg-config --modversion @0@)" = "@1@"'.format(platform_module,
+ glib_version),
+ 'test "$(pkg-config --variable=prefix @0@)" = "@1@"'.format(platform_module,
+ get_option('prefix')),
+ ]
+
+ test(platform_module + '-pkg-config',
+ bash,
+ args: [ '-xe', '-c', '\n'.join(pkg_config_tests) ],
+ suite: ['gio', 'no-valgrind', 'pkg-config'],
+ env: {
+ 'PKG_CONFIG_PATH': meson.project_build_root() / 'meson-private',
+ },
+ )
+endif
+
subdir('services')
diff --git a/gio/tests/resolver.c b/gio/tests/resolver.c
index ec9b9e9de..b8adb4a36 100644
--- a/gio/tests/resolver.c
+++ b/gio/tests/resolver.c
@@ -41,6 +41,7 @@ static int nlookups = 0;
static gboolean synchronous = FALSE;
static guint connectable_count = 0;
static GResolverRecordType record_type = 0;
+static gint timeout_ms = 0;
static G_NORETURN void
usage (void)
@@ -688,7 +689,7 @@ static gboolean
async_cancel (GIOChannel *source, GIOCondition cond, gpointer cancel)
{
g_cancellable_cancel (cancel);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
#endif
@@ -722,6 +723,7 @@ static const GOptionEntry option_entries[] = {
{ "synchronous", 's', 0, G_OPTION_ARG_NONE, &synchronous, "Synchronous connections", NULL },
{ "connectable", 'c', 0, G_OPTION_ARG_INT, &connectable_count, "Connectable count", "C" },
{ "special-type", 't', 0, G_OPTION_ARG_CALLBACK, record_type_arg, "Record type like MX, TXT, NS or SOA", "RR" },
+ { "timeout", 0, 0, G_OPTION_ARG_INT, &timeout_ms, "Timeout (ms)", "ms" },
G_OPTION_ENTRY_NULL,
};
@@ -732,7 +734,7 @@ main (int argc, char **argv)
GError *error = NULL;
#ifdef G_OS_UNIX
GIOChannel *chan;
- guint watch;
+ GSource *watch_source = NULL;
#endif
context = g_option_context_new ("lookups ...");
@@ -749,6 +751,9 @@ main (int argc, char **argv)
resolver = g_resolver_get_default ();
+ if (timeout_ms != 0)
+ g_resolver_set_timeout (resolver, timeout_ms);
+
cancellable = g_cancellable_new ();
#ifdef G_OS_UNIX
@@ -763,7 +768,9 @@ main (int argc, char **argv)
exit (1);
}
chan = g_io_channel_unix_new (cancel_fds[0]);
- watch = g_io_add_watch (chan, G_IO_IN, async_cancel, cancellable);
+ watch_source = g_io_create_watch (chan, G_IO_IN);
+ g_source_set_callback (watch_source, (GSourceFunc) async_cancel, cancellable, NULL);
+ g_source_attach (watch_source, NULL);
g_io_channel_unref (chan);
#endif
@@ -787,7 +794,8 @@ main (int argc, char **argv)
g_main_loop_unref (loop);
#ifdef G_OS_UNIX
- g_source_remove (watch);
+ g_source_destroy (watch_source);
+ g_clear_pointer (&watch_source, g_source_unref);
#endif
g_object_unref (cancellable);
g_option_context_free (context);
diff --git a/gio/tests/socket-common.c b/gio/tests/socket-common.c
index 18d083a30..b740f68e7 100644
--- a/gio/tests/socket-common.c
+++ b/gio/tests/socket-common.c
@@ -1,4 +1,4 @@
-/* #included into both socket-client.c and socket-server.c */
+/* #included into both socket-testclient.c and socket-testserver.c */
#ifdef G_OS_UNIX
static const char *unix_socket_address_types[] = {
diff --git a/gio/tests/socket-client.c b/gio/tests/socket-testclient.c
index 025632767..025632767 100644
--- a/gio/tests/socket-client.c
+++ b/gio/tests/socket-testclient.c
diff --git a/gio/tests/socket-server.c b/gio/tests/socket-testserver.c
index 61715b02d..61715b02d 100644
--- a/gio/tests/socket-server.c
+++ b/gio/tests/socket-testserver.c
diff --git a/gio/win32/meson.build b/gio/win32/meson.build
index 0a896aca0..08be6b09e 100644
--- a/gio/win32/meson.build
+++ b/gio/win32/meson.build
@@ -9,8 +9,12 @@ giowin32_sources = [
giowin32_lib = static_library('giowin32',
sources : [giowin32_sources],
- include_directories : [configinc, glibinc, gioinc, gmoduleinc],
- dependencies : [libintl, gioenumtypes_dep],
+ include_directories : [configinc, glibinc, gioinc],
+ dependencies : [
+ libintl,
+ gioenumtypes_dep,
+ gmodule_inc_dep,
+ ],
gnu_symbol_visibility : 'hidden',
pic : true,
c_args : [gio_c_args, gio_c_args_internal])
diff --git a/glib.doap b/glib.doap
index fec140168..32b217011 100644
--- a/glib.doap
+++ b/glib.doap
@@ -10,13 +10,13 @@
<shortdesc xml:lang="en">Low level core library</shortdesc>
- <description xml:lang="en">GLib is the low-level core library that forms the basis for projects such as GTK+ and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system.</description>
+ <description xml:lang="en">GLib is the low-level core library that forms the basis for projects such as GTK and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system.</description>
<homepage rdf:resource="http://www.gtk.org" />
<license rdf:resource="http://usefulinc.com/doap/licenses/lgpl" />
<bug-database rdf:resource="https://gitlab.gnome.org/GNOME/glib/issues/new"/>
<download-page rdf:resource="http://download.gnome.org/sources/glib/" />
- <mailing-list rdf:resource="https://discourse.gnome.org/tags/glib/" />
+ <developer-forum rdf:resource="https://discourse.gnome.org/tags/glib/" />
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
<programming-language>C</programming-language>
@@ -114,7 +114,7 @@
<foaf:Person>
<foaf:name>Antoine Jacoutot</foaf:name>
<foaf:mbox rdf:resource="mailto:ajacoutot@gnome.org"/>
- <gnome:userid>ajacoutot</gnome:userid>
+<!-- <gnome:userid>ajacoutot</gnome:userid> -->
</foaf:Person>
</maintainer>
diff --git a/glib/docs.c b/glib/docs.c
index 69d81c09a..450616eb9 100644
--- a/glib/docs.c
+++ b/glib/docs.c
@@ -1068,7 +1068,7 @@
* @title: Type Conversion Macros
* @short_description: portably storing integers in pointer variables
*
- * Many times GLib, GTK+, and other libraries allow you to pass "user
+ * Many times GLib, GTK, and other libraries allow you to pass "user
* data" to a callback, in the form of a void pointer. From time to time
* you want to pass an integer instead of a pointer. You could allocate
* an integer, with something like:
diff --git a/glib/gconvert.c b/glib/gconvert.c
index 829fe38de..5e3d781df 100644
--- a/glib/gconvert.c
+++ b/glib/gconvert.c
@@ -56,7 +56,6 @@
#include "glibintl.h"
-
/**
* SECTION:conversions
* @title: Character Set Conversion
@@ -85,7 +84,7 @@
* Character: P r e s e n t a c i ó n . s x i
* Hex code: 50 72 65 73 65 6e 74 61 63 69 c3 b3 6e 2e 73 78 69
* ]|
- * Glib uses UTF-8 for its strings, and GUI toolkits like GTK+ that use
+ * GLib uses UTF-8 for its strings, and GUI toolkits like GTK that use
* GLib do the same thing. If you get a file name from the file system,
* for example, from readdir() or from g_dir_read_name(), and you wish
* to display the file name to the user, you will need to convert it
diff --git a/glib/gerror.c b/glib/gerror.c
index 7ac85fc66..ea168e020 100644
--- a/glib/gerror.c
+++ b/glib/gerror.c
@@ -53,7 +53,7 @@
* These two kinds of errors are fundamentally different: runtime errors
* should be handled or reported to the user, programming errors should
* be eliminated by fixing the bug in the program. This is why most
- * functions in GLib and GTK+ do not use the #GError facility.
+ * functions in GLib and GTK do not use the #GError facility.
*
* Functions that can fail take a return location for a #GError as their
* last argument. On error, a new #GError instance will be allocated and
diff --git a/glib/gfileutils.c b/glib/gfileutils.c
index 4ed8171cc..9646c696e 100644
--- a/glib/gfileutils.c
+++ b/glib/gfileutils.c
@@ -2940,7 +2940,7 @@ g_get_current_dir (void)
const gchar *pwd;
gchar *buffer = NULL;
gchar *dir = NULL;
- static gulong max_len = 0;
+ static gsize buffer_size = 0;
struct stat pwdbuf, dotbuf;
pwd = g_getenv ("PWD");
@@ -2949,27 +2949,31 @@ g_get_current_dir (void)
dotbuf.st_dev == pwdbuf.st_dev && dotbuf.st_ino == pwdbuf.st_ino)
return g_strdup (pwd);
- if (max_len == 0)
- max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
+ if (buffer_size == 0)
+ buffer_size = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
- while (max_len < G_MAXULONG / 2)
+ while (buffer_size < G_MAXSIZE / 2)
{
g_free (buffer);
- buffer = g_new (gchar, max_len + 1);
+ buffer = g_new (gchar, buffer_size);
*buffer = 0;
- dir = getcwd (buffer, max_len);
+ dir = getcwd (buffer, buffer_size);
if (dir || errno != ERANGE)
break;
- max_len *= 2;
+ buffer_size *= 2;
}
+ /* Check that getcwd() nul-terminated the string. It should do, but the specs
+ * don’t actually explicitly state that:
+ * https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html */
+ g_assert (dir == NULL || strnlen (dir, buffer_size) < buffer_size);
+
if (!dir || !*buffer)
{
- /* hm, should we g_error() out here?
- * this can happen if e.g. "./" has mode \0000
- */
+ /* Fallback return value */
+ g_assert (buffer_size >= 2);
buffer[0] = G_DIR_SEPARATOR;
buffer[1] = 0;
}
diff --git a/glib/ggettext.c b/glib/ggettext.c
index 42f3d0e72..71654fb84 100644
--- a/glib/ggettext.c
+++ b/glib/ggettext.c
@@ -362,12 +362,12 @@ _g_dgettext_should_translate (void)
* translations for the current locale.
*
* The advantage of using this function over dgettext() proper is that
- * libraries using this function (like GTK+) will not use translations
+ * libraries using this function (like GTK) will not use translations
* if the application using the library does not have translations for
* the current locale. This results in a consistent English-only
* interface instead of one having partial translations. For this
* feature to work, the call to textdomain() and setlocale() should
- * precede any g_dgettext() invocations. For GTK+, it means calling
+ * precede any g_dgettext() invocations. For GTK, it means calling
* textdomain() before gtk_init or its variants.
*
* This function disables translations if and only if upon its first
@@ -385,7 +385,7 @@ _g_dgettext_should_translate (void)
*
* Note that this behavior may not be desired for example if an application
* has its untranslated messages in a language other than English. In those
- * cases the application should call textdomain() after initializing GTK+.
+ * cases the application should call textdomain() after initializing GTK.
*
* Applications should normally not use this function directly,
* but use the _() macro for translations.
diff --git a/glib/glib-init.c b/glib/glib-init.c
index c513f5190..933f891da 100644
--- a/glib/glib-init.c
+++ b/glib/glib-init.c
@@ -220,7 +220,7 @@ G_STATIC_ASSERT (sizeof (int) == sizeof (gint32));
*
* Parses a string containing debugging options
* into a %guint containing bit flags. This is used
- * within GDK and GTK+ to parse the debug options passed on the
+ * within GDK and GTK to parse the debug options passed on the
* command line or through environment variables.
*
* If @string is equal to "all", all flags are set. Any flags
diff --git a/glib/glib-unix.c b/glib/glib-unix.c
index ef0d1fbfb..f671887c9 100644
--- a/glib/glib-unix.c
+++ b/glib/glib-unix.c
@@ -293,12 +293,15 @@ GSourceFuncs g_unix_fd_source_funcs = {
/**
* g_unix_fd_source_new:
* @fd: a file descriptor
- * @condition: IO conditions to watch for on @fd
+ * @condition: I/O conditions to watch for on @fd
*
- * Creates a #GSource to watch for a particular IO condition on a file
+ * Creates a #GSource to watch for a particular I/O condition on a file
* descriptor.
*
- * The source will never close the fd -- you must do it yourself.
+ * The source will never close the @fd — you must do it yourself.
+ *
+ * Any callback attached to the returned #GSource must have type
+ * #GUnixFDSourceFunc.
*
* Returns: the newly created #GSource
*
diff --git a/glib/gmacros.h b/glib/gmacros.h
index 02ed33417..a7ed77541 100644
--- a/glib/gmacros.h
+++ b/glib/gmacros.h
@@ -918,9 +918,6 @@
# else
# define NULL ((void*) 0)
# endif /* G_CXX_STD_CHECK_VERSION (11) */
-#elif G_CXX_STD_CHECK_VERSION (11)
-# undef NULL
-# define NULL (nullptr)
#endif
#ifndef FALSE
diff --git a/glib/gmain.c b/glib/gmain.c
index ec4d24cde..b91e68d36 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -133,7 +133,7 @@
* @short_description: manages all available sources of events
*
* The main event loop manages all the available sources of events for
- * GLib and GTK+ applications. These events can come from any number of
+ * GLib and GTK applications. These events can come from any number of
* different types of sources such as file descriptors (plain files,
* pipes or sockets) and timeouts. New types of event sources can also
* be added using g_source_attach().
@@ -165,12 +165,12 @@
* exit the main loop, and g_main_loop_run() returns.
*
* It is possible to create new instances of #GMainLoop recursively.
- * This is often used in GTK+ applications when showing modal dialog
+ * This is often used in GTK applications when showing modal dialog
* boxes. Note that event sources are associated with a particular
* #GMainContext, and will be checked and dispatched for all main
* loops associated with that GMainContext.
*
- * GTK+ contains wrappers of some of these functions, e.g. gtk_main(),
+ * GTK contains wrappers of some of these functions, e.g. gtk_main(),
* gtk_main_quit() and gtk_events_pending().
*
* ## Creating new source types
@@ -446,11 +446,25 @@ static void g_source_set_priority_unlocked (GSource *source,
static void g_child_source_remove_internal (GSource *child_source,
GMainContext *context);
-static void g_main_context_poll (GMainContext *context,
- gint timeout,
- gint priority,
- GPollFD *fds,
- gint n_fds);
+static gboolean g_main_context_acquire_unlocked (GMainContext *context);
+static void g_main_context_release_unlocked (GMainContext *context);
+static gboolean g_main_context_prepare_unlocked (GMainContext *context,
+ gint *priority);
+static gint g_main_context_query_unlocked (GMainContext *context,
+ gint max_priority,
+ gint *timeout,
+ GPollFD *fds,
+ gint n_fds);
+static gboolean g_main_context_check_unlocked (GMainContext *context,
+ gint max_priority,
+ GPollFD *fds,
+ gint n_fds);
+static void g_main_context_dispatch_unlocked (GMainContext *context);
+static void g_main_context_poll_unlocked (GMainContext *context,
+ int timeout,
+ int priority,
+ GPollFD *fds,
+ int n_fds);
static void g_main_context_add_poll_unlocked (GMainContext *context,
gint priority,
GPollFD *fd);
@@ -2183,7 +2197,7 @@ g_source_set_name_full (GSource *source,
*
* The source name should describe in a human-readable way
* what the source does. For example, "X11 event queue"
- * or "GTK+ repaint idle handler" or whatever it is.
+ * or "GTK repaint idle handler" or whatever it is.
*
* It is permitted to call this function multiple times, but is not
* recommended due to the potential performance impact. For example,
@@ -3107,7 +3121,7 @@ get_dispatch (void)
*
* Returns the depth of the stack of calls to
* g_main_context_dispatch() on any #GMainContext in the current thread.
- * That is, when called from the toplevel, it gives 0. When
+ * That is, when called from the toplevel, it gives 0. When
* called from within a callback from g_main_context_iteration()
* (or g_main_loop_run(), etc.) it returns 1. When called from within
* a callback to a recursive call to g_main_context_iteration(),
@@ -3511,7 +3525,7 @@ g_main_dispatch (GMainContext *context)
*
* You must be the owner of a context before you
* can call g_main_context_prepare(), g_main_context_query(),
- * g_main_context_check(), g_main_context_dispatch().
+ * g_main_context_check(), g_main_context_dispatch(), g_main_context_release().
*
* Since 2.76 @context can be %NULL to use the global-default
* main context.
@@ -3523,13 +3537,24 @@ gboolean
g_main_context_acquire (GMainContext *context)
{
gboolean result = FALSE;
- GThread *self = G_THREAD_SELF;
if (context == NULL)
context = g_main_context_default ();
LOCK_CONTEXT (context);
+ result = g_main_context_acquire_unlocked (context);
+
+ UNLOCK_CONTEXT (context);
+
+ return result;
+}
+
+static gboolean
+g_main_context_acquire_unlocked (GMainContext *context)
+{
+ GThread *self = G_THREAD_SELF;
+
if (!context->owner)
{
context->owner = self;
@@ -3540,16 +3565,13 @@ g_main_context_acquire (GMainContext *context)
if (context->owner == self)
{
context->owner_count++;
- result = TRUE;
+ return TRUE;
}
else
{
TRACE (GLIB_MAIN_CONTEXT_ACQUIRE (context, FALSE /* failure */));
+ return FALSE;
}
-
- UNLOCK_CONTEXT (context);
-
- return result;
}
/**
@@ -3561,15 +3583,40 @@ g_main_context_acquire (GMainContext *context)
* with g_main_context_acquire(). If the context was acquired multiple
* times, the ownership will be released only when g_main_context_release()
* is called as many times as it was acquired.
+ *
+ * You must have successfully acquired the context with
+ * g_main_context_acquire() before you may call this function.
**/
void
g_main_context_release (GMainContext *context)
{
if (context == NULL)
context = g_main_context_default ();
-
+
LOCK_CONTEXT (context);
+#ifndef G_DISABLE_CHECKS
+ if (G_UNLIKELY (context->owner != G_THREAD_SELF || context->owner_count == 0))
+ {
+ GThread *context_owner = context->owner;
+ guint context_owner_count = context->owner_count;
+
+ UNLOCK_CONTEXT (context);
+
+ g_critical ("g_main_context_release() called on a context (%p, owner %p, "
+ "owner count %u) which is not acquired by the current thread",
+ context, context_owner, context_owner_count);
+ }
+#endif /* !G_DISABLE_CHECKS */
+
+ g_main_context_release_unlocked (context);
+
+ UNLOCK_CONTEXT (context);
+}
+
+static void
+g_main_context_release_unlocked (GMainContext *context)
+{
context->owner_count--;
if (context->owner_count == 0)
{
@@ -3592,8 +3639,6 @@ g_main_context_release (GMainContext *context)
g_mutex_unlock (waiter->mutex);
}
}
-
- UNLOCK_CONTEXT (context);
}
static gboolean
@@ -3706,24 +3751,36 @@ gboolean
g_main_context_prepare (GMainContext *context,
gint *priority)
{
- guint i;
- gint n_ready = 0;
- gint current_priority = G_MAXINT;
- GSource *source;
- GSourceIter iter;
+ gboolean ready;
if (context == NULL)
context = g_main_context_default ();
LOCK_CONTEXT (context);
+ ready = g_main_context_prepare_unlocked (context, priority);
+
+ UNLOCK_CONTEXT (context);
+
+ return ready;
+}
+
+static gboolean
+g_main_context_prepare_unlocked (GMainContext *context,
+ gint *priority)
+{
+ guint i;
+ gint n_ready = 0;
+ gint current_priority = G_MAXINT;
+ GSource *source;
+ GSourceIter iter;
+
context->time_is_fresh = FALSE;
if (context->in_check_or_prepare)
{
g_warning ("g_main_context_prepare() called recursively from within a source's check() or "
"prepare() member.");
- UNLOCK_CONTEXT (context);
return FALSE;
}
@@ -3736,7 +3793,6 @@ g_main_context_prepare (GMainContext *context,
if (dispatch)
g_main_dispatch (context, &current_time);
- UNLOCK_CONTEXT (context);
return TRUE;
}
#endif
@@ -3854,8 +3910,6 @@ g_main_context_prepare (GMainContext *context,
g_source_iter_clear (&iter);
TRACE (GLIB_MAIN_CONTEXT_AFTER_PREPARE (context, current_priority, n_ready));
-
- UNLOCK_CONTEXT (context);
if (priority)
*priority = current_priority;
@@ -3893,14 +3947,30 @@ g_main_context_query (GMainContext *context,
gint n_fds)
{
gint n_poll;
- GPollRec *pollrec, *lastpollrec;
- gushort events;
if (context == NULL)
context = g_main_context_default ();
LOCK_CONTEXT (context);
+ n_poll = g_main_context_query_unlocked (context, max_priority, timeout, fds, n_fds);
+
+ UNLOCK_CONTEXT (context);
+
+ return n_poll;
+}
+
+static gint
+g_main_context_query_unlocked (GMainContext *context,
+ gint max_priority,
+ gint *timeout,
+ GPollFD *fds,
+ gint n_fds)
+{
+ gint n_poll;
+ GPollRec *pollrec, *lastpollrec;
+ gushort events;
+
TRACE (GLIB_MAIN_CONTEXT_BEFORE_QUERY (context, max_priority));
/* fds is filled sequentially from poll_records. Since poll_records
@@ -3957,8 +4027,6 @@ g_main_context_query (GMainContext *context,
TRACE (GLIB_MAIN_CONTEXT_AFTER_QUERY (context, context->timeout,
fds, n_poll));
- UNLOCK_CONTEXT (context);
-
return n_poll;
}
@@ -3990,6 +4058,23 @@ g_main_context_check (GMainContext *context,
GPollFD *fds,
gint n_fds)
{
+ gboolean ready;
+
+ LOCK_CONTEXT (context);
+
+ ready = g_main_context_check_unlocked (context, max_priority, fds, n_fds);
+
+ UNLOCK_CONTEXT (context);
+
+ return ready;
+}
+
+static gboolean
+g_main_context_check_unlocked (GMainContext *context,
+ gint max_priority,
+ GPollFD *fds,
+ gint n_fds)
+{
GSource *source;
GSourceIter iter;
GPollRec *pollrec;
@@ -3999,13 +4084,10 @@ g_main_context_check (GMainContext *context,
if (context == NULL)
context = g_main_context_default ();
- LOCK_CONTEXT (context);
-
if (context->in_check_or_prepare)
{
g_warning ("g_main_context_check() called recursively from within a source's check() or "
"prepare() member.");
- UNLOCK_CONTEXT (context);
return FALSE;
}
@@ -4031,7 +4113,6 @@ g_main_context_check (GMainContext *context,
{
TRACE (GLIB_MAIN_CONTEXT_AFTER_CHECK (context, 0));
- UNLOCK_CONTEXT (context);
return FALSE;
}
@@ -4167,8 +4248,6 @@ g_main_context_check (GMainContext *context,
TRACE (GLIB_MAIN_CONTEXT_AFTER_CHECK (context, n_ready));
- UNLOCK_CONTEXT (context);
-
return n_ready > 0;
}
@@ -4193,6 +4272,14 @@ g_main_context_dispatch (GMainContext *context)
LOCK_CONTEXT (context);
+ g_main_context_dispatch_unlocked (context);
+
+ UNLOCK_CONTEXT (context);
+}
+
+static void
+g_main_context_dispatch_unlocked (GMainContext *context)
+{
TRACE (GLIB_MAIN_CONTEXT_BEFORE_DISPATCH (context));
if (context->pending_dispatches->len > 0)
@@ -4201,16 +4288,14 @@ g_main_context_dispatch (GMainContext *context)
}
TRACE (GLIB_MAIN_CONTEXT_AFTER_DISPATCH (context));
-
- UNLOCK_CONTEXT (context);
}
/* HOLDS context lock */
static gboolean
-g_main_context_iterate (GMainContext *context,
- gboolean block,
- gboolean dispatch,
- GThread *self)
+g_main_context_iterate_unlocked (GMainContext *context,
+ gboolean block,
+ gboolean dispatch,
+ GThread *self)
{
gint max_priority = 0;
gint timeout;
@@ -4219,16 +4304,12 @@ g_main_context_iterate (GMainContext *context,
GPollFD *fds = NULL;
gint64 begin_time_nsec G_GNUC_UNUSED;
- UNLOCK_CONTEXT (context);
-
begin_time_nsec = G_TRACE_CURRENT_TIME;
- if (!g_main_context_acquire (context))
+ if (!g_main_context_acquire_unlocked (context))
{
gboolean got_ownership;
- LOCK_CONTEXT (context);
-
if (!block)
return FALSE;
@@ -4239,8 +4320,6 @@ g_main_context_iterate (GMainContext *context,
if (!got_ownership)
return FALSE;
}
- else
- LOCK_CONTEXT (context);
if (!context->cached_poll_array)
{
@@ -4251,38 +4330,33 @@ g_main_context_iterate (GMainContext *context,
allocated_nfds = context->cached_poll_array_size;
fds = context->cached_poll_array;
- UNLOCK_CONTEXT (context);
-
- g_main_context_prepare (context, &max_priority);
+ g_main_context_prepare_unlocked (context, &max_priority);
- while ((nfds = g_main_context_query (context, max_priority, &timeout, fds,
- allocated_nfds)) > allocated_nfds)
+ while ((nfds = g_main_context_query_unlocked (
+ context, max_priority, &timeout, fds,
+ allocated_nfds)) > allocated_nfds)
{
- LOCK_CONTEXT (context);
g_free (fds);
context->cached_poll_array_size = allocated_nfds = nfds;
context->cached_poll_array = fds = g_new (GPollFD, nfds);
- UNLOCK_CONTEXT (context);
}
if (!block)
timeout = 0;
- g_main_context_poll (context, timeout, max_priority, fds, nfds);
+ g_main_context_poll_unlocked (context, timeout, max_priority, fds, nfds);
- some_ready = g_main_context_check (context, max_priority, fds, nfds);
+ some_ready = g_main_context_check_unlocked (context, max_priority, fds, nfds);
if (dispatch)
- g_main_context_dispatch (context);
+ g_main_context_dispatch_unlocked (context);
- g_main_context_release (context);
+ g_main_context_release_unlocked (context);
g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
"GLib", "g_main_context_iterate",
"Context %p, %s ⇒ %s", context, block ? "blocking" : "non-blocking", some_ready ? "dispatched" : "nothing");
- LOCK_CONTEXT (context);
-
return some_ready;
}
@@ -4304,7 +4378,7 @@ g_main_context_pending (GMainContext *context)
context = g_main_context_default();
LOCK_CONTEXT (context);
- retval = g_main_context_iterate (context, FALSE, FALSE, G_THREAD_SELF);
+ retval = g_main_context_iterate_unlocked (context, FALSE, FALSE, G_THREAD_SELF);
UNLOCK_CONTEXT (context);
return retval;
@@ -4340,7 +4414,7 @@ g_main_context_iteration (GMainContext *context, gboolean may_block)
context = g_main_context_default();
LOCK_CONTEXT (context);
- retval = g_main_context_iterate (context, may_block, TRUE, G_THREAD_SELF);
+ retval = g_main_context_iterate_unlocked (context, may_block, TRUE, G_THREAD_SELF);
UNLOCK_CONTEXT (context);
return retval;
@@ -4438,13 +4512,13 @@ g_main_loop_run (GMainLoop *loop)
/* Hold a reference in case the loop is unreffed from a callback function */
g_atomic_int_inc (&loop->ref_count);
- if (!g_main_context_acquire (loop->context))
+ LOCK_CONTEXT (loop->context);
+
+ if (!g_main_context_acquire_unlocked (loop->context))
{
gboolean got_ownership = FALSE;
/* Another thread owns this context */
- LOCK_CONTEXT (loop->context);
-
g_atomic_int_set (&loop->is_running, TRUE);
while (g_atomic_int_get (&loop->is_running) && !got_ownership)
@@ -4454,34 +4528,35 @@ g_main_loop_run (GMainLoop *loop)
if (!g_atomic_int_get (&loop->is_running))
{
- UNLOCK_CONTEXT (loop->context);
if (got_ownership)
- g_main_context_release (loop->context);
+ g_main_context_release_unlocked (loop->context);
+
+ UNLOCK_CONTEXT (loop->context);
g_main_loop_unref (loop);
return;
}
g_assert (got_ownership);
}
- else
- LOCK_CONTEXT (loop->context);
- if (loop->context->in_check_or_prepare)
+ if G_UNLIKELY (loop->context->in_check_or_prepare)
{
g_warning ("g_main_loop_run(): called recursively from within a source's "
"check() or prepare() member, iteration not possible.");
+ g_main_context_release_unlocked (loop->context);
+ UNLOCK_CONTEXT (loop->context);
g_main_loop_unref (loop);
return;
}
g_atomic_int_set (&loop->is_running, TRUE);
while (g_atomic_int_get (&loop->is_running))
- g_main_context_iterate (loop->context, TRUE, TRUE, self);
+ g_main_context_iterate_unlocked (loop->context, TRUE, TRUE, self);
+
+ g_main_context_release_unlocked (loop->context);
UNLOCK_CONTEXT (loop->context);
- g_main_context_release (loop->context);
-
g_main_loop_unref (loop);
}
@@ -4548,11 +4623,11 @@ g_main_loop_get_context (GMainLoop *loop)
/* HOLDS: context's lock */
static void
-g_main_context_poll (GMainContext *context,
- gint timeout,
- gint priority,
- GPollFD *fds,
- gint n_fds)
+g_main_context_poll_unlocked (GMainContext *context,
+ int timeout,
+ int priority,
+ GPollFD *fds,
+ int n_fds)
{
#ifdef G_MAIN_POLL_DEBUG
GTimer *poll_timer;
@@ -4575,13 +4650,12 @@ g_main_context_poll (GMainContext *context,
poll_timer = g_timer_new ();
}
#endif
-
- LOCK_CONTEXT (context);
-
poll_func = context->poll_func;
UNLOCK_CONTEXT (context);
ret = (*poll_func) (fds, n_fds, timeout);
+ LOCK_CONTEXT (context);
+
errsv = errno;
if (ret < 0 && errsv != EINTR)
{
@@ -4596,8 +4670,6 @@ g_main_context_poll (GMainContext *context,
#ifdef G_MAIN_POLL_DEBUG
if (_g_main_poll_debug)
{
- LOCK_CONTEXT (context);
-
g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds",
n_fds,
timeout,
@@ -4634,8 +4706,6 @@ g_main_context_poll (GMainContext *context,
pollrec = pollrec->next;
}
g_print ("\n");
-
- UNLOCK_CONTEXT (context);
}
#endif
} /* if (n_fds || timeout != 0) */
@@ -5340,21 +5410,7 @@ g_timeout_add_seconds_full (gint priority,
gpointer data,
GDestroyNotify notify)
{
- GSource *source;
- guint id;
-
- g_return_val_if_fail (function != NULL, 0);
-
- source = g_timeout_source_new_seconds (interval);
-
- if (priority != G_PRIORITY_DEFAULT)
- g_source_set_priority (source, priority);
-
- g_source_set_callback (source, function, data, notify);
- id = g_source_attach (source, NULL);
- g_source_unref (source);
-
- return id;
+ return timeout_add_full (priority, interval, TRUE, FALSE, function, data, notify);
}
/**
@@ -5401,6 +5457,26 @@ g_timeout_add_seconds (guint interval,
return g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval, function, data, NULL);
}
+/**
+ * g_timeout_add_seconds_once:
+ * @interval: the time after which the function will be called, in seconds
+ * @function: function to call
+ * @data: data to pass to @function
+ *
+ * This function behaves like g_timeout_add_once() but with a range in seconds.
+ *
+ * Returns: the ID (greater than 0) of the event source
+ *
+ * Since: 2.78
+ */
+guint
+g_timeout_add_seconds_once (guint interval,
+ GSourceOnceFunc function,
+ gpointer data)
+{
+ return timeout_add_full (G_PRIORITY_DEFAULT, interval, TRUE, TRUE, (GSourceFunc) function, data, NULL);
+}
+
/* Child watch functions */
#ifdef G_OS_WIN32
diff --git a/glib/gmain.h b/glib/gmain.h
index ae3cc3ec5..14a1d2b06 100644
--- a/glib/gmain.h
+++ b/glib/gmain.h
@@ -73,7 +73,7 @@ typedef struct _GMainContext GMainContext;
* GMainLoop:
*
* The `GMainLoop` struct is an opaque data type
- * representing the main event loop of a GLib or GTK+ application.
+ * representing the main event loop of a GLib or GTK application.
*/
typedef struct _GMainLoop GMainLoop;
@@ -324,7 +324,7 @@ struct _GSourceFuncs
*
* Use this for high priority event sources.
*
- * It is not used within GLib or GTK+.
+ * It is not used within GLib or GTK.
*/
#define G_PRIORITY_HIGH -100
@@ -344,7 +344,7 @@ struct _GSourceFuncs
*
* Use this for high priority idle functions.
*
- * GTK+ uses %G_PRIORITY_HIGH_IDLE + 10 for resizing operations,
+ * GTK uses %G_PRIORITY_HIGH_IDLE + 10 for resizing operations,
* and %G_PRIORITY_HIGH_IDLE + 20 for redrawing operations. (This is
* done to ensure that any pending resizes are processed before any
* pending redraws, so that widgets are not redrawn twice unnecessarily.)
@@ -366,7 +366,7 @@ struct _GSourceFuncs
*
* Use this for very low priority background tasks.
*
- * It is not used within GLib or GTK+.
+ * It is not used within GLib or GTK.
*/
#define G_PRIORITY_LOW 300
@@ -800,6 +800,10 @@ GLIB_AVAILABLE_IN_ALL
guint g_timeout_add_seconds (guint interval,
GSourceFunc function,
gpointer data);
+GLIB_AVAILABLE_IN_2_78
+guint g_timeout_add_seconds_once (guint interval,
+ GSourceOnceFunc function,
+ gpointer data);
GLIB_AVAILABLE_IN_ALL
guint g_child_watch_add_full (gint priority,
GPid pid,
diff --git a/glib/gmessages.c b/glib/gmessages.c
index 541b08130..45906a754 100644
--- a/glib/gmessages.c
+++ b/glib/gmessages.c
@@ -241,7 +241,7 @@
* not advisable, as it cannot be filtered against using the `G_MESSAGES_DEBUG`
* environment variable.
*
- * For example, GTK+ uses this in its `Makefile.am`:
+ * For example, GTK uses this in its `Makefile.am`:
* |[
* AM_CPPFLAGS = -DG_LOG_DOMAIN=\"Gtk\"
* ]|
@@ -831,7 +831,7 @@ g_log_set_fatal_mask (const gchar *log_domain,
* | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
* ]|
*
- * This example adds a log handler for all critical messages from GTK+:
+ * This example adds a log handler for all critical messages from GTK:
*
* |[<!-- language="C" -->
* g_log_set_handler ("Gtk", G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL
@@ -3295,7 +3295,7 @@ g_log_default_handler (const gchar *log_domain,
* Any messages passed to g_print() will be output via
* the new handler. The default handler outputs
* the encoded message to stdout. By providing your own handler
- * you can redirect the output, to a GTK+ widget or a
+ * you can redirect the output, to a GTK widget or a
* log file for example.
*
* Since 2.76 this functions always returns a valid
@@ -3424,7 +3424,7 @@ g_print (const gchar *format,
* Any messages passed to g_printerr() will be output via
* the new handler. The default handler outputs the encoded
* message to stderr. By providing your own handler you can
- * redirect the output, to a GTK+ widget or a log file for
+ * redirect the output, to a GTK widget or a log file for
* example.
*
* Since 2.76 this functions always returns a valid
diff --git a/glib/goption.c b/glib/goption.c
index 64aed7a03..ee40e90bd 100644
--- a/glib/goption.c
+++ b/glib/goption.c
@@ -65,7 +65,7 @@
* Help Options:
* -h, --help Show help options
* --help-all Show all help options
- * --help-gtk Show GTK+ Options
+ * --help-gtk Show GTK Options
*
* Application Options:
* -r, --repeats=N Average over N repetitions
diff --git a/glib/gquark.c b/glib/gquark.c
index cdd9bdf9a..42cb39364 100644
--- a/glib/gquark.c
+++ b/glib/gquark.c
@@ -246,7 +246,7 @@ g_quark_from_string (const gchar *string)
* with statically allocated strings in the main program, but not with
* statically allocated memory in dynamically loaded modules, if you
* expect to ever unload the module again (e.g. do not use this
- * function in GTK+ theme engines).
+ * function in GTK theme engines).
*
* This function must not be used before library constructors have finished
* running. In particular, this means it cannot be used to initialize global
diff --git a/glib/grefcount.h b/glib/grefcount.h
index 88fc716e7..53b96932e 100644
--- a/glib/grefcount.h
+++ b/glib/grefcount.h
@@ -50,6 +50,60 @@ GLIB_AVAILABLE_IN_2_58
gboolean g_atomic_ref_count_compare (gatomicrefcount *arc,
gint val);
+/**
+ * G_REF_COUNT_INIT:
+ *
+ * Evaluates to the initial reference count for `grefcount`.
+ *
+ * This macro is useful for initializing `grefcount` fields inside
+ * structures, for instance:
+ *
+ * |[<!-- language="C" -->
+ * typedef struct {
+ * grefcount ref_count;
+ * char *name;
+ * char *address;
+ * } Person;
+ *
+ * static const Person default_person = {
+ * .ref_count = G_REF_COUNT_INIT,
+ * .name = "Default name",
+ * .address = "Default address",
+ * };
+ * ]|
+ *
+ * Since: 2.78
+ */
+#define G_REF_COUNT_INIT -1 \
+ GLIB_AVAILABLE_MACRO_IN_2_78
+
+/**
+ * G_ATOMIC_REF_COUNT_INIT:
+ *
+ * Evaluates to the initial reference count for `gatomicrefcount`.
+ *
+ * This macro is useful for initializing `gatomicrefcount` fields inside
+ * structures, for instance:
+ *
+ * |[<!-- language="C" -->
+ * typedef struct {
+ * gatomicrefcount ref_count;
+ * char *name;
+ * char *address;
+ * } Person;
+ *
+ * static const Person default_person = {
+ * .ref_count = G_ATOMIC_REF_COUNT_INIT,
+ * .name = "Default name",
+ * .address = "Default address",
+ * };
+ * ]|
+ *
+ * Since: 2.78
+ */
+#define G_ATOMIC_REF_COUNT_INIT 1 \
+ GLIB_AVAILABLE_MACRO_IN_2_78
+
/* On GCC we can use __extension__ to inline the API without using
* ancillary functions; we only do this when disabling checks, as
* it disables warnings when saturating the reference counters
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index e98294ed3..0f0853259 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <inttypes.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
@@ -174,7 +175,7 @@
* }
* ]|
*
- * ### Integrating GTest in your project
+ * ## Integrating GTest in your project
*
* If you are using the [Meson](http://mesonbuild.com) build system, you will
* typically use the provided `test()` primitive to call the test binaries,
@@ -3487,6 +3488,43 @@ g_assertion_message_expr (const char *domain,
}
void
+g_assertion_message_cmpint (const char *domain,
+ const char *file,
+ int line,
+ const char *func,
+ const char *expr,
+ guint64 arg1,
+ const char *cmp,
+ guint64 arg2,
+ char numtype)
+{
+ char *s = NULL;
+
+ switch (numtype)
+ {
+ case 'i':
+ s = g_strdup_printf ("assertion failed (%s): "
+ "(%" PRIi64 " %s %" PRIi64 ")",
+ expr, (int64_t) arg1, cmp, (int64_t) arg2);
+ break;
+ case 'u':
+ s = g_strdup_printf ("assertion failed (%s): "
+ "(%" PRIu64 " %s %" PRIu64 ")",
+ expr, (uint64_t) arg1, cmp, (uint64_t) arg2);
+ break;
+ case 'x':
+ s = g_strdup_printf ("assertion failed (%s): "
+ "(0x%08" PRIx64 " %s 0x%08" PRIx64 ")",
+ expr, (uint64_t) arg1, cmp, (uint64_t) arg2);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ g_assertion_message (domain, file, line, func, s);
+ g_free (s);
+}
+
+void
g_assertion_message_cmpnum (const char *domain,
const char *file,
int line,
@@ -3501,10 +3539,16 @@ g_assertion_message_cmpnum (const char *domain,
switch (numtype)
{
- case 'i': s = g_strdup_printf ("assertion failed (%s): (%" G_GINT64_MODIFIER "i %s %" G_GINT64_MODIFIER "i)", expr, (gint64) arg1, cmp, (gint64) arg2); break;
- case 'x': s = g_strdup_printf ("assertion failed (%s): (0x%08" G_GINT64_MODIFIER "x %s 0x%08" G_GINT64_MODIFIER "x)", expr, (guint64) arg1, cmp, (guint64) arg2); break;
case 'f': s = g_strdup_printf ("assertion failed (%s): (%.9g %s %.9g)", expr, (double) arg1, cmp, (double) arg2); break;
/* ideally use: floats=%.7g double=%.17g */
+ case 'i':
+ case 'x':
+ /* Backwards compatibility to apps compiled before 2.78 */
+ g_assertion_message_cmpint (domain, file, line, func, expr,
+ (guint64) arg1, cmp, (guint64) arg2, numtype);
+ break;
+ default:
+ g_assert_not_reached ();
}
g_assertion_message (domain, file, line, func, s);
g_free (s);
diff --git a/glib/gtestutils.h b/glib/gtestutils.h
index 86ee4e521..9406ff0d8 100644
--- a/glib/gtestutils.h
+++ b/glib/gtestutils.h
@@ -49,6 +49,26 @@ typedef void (*GTestFixtureFunc) (gpointer fixture,
g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
#s1 " " #cmp " " #s2, __s1, #cmp, __s2); \
} G_STMT_END
+#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_78
+#define g_assert_cmpint(n1, cmp, n2) G_STMT_START { \
+ gint64 __n1 = (n1), __n2 = (n2); \
+ if (__n1 cmp __n2) ; else \
+ g_assertion_message_cmpint (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); \
+ } G_STMT_END
+#define g_assert_cmpuint(n1, cmp, n2) G_STMT_START { \
+ guint64 __n1 = (n1), __n2 = (n2); \
+ if (__n1 cmp __n2) ; else \
+ g_assertion_message_cmpint (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'u'); \
+ } G_STMT_END
+#define g_assert_cmphex(n1, cmp, n2) G_STMT_START { \
+ guint64 __n1 = (n1), __n2 = (n2); \
+ if (__n1 cmp __n2) ; else \
+ g_assertion_message_cmpint (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'x'); \
+ } G_STMT_END
+#else /* GLIB_VERSION_MIN_REQUIRED < GLIB_VERSION_2_78 */
#define g_assert_cmpint(n1, cmp, n2) G_STMT_START { \
gint64 __n1 = (n1), __n2 = (n2); \
if (__n1 cmp __n2) ; else \
@@ -67,6 +87,7 @@ typedef void (*GTestFixtureFunc) (gpointer fixture,
g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
#n1 " " #cmp " " #n2, (long double) __n1, #cmp, (long double) __n2, 'x'); \
} G_STMT_END
+#endif /* GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_78 */
#define g_assert_cmpfloat(n1,cmp,n2) G_STMT_START { \
long double __n1 = (long double) (n1), __n2 = (long double) (n2); \
if (__n1 cmp __n2) ; else \
@@ -80,6 +101,25 @@ typedef void (*GTestFixtureFunc) (gpointer fixture,
g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
#n1 " == " #n2 " (+/- " #epsilon ")", __n1, "==", __n2, 'f'); \
} G_STMT_END
+#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_78
+#define g_assert_cmpmem(m1, l1, m2, l2) G_STMT_START {\
+ gconstpointer __m1 = m1, __m2 = m2; \
+ size_t __l1 = (size_t) l1, __l2 = (size_t) l2; \
+ if (__l1 != 0 && __m1 == NULL) \
+ g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ "assertion failed (" #l1 " == 0 || " #m1 " != NULL)"); \
+ else if (__l2 != 0 && __m2 == NULL) \
+ g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ "assertion failed (" #l2 " == 0 || " #m2 " != NULL)"); \
+ else if (__l1 != __l2) \
+ g_assertion_message_cmpint (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ #l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", \
+ __l1, "==", __l2, 'u'); \
+ else if (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
+ g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ "assertion failed (" #m1 " == " #m2 ")"); \
+ } G_STMT_END
+#else /* GLIB_VERSION_MIN_REQUIRED < GLIB_VERSION_2_78 */
#define g_assert_cmpmem(m1, l1, m2, l2) G_STMT_START {\
gconstpointer __m1 = m1, __m2 = m2; \
size_t __l1 = (size_t) l1, __l2 = (size_t) l2; \
@@ -97,6 +137,7 @@ typedef void (*GTestFixtureFunc) (gpointer fixture,
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
"assertion failed (" #m1 " == " #m2 ")"); \
} G_STMT_END
+#endif /* GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_78 */
#define g_assert_cmpvariant(v1, v2) \
G_STMT_START \
{ \
@@ -567,6 +608,16 @@ void g_assertion_message_cmpstrv (const char *domain,
const char * const *arg1,
const char * const *arg2,
gsize first_wrong_idx) G_ANALYZER_NORETURN;
+GLIB_AVAILABLE_IN_2_78
+void g_assertion_message_cmpint (const char *domain,
+ const char *file,
+ int line,
+ const char *func,
+ const char *expr,
+ guint64 arg1,
+ const char *cmp,
+ guint64 arg2,
+ char numtype) G_ANALYZER_NORETURN;
GLIB_AVAILABLE_IN_ALL
void g_assertion_message_cmpnum (const char *domain,
const char *file,
diff --git a/glib/gthreadpool.c b/glib/gthreadpool.c
index 3151cb6ad..c18de89d0 100644
--- a/glib/gthreadpool.c
+++ b/glib/gthreadpool.c
@@ -536,10 +536,14 @@ g_thread_pool_start_thread (GRealThreadPool *pool,
* since their threads are never considered idle and returned to the
* global pool.
*
- * Note that the threads used by exclusive threadpools will all inherit the
+ * Note that the threads used by exclusive thread pools will all inherit the
* scheduler settings of the current thread while the threads used by
- * non-exclusive threadpools will inherit the scheduler settings from the
- * first thread that created such a threadpool.
+ * non-exclusive thread pools will inherit the scheduler settings from the
+ * first thread that created such a thread pool.
+ *
+ * At least one thread will be spawned when this function is called, either to
+ * create the @max_threads exclusive threads, or to preserve the scheduler
+ * settings of the current thread for future spawns.
*
* @error can be %NULL to ignore errors, or non-%NULL to report
* errors. An error can only occur when @exclusive is set to %TRUE
@@ -576,6 +580,9 @@ g_thread_pool_new (GFunc func,
* to g_thread_pool_push() in the case that the #GThreadPool is stopped
* and freed before all tasks have been executed.
*
+ * @item_free_func will *not* be called on items successfully passed to @func.
+ * @func is responsible for freeing the items passed to it.
+ *
* Returns: (transfer full): the new #GThreadPool
*
* Since: 2.70
diff --git a/glib/gthreadprivate.h b/glib/gthreadprivate.h
index 9c847e039..74d37ba32 100644
--- a/glib/gthreadprivate.h
+++ b/glib/gthreadprivate.h
@@ -65,9 +65,13 @@ struct _GRealThread
#define g_futex_simple(uaddr, futex_op, ...) \
G_STMT_START \
{ \
+ int saved_errno = errno; \
int res = syscall (__NR_futex_time64, uaddr, (gsize) futex_op, __VA_ARGS__); \
if (res < 0 && errno == ENOSYS) \
- syscall (__NR_futex, uaddr, (gsize) futex_op, __VA_ARGS__); \
+ { \
+ errno = saved_errno; \
+ syscall (__NR_futex, uaddr, (gsize) futex_op, __VA_ARGS__); \
+ } \
} \
G_STMT_END
#elif defined(__NR_futex_time64)
diff --git a/glib/gtimer.c b/glib/gtimer.c
index d2d259918..dde502a15 100644
--- a/glib/gtimer.c
+++ b/glib/gtimer.c
@@ -269,6 +269,9 @@ g_timer_is_active (GTimer *timer)
void
g_usleep (gulong microseconds)
{
+ if G_UNLIKELY (microseconds == 0)
+ return;
+
#ifdef G_OS_WIN32
/* Round up to the next millisecond */
Sleep (microseconds ? (1 + (microseconds - 1) / 1000) : 0);
diff --git a/glib/gtypes.h b/glib/gtypes.h
index 9d68f93a7..9d912d523 100644
--- a/glib/gtypes.h
+++ b/glib/gtypes.h
@@ -165,7 +165,7 @@ typedef gpointer (*GCopyFunc) (gconstpointer src,
*
* Declares a type of function which takes an arbitrary
* data pointer argument and has no return value. It is
- * not currently used in GLib or GTK+.
+ * not currently used in GLib or GTK.
*/
typedef void (*GFreeFunc) (gpointer data);
diff --git a/glib/guri.c b/glib/guri.c
index 5fa668873..950becf12 100644
--- a/glib/guri.c
+++ b/glib/guri.c
@@ -1760,7 +1760,7 @@ g_uri_join_internal (GUriFlags flags,
*
* When @host is present, @path must either be empty or begin with a slash (`/`)
* character. When @host is not present, @path cannot begin with two slash
- characters (`//`). See
+ * characters (`//`). See
* [RFC 3986, section 3](https://tools.ietf.org/html/rfc3986#section-3).
*
* See also g_uri_join_with_user(), which allows specifying the
diff --git a/glib/gutf8.c b/glib/gutf8.c
index a018f2a8d..3fa2def66 100644
--- a/glib/gutf8.c
+++ b/glib/gutf8.c
@@ -1678,7 +1678,7 @@ fast_validate_len (const char *str,
* Note that g_utf8_validate() returns %FALSE if @max_len is
* positive and any of the @max_len bytes are nul.
*
- * Returns %TRUE if all of @str was valid. Many GLib and GTK+
+ * Returns %TRUE if all of @str was valid. Many GLib and GTK
* routines require valid UTF-8 as input; so data read from a file
* or the network should be checked with g_utf8_validate() before
* doing anything else with it.
diff --git a/glib/gutils.c b/glib/gutils.c
index dce7cbee5..362c55aff 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -1138,7 +1138,7 @@ static const gchar *g_prgname = NULL; /* always a quark */
* in contrast to g_get_application_name().
*
* If you are using #GApplication the program name is set in
- * g_application_run(). In case of GDK or GTK+ it is set in
+ * g_application_run(). In case of GDK or GTK it is set in
* gdk_init(), which is called by gtk_init() and the
* #GtkApplication::startup handler. The program name is found by
* taking the last component of @argv[0].
@@ -1167,7 +1167,7 @@ g_get_prgname (void)
* in contrast to g_set_application_name().
*
* If you are using #GApplication the program name is set in
- * g_application_run(). In case of GDK or GTK+ it is set in
+ * g_application_run(). In case of GDK or GTK it is set in
* gdk_init(), which is called by gtk_init() and the
* #GtkApplication::startup handler. The program name is found by
* taking the last component of @argv[0].
@@ -2575,16 +2575,16 @@ g_win32_get_system_data_dirs_for_module_real (void (*address_of_function)(void))
p = get_special_folder (&FOLDERID_ProgramData);
if (p)
g_array_append_val (data_dirs, p);
-
+
/* Documents and Settings\All Users\Documents */
p = get_special_folder (&FOLDERID_PublicDocuments);
if (p)
g_array_append_val (data_dirs, p);
-
+
/* Using the above subfolders of Documents and Settings perhaps
* makes sense from a Windows perspective.
*
- * But looking at the actual use cases of this function in GTK+
+ * But looking at the actual use cases of this function in GTK
* and GNOME software, what we really want is the "share"
* subdirectory of the installation directory for the package
* our caller is a part of.
diff --git a/glib/gvariant.c b/glib/gvariant.c
index d7b305188..40cda9c9d 100644
--- a/glib/gvariant.c
+++ b/glib/gvariant.c
@@ -1352,8 +1352,8 @@ g_variant_new_printf (const gchar *format_string,
* g_variant_new_object_path:
* @object_path: a normal C nul-terminated string
*
- * Creates a D-Bus object path #GVariant with the contents of @string.
- * @string must be a valid D-Bus object path. Use
+ * Creates a D-Bus object path #GVariant with the contents of @object_path.
+ * @object_path must be a valid D-Bus object path. Use
* g_variant_is_object_path() if you're not sure.
*
* Returns: (transfer none): a floating reference to a new object path #GVariant instance
diff --git a/glib/gwin32.c b/glib/gwin32.c
index 85053c079..ab9e4b571 100644
--- a/glib/gwin32.c
+++ b/glib/gwin32.c
@@ -123,8 +123,8 @@ g_win32_getlocale (void)
const gchar *script = NULL;
/* Let the user override the system settings through environment
- * variables, as on POSIX systems. Note that in GTK+ applications
- * since GTK+ 2.10.7 setting either LC_ALL or LANG also sets the
+ * variables, as on POSIX systems. Note that in GTK applications
+ * since GTK 2.10.7 setting either LC_ALL or LANG also sets the
* Win32 locale and C library locale through code in gtkmain.c.
*/
if (((ev = g_getenv ("LC_ALL")) != NULL && ev[0] != '\0')
diff --git a/glib/meson.build b/glib/meson.build
index 744275649..898446e00 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -444,10 +444,16 @@ pkg.generate(libglib,
libraries_private : [win32_ldflags],
subdirs : ['glib-2.0'],
extra_cflags : ['-I${libdir}/glib-2.0/include'] + win32_cflags,
- variables : ['bindir=' + join_paths('${prefix}', get_option('bindir')),
- 'glib_genmarshal=' + join_paths('${bindir}', 'glib-genmarshal'),
- 'gobject_query=' + join_paths('${bindir}', 'gobject-query'),
- 'glib_mkenums=' + join_paths('${bindir}', 'glib-mkenums')],
+ variables : [
+ 'bindir=' + '${prefix}' / get_option('bindir'),
+ 'datadir=' + '${prefix}' / get_option('datadir'),
+ 'glib_genmarshal=' + '${bindir}' / 'glib-genmarshal',
+ 'gobject_query=' + '${bindir}' / 'gobject-query',
+ 'glib_mkenums=' + '${bindir}' / 'glib-mkenums',
+ 'glib_valgrind_suppressions=' + '${datadir}' /
+ valgrind_suppression_file_install_subdir /
+ fs.name(valgrind_suppression_file),
+ ],
version : glib_version,
install_dir : glib_pkgconfigreldir,
filebase : 'glib-2.0',
diff --git a/glib/tests/assert-msg-test.c b/glib/tests/assert-msg-test.c
index 75591c853..b46496635 100644
--- a/glib/tests/assert-msg-test.c
+++ b/glib/tests/assert-msg-test.c
@@ -1,7 +1,39 @@
+/* GLib testing framework examples and tests
+ *
+ * Copyright © 2009 Canonical Limited
+ *
+ * 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/>.
+ */
+
+#include "config.h"
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
#include <glib.h>
-int main(int argc, char **argv)
+int
+main (int argc,
+ char **argv)
{
- g_assert(42 < 0);
- return 0;
+#ifdef HAVE_SYS_RESOURCE_H
+ /* We expect this test to abort, so try to avoid that creating a coredump */
+ struct rlimit limit = { 0, 0 };
+ (void) setrlimit (RLIMIT_CORE, &limit);
+#endif
+
+ g_assert (42 < 0);
+ return 0;
}
diff --git a/glib/tests/mainloop.c b/glib/tests/mainloop.c
index 4c63df168..5c34cf4ae 100644
--- a/glib/tests/mainloop.c
+++ b/glib/tests/mainloop.c
@@ -1169,6 +1169,75 @@ test_unref_while_pending (void)
g_assert_cmpint (n_finalized, ==, 1);
}
+typedef struct {
+ GSource parent;
+ GMainLoop *loop;
+} LoopedSource;
+
+static gboolean
+prepare_loop_run (GSource *source, gint *time)
+{
+ LoopedSource *looped_source = (LoopedSource*) source;
+ *time = 0;
+
+ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
+ "*called recursively from within a source's check() "
+ "or prepare() member*");
+ g_main_loop_run (looped_source->loop);
+ g_test_assert_expected_messages ();
+
+ return FALSE;
+}
+
+static gboolean
+check_loop_run (GSource *source)
+{
+ LoopedSource *looped_source = (LoopedSource*) source;
+
+ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
+ "*called recursively from within a source's check() "
+ "or prepare() member*");
+ g_main_loop_run (looped_source->loop);
+ g_test_assert_expected_messages ();
+
+ return TRUE;
+}
+
+static gboolean
+dispatch_loop_run (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ LoopedSource *looped_source = (LoopedSource*) source;
+
+ g_main_loop_quit (looped_source->loop);
+
+ return FALSE;
+}
+
+static void
+test_recursive_loop_child_sources (void)
+{
+ GMainLoop *loop;
+ GSource *source;
+ GSourceFuncs loop_run_funcs = {
+ prepare_loop_run, check_loop_run, dispatch_loop_run, NULL, NULL, NULL,
+ };
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ source = g_source_new (&loop_run_funcs, sizeof (LoopedSource));
+ ((LoopedSource*)source)->loop = loop;
+
+ g_source_attach (source, NULL);
+
+ g_main_loop_run (loop);
+ g_source_unref (source);
+
+ g_main_loop_unref (loop);
+}
+
+
#ifdef G_OS_UNIX
#include <glib-unix.h>
@@ -2440,6 +2509,7 @@ main (int argc, char *argv[])
g_test_add_func ("/mainloop/invoke", test_invoke);
g_test_add_func ("/mainloop/child_sources", test_child_sources);
g_test_add_func ("/mainloop/recursive_child_sources", test_recursive_child_sources);
+ g_test_add_func ("/mainloop/recursive_loop_child_sources", test_recursive_loop_child_sources);
g_test_add_func ("/mainloop/swapping_child_sources", test_swapping_child_sources);
g_test_add_func ("/mainloop/blocked_child_sources", test_blocked_child_sources);
g_test_add_func ("/mainloop/source_time", test_source_time);
diff --git a/glib/tests/meson.build b/glib/tests/meson.build
index 72a6ff92b..09ecd5ab3 100644
--- a/glib/tests/meson.build
+++ b/glib/tests/meson.build
@@ -491,3 +491,34 @@ if not meson.is_cross_build() and host_system != 'windows'
endif
endif
+if have_bash and have_pkg_config
+ prefix = get_option('prefix')
+ if prefix.endswith(':/')
+ prefix += '/'
+ endif
+ test('glib-2.0-pkg-config',
+ bash,
+ args: [
+ '-xe', '-c',
+ '\n'.join([
+ 'pkg-config --validate glib-2.0',
+ 'test "$(pkg-config --modversion glib-2.0)" = "@0@"'.format(glib_version),
+ 'test "$(pkg-config --variable=prefix glib-2.0)" = "@0@"'.format(
+ get_option('prefix')),
+ 'test "$(pkg-config --variable=datadir glib-2.0)" = "@0@"'.format(
+ prefix / get_option('datadir')),
+ 'test "$(pkg-config --variable=gobject_query glib-2.0)" = "@0@"'.format(
+ prefix / get_option('bindir') / 'gobject-query'),
+ 'test "$(pkg-config --variable=glib_mkenums glib-2.0)" = "@0@"'.format(
+ prefix / get_option('bindir') / 'glib-mkenums'),
+ 'test "$(pkg-config --variable=glib_valgrind_suppressions glib-2.0)" = "@0@"'.format(
+ prefix / get_option('datadir') /
+ valgrind_suppression_file_install_subdir / fs.name(valgrind_suppression_file)),
+ ]),
+ ],
+ suite: ['glib', 'core', 'no-valgrind', 'pkg-config'],
+ env: {
+ 'PKG_CONFIG_PATH': meson.project_build_root() / 'meson-private',
+ },
+ )
+endif
diff --git a/glib/tests/messages-low-memory.c b/glib/tests/messages-low-memory.c
index af35c4e26..ecb507024 100644
--- a/glib/tests/messages-low-memory.c
+++ b/glib/tests/messages-low-memory.c
@@ -23,6 +23,9 @@
#include "config.h"
#include <dlfcn.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
#include <glib.h>
static gboolean malloc_eom = FALSE;
@@ -56,6 +59,12 @@ int
main (int argc,
char *argv[])
{
+#ifdef HAVE_SYS_RESOURCE_H
+ /* We expect this test to abort, so try to avoid that creating a coredump */
+ struct rlimit limit = { 0, 0 };
+ (void) setrlimit (RLIMIT_CORE, &limit);
+#endif
+
g_setenv ("LC_ALL", "C", TRUE);
#ifndef ENOMEM
diff --git a/glib/tests/mutex.c b/glib/tests/mutex.c
index 7aeb4a561..2d0ef1ff3 100644
--- a/glib/tests/mutex.c
+++ b/glib/tests/mutex.c
@@ -195,7 +195,7 @@ test_mutex_perf (gconstpointer data)
gint x = -1;
guint i;
- count_to = g_test_perf () ? 100000000 : 1;
+ count_to = g_test_perf () ? 100000000 : n_threads + 1;
g_assert (n_threads <= G_N_ELEMENTS (threads));
diff --git a/glib/tests/rec-mutex.c b/glib/tests/rec-mutex.c
index d7cd62431..ad38a69a8 100644
--- a/glib/tests/rec-mutex.c
+++ b/glib/tests/rec-mutex.c
@@ -204,7 +204,7 @@ test_mutex_perf (gconstpointer data)
n_threads = c / 256;
depth = c % 256;
- count_to = g_test_perf () ? 100000000 : 1;
+ count_to = g_test_perf () ? 100000000 : n_threads + 1;
for (i = 0; i < n_threads - 1; i++)
threads[i] = g_thread_new ("test", addition_thread, &x);
diff --git a/glib/tests/timeout.c b/glib/tests/timeout.c
index acbb8f3e1..1ae3f3a34 100644
--- a/glib/tests/timeout.c
+++ b/glib/tests/timeout.c
@@ -20,6 +20,12 @@ unreachable_callback (gpointer data)
}
static void
+unreachable_void_callback (gpointer data)
+{
+ g_assert_not_reached ();
+}
+
+static void
test_seconds (void)
{
guint id;
@@ -52,6 +58,19 @@ test_seconds (void)
}
static void
+test_seconds_once (void)
+{
+ /* Use the same principle as in test_seconds() */
+ loop = g_main_loop_new (NULL, FALSE);
+
+ g_timeout_add_once (2100, stop_waiting, NULL);
+ g_timeout_add_seconds_once (21475, unreachable_void_callback, NULL);
+
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+}
+
+static void
test_weeks_overflow (void)
{
guint id;
@@ -192,6 +211,7 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/timeout/seconds", test_seconds);
+ g_test_add_func ("/timeout/seconds-once", test_seconds_once);
g_test_add_func ("/timeout/weeks-overflow", test_weeks_overflow);
g_test_add_func ("/timeout/far-future-ready-time", test_far_future_ready_time);
g_test_add_func ("/timeout/rounding", test_rounding);
diff --git a/glib/tests/timer.c b/glib/tests/timer.c
index 3a2d1019c..be4cb957b 100644
--- a/glib/tests/timer.c
+++ b/glib/tests/timer.c
@@ -346,6 +346,29 @@ test_timeval_to_iso8601_overflow (void)
g_assert_null (out);
}
+static void
+test_usleep_with_zero_wait (void)
+{
+ GTimer *timer;
+ gdouble elapsed0, elapsed1;
+
+ timer = g_timer_new ();
+
+ g_timer_start (timer);
+ g_usleep (0);
+ elapsed0 = g_timer_elapsed (timer, NULL);
+ g_timer_stop (timer);
+
+ g_timer_start (timer);
+ g_usleep (1);
+ elapsed1 = g_timer_elapsed (timer, NULL);
+ g_timer_stop (timer);
+
+ g_assert_cmpfloat (elapsed0, <=, elapsed1);
+
+ g_clear_pointer (&timer, g_timer_destroy);
+}
+
int
main (int argc, char *argv[])
{
@@ -360,6 +383,7 @@ main (int argc, char *argv[])
g_test_add_func ("/timeval/from-iso8601", test_timeval_from_iso8601);
g_test_add_func ("/timeval/to-iso8601", test_timeval_to_iso8601);
g_test_add_func ("/timeval/to-iso8601/overflow", test_timeval_to_iso8601_overflow);
+ g_test_add_func ("/usleep/with-zero-wait", test_usleep_with_zero_wait);
return g_test_run ();
}
diff --git a/gmodule/meson.build b/gmodule/meson.build
index 237992fcc..f7b41536e 100644
--- a/gmodule/meson.build
+++ b/gmodule/meson.build
@@ -137,10 +137,13 @@ pkg.generate(libraries : [libgmodule],
description : 'Dynamic module loader for GLib',
)
+gmodule_inc_dep = declare_dependency(
+ include_directories: [gmoduleinc],
+ sources: [gmodule_visibility_h],
+)
+
libgmodule_dep = declare_dependency(link_with : libgmodule,
- include_directories : [gmoduleinc],
- sources : [gmodule_visibility_h],
- dependencies : [libglib_dep])
+ dependencies : [libglib_dep, gmodule_inc_dep])
meson.override_dependency('gmodule-no-export-2.0', libgmodule_dep)
meson.override_dependency('gmodule-export-2.0', libgmodule_dep)
diff --git a/gmodule/tests/meson.build b/gmodule/tests/meson.build
index ec7eb68fd..5374c1c2a 100644
--- a/gmodule/tests/meson.build
+++ b/gmodule/tests/meson.build
@@ -124,3 +124,31 @@ foreach test_name, extra_args : gmodule_tests
suite : suite,
)
endforeach
+
+if have_bash and have_pkg_config
+ modules = [
+ 'gmodule-no-export-2.0',
+ 'gmodule-export-2.0',
+ 'gmodule-2.0',
+ ]
+
+ foreach module: modules
+ test(module + '-pkg-config',
+ bash,
+ args: [
+ '-xe', '-c',
+ '\n'.join([
+ 'pkg-config --validate ' + module,
+ 'test "$(pkg-config --modversion @0@)" = "@1@"'.format(
+ module, glib_version),
+ 'test "$(pkg-config --variable=prefix @0@)" = "@1@"'.format(
+ module, get_option('prefix')),
+ ]),
+ ],
+ suite: ['gmodule', 'no-valgrind', 'pkg-config'],
+ env: {
+ 'PKG_CONFIG_PATH': meson.project_build_root() / 'meson-private',
+ },
+ )
+ endforeach
+endif
diff --git a/gobject/gobject.c b/gobject/gobject.c
index a61754b9f..b4186c561 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -44,7 +44,7 @@
* @see_also: #GParamSpecObject, g_param_spec_object()
*
* GObject is the fundamental type providing the common attributes and
- * methods for all object types in GTK+, Pango and other libraries
+ * methods for all object types in GTK, Pango and other libraries
* based on GObject. The GObject class provides methods for object
* construction and destruction, property access methods, and signal
* support. Signals are described in detail [here][gobject-Signals].
@@ -136,7 +136,6 @@
* ]|
*/
-
/* --- macros --- */
#define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id)
#define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id))
diff --git a/gobject/gtype.c b/gobject/gtype.c
index dfb01eed1..72ef32cfc 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -87,6 +87,20 @@
* be at least three characters long. There is no upper length limit. The first
* character must be a letter (a–z or A–Z) or an underscore (‘_’). Subsequent
* characters can be letters, numbers or any of ‘-_+’.
+ *
+ * # Runtime Debugging
+ *
+ * When `G_ENABLE_DEBUG` is defined during compilation, the GObject library
+ * supports an environment variable `GOBJECT_DEBUG` that can be set to a
+ * combination of flags to trigger debugging messages about
+ * object bookkeeping and signal emissions during runtime.
+ *
+ * The currently supported flags are:
+ * - `objects`: Tracks all #GObject instances in a global hash table called
+ * `debug_objects_ht`, and prints the still-alive objects on exit.
+ * - `instance-count`: Tracks the number of instances of every #GType and makes
+ * it available via the g_type_get_instance_count() function.
+ * - `signals`: Currently unused.
*/
@@ -3953,8 +3967,8 @@ g_type_query (GType type,
*
* Returns the number of instances allocated of the particular type;
* this is only available if GLib is built with debugging support and
- * the instance_count debug flag is set (by setting the GOBJECT_DEBUG
- * variable to include instance-count).
+ * the `instance-count` debug flag is set (by setting the `GOBJECT_DEBUG`
+ * variable to include `instance-count`).
*
* Returns: the number of instances allocated of the given type;
* if instance counts are not available, returns 0.
@@ -4468,7 +4482,7 @@ _g_type_boxed_init (GType type,
* flags. Since GLib 2.36, the type system is initialised automatically
* and this function does nothing.
*
- * If you need to enable debugging features, use the GOBJECT_DEBUG
+ * If you need to enable debugging features, use the `GOBJECT_DEBUG`
* environment variable.
*
* Deprecated: 2.36: the type system is now initialised automatically
diff --git a/gobject/gtype.h b/gobject/gtype.h
index b68af22ca..4557a5d0c 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -714,7 +714,7 @@ struct _GTypeQuery
* These flags used to be passed to g_type_init_with_debug_flags() which
* is now deprecated.
*
- * If you need to enable debugging features, use the GOBJECT_DEBUG
+ * If you need to enable debugging features, use the `GOBJECT_DEBUG`
* environment variable.
*
* Deprecated: 2.36: g_type_init() is now done automatically
diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c
index b8bd8247e..ec9a584ca 100644
--- a/gobject/tests/signals.c
+++ b/gobject/tests/signals.c
@@ -4,13 +4,13 @@
#define g_assert_cmpflags(type,n1, cmp, n2) G_STMT_START { \
type __n1 = (n1), __n2 = (n2); \
if (__n1 cmp __n2) ; else \
- g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ g_assertion_message_cmpint (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
#n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); \
} G_STMT_END
#define g_assert_cmpenum(type,n1, cmp, n2) G_STMT_START { \
type __n1 = (n1), __n2 = (n2); \
if (__n1 cmp __n2) ; else \
- g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ g_assertion_message_cmpint (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
#n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); \
} G_STMT_END
@@ -1503,6 +1503,20 @@ test_block_handler (void)
g_assert_cmpuint (g_signal_handlers_block_matched (test1, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, test_handler, &count1), ==, 1);
g_assert_cmpuint (g_signal_handlers_unblock_matched (test1, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, test_handler, &count1), ==, 1);
+ /* Test g_signal_handlers_disconnect_matched for G_SIGNAL_MATCH_ID match */
+ g_assert_cmpuint (g_signal_handlers_disconnect_matched (test1,
+ G_SIGNAL_MATCH_ID,
+ simple_id, 0,
+ NULL, NULL, NULL),
+ ==,
+ 1);
+ g_assert_cmpuint (g_signal_handler_find (test1,
+ G_SIGNAL_MATCH_ID,
+ simple_id, 0,
+ NULL, NULL, NULL),
+ ==,
+ 0);
+
g_object_unref (test1);
g_object_unref (test2);
}
diff --git a/gthread/tests/meson.build b/gthread/tests/meson.build
index 53fb78e18..41fad1de4 100644
--- a/gthread/tests/meson.build
+++ b/gthread/tests/meson.build
@@ -52,3 +52,22 @@ foreach test_name, extra_args : gthread_tests
suite : suite,
)
endforeach
+
+if have_bash and have_pkg_config
+ test('gthread-2.0-pkg-config',
+ bash,
+ args: [
+ '-xe', '-c',
+ '\n'.join([
+ 'pkg-config --validate gthread-2.0',
+ 'test "$(pkg-config --modversion gthread-2.0)" = "@0@"'.format(glib_version),
+ 'test "$(pkg-config --variable=prefix gthread-2.0)" = "@0@"'.format(
+ get_option('prefix')),
+ ]),
+ ],
+ suite: ['gthread', 'no-valgrind', 'pkg-config'],
+ env: {
+ 'PKG_CONFIG_PATH': meson.project_build_root() / 'meson-private',
+ },
+ )
+endif
diff --git a/meson.build b/meson.build
index 62334cea4..44284fc10 100644
--- a/meson.build
+++ b/meson.build
@@ -9,6 +9,8 @@ project('glib', 'c',
]
)
+fs = import('fs')
+
cc = meson.get_compiler('c')
c_standards = {}
@@ -175,9 +177,10 @@ add_test_setup('unstable_tests',
# Allow the tests to be easily run under valgrind using --setup=valgrind
valgrind = find_program('valgrind', required: false)
-if valgrind.found()
- suppression_file = files('tools' / 'glib.supp')
+valgrind_suppression_file = files('tools' / 'glib.supp')[0]
+valgrind_suppression_file_install_subdir = 'glib-2.0' / 'valgrind'
+if valgrind.found()
add_test_setup('valgrind',
exclude_suites: [ 'no-valgrind', 'flaky' ],
exe_wrapper: [
@@ -191,7 +194,7 @@ if valgrind.found()
'--show-leak-kinds=definite,possible',
'--show-error-list=yes',
'--suppressions=@0@'.format(meson.project_source_root() /
- '@0@'.format(suppression_file[0])),
+ '@0@'.format(valgrind_suppression_file)),
],
env: common_test_env,
timeout_multiplier: 20,
@@ -409,7 +412,7 @@ if cc.check_header('malloc.h')
glib_conf_prefix = glib_conf_prefix + '#define HAVE_MALLOC_H 1\n'
endif
-if cc.has_header('linux/netlink.h')
+if cc.check_header('linux/netlink.h')
glib_conf.set('HAVE_NETLINK', 1)
endif
@@ -506,7 +509,7 @@ if cc.get_id() == 'gcc' or cc.get_id() == 'clang'
# building with -Wbad-function-cast.
'-Wno-cast-function-type',
# Due to function casts through (void*) we cannot support -Wpedantic:
- # https://wiki.gnome.org/Projects/GLib/CompilerRequirements#Function_pointer_conversions.
+ # ./docs/toolchain-requirements.md#Function_pointer_conversions.
'-Wno-pedantic',
# A zero-length format string shouldn't be considered an issue.
'-Wno-format-zero-length',
@@ -608,6 +611,7 @@ endif
functions = [
'accept4',
'close_range',
+ 'copy_file_range',
'endmntent',
'endservent',
'epoll_create',
@@ -2285,9 +2289,11 @@ if not python_version.version_compare(python_version_req)
endif
# Determine which user environment-dependent files that we want to install
-have_bash = find_program('bash', required : false).found() # For completion scripts
+bash = find_program('bash', required : false)
+have_bash = bash.found() # For completion scripts
bash_comp_dep = dependency('bash-completion', version: '>=2.0', required: false)
have_sh = find_program('sh', required : false).found() # For glib-gettextize
+have_pkg_config = find_program('pkg-config', required: false).found()
# Some installed tests require a custom environment
env_program = find_program('env', required: installed_tests_enabled)
diff --git a/po/gl.po b/po/gl.po
index 73b8e53a3..cfd0a9dc0 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -18,8 +18,8 @@ msgid ""
msgstr ""
"Project-Id-Version: glib.master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2023-02-15 16:30+0000\n"
-"PO-Revision-Date: 2023-02-16 13:07+0100\n"
+"POT-Creation-Date: 2023-04-14 16:57+0000\n"
+"PO-Revision-Date: 2023-04-27 11:06+0200\n"
"Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n"
"Language-Team: Galician <proxecto@trasno.gal>\n"
"Language: gl\n"
@@ -297,7 +297,7 @@ msgstr ""
#: gio/gbufferedinputstream.c:422 gio/gbufferedinputstream.c:500
#: gio/ginputstream.c:181 gio/ginputstream.c:381 gio/ginputstream.c:650
#: gio/ginputstream.c:1052 gio/goutputstream.c:225 gio/goutputstream.c:1051
-#: gio/gpollableinputstream.c:207 gio/gpollableoutputstream.c:279
+#: gio/gpollableinputstream.c:221 gio/gpollableoutputstream.c:293
#, c-format
msgid "Too large count value passed to %s"
msgstr "O valor de conta pasado a %s é demasiado longo"
@@ -320,7 +320,7 @@ msgstr "O fluxo xa se pechou"
msgid "Truncate not supported on base stream"
msgstr "Non se permite truncar no fluxo base"
-#: gio/gcancellable.c:326 gio/gdbusconnection.c:1859 gio/gdbusprivate.c:1420
+#: gio/gcancellable.c:326 gio/gdbusconnection.c:1865 gio/gdbusprivate.c:1420
#: gio/gsimpleasyncresult.c:873 gio/gsimpleasyncresult.c:899
#, c-format
msgid "Operation was cancelled"
@@ -403,17 +403,17 @@ msgstr "Non é posíbel burlar as credenciais neste SO"
msgid "Unexpected early end-of-stream"
msgstr "Final de fluxo inesperadamente prematuro"
-#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:234 gio/gdbusaddress.c:321
+#: gio/gdbusaddress.c:168 gio/gdbusaddress.c:240 gio/gdbusaddress.c:327
#, c-format
msgid "Unsupported key “%s” in address entry “%s”"
msgstr "Clave «%s» non admitida na entrada do enderezo «%s»"
-#: gio/gdbusaddress.c:175
+#: gio/gdbusaddress.c:181
#, c-format
msgid "Meaningless key/value pair combination in address entry “%s”"
msgstr "Combinación de par clave/valor sen sentido na entrada do enderezo «%s»"
-#: gio/gdbusaddress.c:184
+#: gio/gdbusaddress.c:190
#, c-format
msgid ""
"Address “%s” is invalid (need exactly one of path, dir, tmpdir, or abstract "
@@ -422,29 +422,29 @@ msgstr ""
"O enderezo «%s» non é válido (necesítase exactamente unha ruta, directorio, "
"directorio temporal ou claves abstractas)"
-#: gio/gdbusaddress.c:249 gio/gdbusaddress.c:260 gio/gdbusaddress.c:275
-#: gio/gdbusaddress.c:336 gio/gdbusaddress.c:347
+#: gio/gdbusaddress.c:255 gio/gdbusaddress.c:266 gio/gdbusaddress.c:281
+#: gio/gdbusaddress.c:342 gio/gdbusaddress.c:353
#, c-format
msgid "Error in address “%s” — the “%s” attribute is malformed"
msgstr "Erro no enderezo «%s» — o atributo «%s» está mal formado"
-#: gio/gdbusaddress.c:417 gio/gdbusaddress.c:676
+#: gio/gdbusaddress.c:423 gio/gdbusaddress.c:682
#, c-format
msgid "Unknown or unsupported transport “%s” for address “%s”"
msgstr "Transporte «%s» descoñecido ou non compatíbel para o enderezo «%s»"
-#: gio/gdbusaddress.c:461
+#: gio/gdbusaddress.c:467
#, c-format
msgid "Address element “%s” does not contain a colon (:)"
msgstr "O elemento do enderezo «%s» non contén un carácter dous puntos (:)"
-#: gio/gdbusaddress.c:470
+#: gio/gdbusaddress.c:476
#, c-format
msgid "Transport name in address element “%s” must not be empty"
msgstr ""
"O nome de transporte do elemento de enderezo «%s» non pode estar baleiro"
-#: gio/gdbusaddress.c:491
+#: gio/gdbusaddress.c:497
#, c-format
msgid ""
"Key/Value pair %d, “%s”, in address element “%s” does not contain an equal "
@@ -453,7 +453,7 @@ msgstr ""
"O par clave/valor %d, «%s» no elemento do enderezo «%s» non contén un signo "
"de igual"
-#: gio/gdbusaddress.c:502
+#: gio/gdbusaddress.c:508
#, c-format
msgid ""
"Key/Value pair %d, “%s”, in address element “%s” must not have an empty key"
@@ -461,7 +461,7 @@ msgstr ""
"O par clave/valor %d, «%s» no elemento do enderezo «%s» non debe ter unha "
"chave baleira"
-#: gio/gdbusaddress.c:516
+#: gio/gdbusaddress.c:522
#, c-format
msgid ""
"Error unescaping key or value in Key/Value pair %d, “%s”, in address element "
@@ -470,7 +470,7 @@ msgstr ""
"Produciuse un erro ao desescapar a clave ou o valor no par clave/valor %d, "
"«%s», no elemento de enderezo «%s»"
-#: gio/gdbusaddress.c:584
+#: gio/gdbusaddress.c:590
#, c-format
msgid ""
"Error in address “%s” — the unix transport requires exactly one of the keys "
@@ -479,85 +479,85 @@ msgstr ""
"Erro no enderezo «%s» — o transporte unix require que se estabeleza "
"exactamente unha das claves «path» ou «abstract»"
-#: gio/gdbusaddress.c:619
+#: gio/gdbusaddress.c:625
#, c-format
msgid "Error in address “%s” — the host attribute is missing or malformed"
msgstr "Erro no enderezo «%s» — falta o atributo do equipo ou está mal formado"
-#: gio/gdbusaddress.c:633
+#: gio/gdbusaddress.c:639
#, c-format
msgid "Error in address “%s” — the port attribute is missing or malformed"
msgstr "Erro no enderezo «%s» — falta o atributo do porto ou está mal formado"
-#: gio/gdbusaddress.c:647
+#: gio/gdbusaddress.c:653
#, c-format
msgid "Error in address “%s” — the noncefile attribute is missing or malformed"
msgstr ""
"Erro no enderezo «%s» — falta o atributo do ficheiro de uso de unha vez ou "
"está mal formado"
-#: gio/gdbusaddress.c:668
+#: gio/gdbusaddress.c:674
msgid "Error auto-launching: "
msgstr "Produciuse un erro ao autoiniciar: "
-#: gio/gdbusaddress.c:721
+#: gio/gdbusaddress.c:727
#, c-format
msgid "Error opening nonce file “%s”: %s"
msgstr "Produciuse un erro ao abrir o ficheiro de uso de unha vez «%s»: %s"
-#: gio/gdbusaddress.c:740
+#: gio/gdbusaddress.c:746
#, c-format
msgid "Error reading from nonce file “%s”: %s"
msgstr "Produciuse un erro ao ler o ficheiro de uso de unha vez «%s»: %s"
-#: gio/gdbusaddress.c:749
+#: gio/gdbusaddress.c:755
#, c-format
msgid "Error reading from nonce file “%s”, expected 16 bytes, got %d"
msgstr ""
"Produciuse un erro ao ler o ficheiro de uso de unha vez «%s»:, esperábanse "
"16 bytes, obtivéronse %d"
-#: gio/gdbusaddress.c:767
+#: gio/gdbusaddress.c:773
#, c-format
msgid "Error writing contents of nonce file “%s” to stream:"
msgstr ""
"Produciuse un erro ao gravar os contidos do ficheiro de uso de unha vez «%s» "
"ao fluxo:"
-#: gio/gdbusaddress.c:982
+#: gio/gdbusaddress.c:988
msgid "The given address is empty"
msgstr "O enderezo fornecido está baleiro"
-#: gio/gdbusaddress.c:1095
+#: gio/gdbusaddress.c:1101
#, c-format
msgid "Cannot spawn a message bus when AT_SECURE is set"
msgstr ""
"Non é posíbel iniciar («spawn») unha bus de mensaxe cando AT_SECURE está "
"estabelecido"
-#: gio/gdbusaddress.c:1102
+#: gio/gdbusaddress.c:1108
msgid "Cannot spawn a message bus without a machine-id: "
msgstr ""
"Non é posíbel iniciar («spawn») unha mensaxe ao bus sen un ID de máquina: "
-#: gio/gdbusaddress.c:1109
+#: gio/gdbusaddress.c:1115
#, c-format
msgid "Cannot autolaunch D-Bus without X11 $DISPLAY"
msgstr "Non é posíbel autoiniciar D-Bus sen un $DISPLAY X11"
-#: gio/gdbusaddress.c:1151
+#: gio/gdbusaddress.c:1157
#, c-format
msgid "Error spawning command line “%s”: "
msgstr "Produciuse un erro ao iniciar («spawn») a orde «%s»: "
-#: gio/gdbusaddress.c:1220
+#: gio/gdbusaddress.c:1226
#, c-format
msgid "Cannot determine session bus address (not implemented for this OS)"
msgstr ""
"Non é posíbel determinar o enderezo do bus de sesión (non está implementado "
"para este SO)"
-#: gio/gdbusaddress.c:1374 gio/gdbusconnection.c:7316
+#: gio/gdbusaddress.c:1380 gio/gdbusconnection.c:7324
#, c-format
msgid ""
"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable "
@@ -566,7 +566,7 @@ msgstr ""
"Non é posíbel determinar o enderezo do bus desde a variábel de ambiente "
"DBUS_STARTER_BUS_TYPE - valor descoñecido «%s»"
-#: gio/gdbusaddress.c:1383 gio/gdbusconnection.c:7325
+#: gio/gdbusaddress.c:1389 gio/gdbusconnection.c:7333
msgid ""
"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment "
"variable is not set"
@@ -574,7 +574,7 @@ msgstr ""
"Non é posíbel determinar o enderezo do bus xa que a variábel de ambiente "
"DBUS_STARTER_BUS_TYPE non está estabelecida"
-#: gio/gdbusaddress.c:1393
+#: gio/gdbusaddress.c:1399
#, c-format
msgid "Unknown bus type %d"
msgstr "Tipo de bus %d descoñecido"
@@ -607,12 +607,12 @@ msgstr "Os IDs de usuario deben ser os mesmos para o par e o servidor"
msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer"
msgstr "Cancelando mediante GDBusAuthObserver::authorize-authenticated-peer"
-#: gio/gdbusauthmechanismsha1.c:303
+#: gio/gdbusauthmechanismsha1.c:307
#, c-format
msgid "Error when getting information for directory “%s”: %s"
msgstr "Produciuse un erro ao obter a información do directorio «%s»: %s"
-#: gio/gdbusauthmechanismsha1.c:318
+#: gio/gdbusauthmechanismsha1.c:322
#, c-format
msgid ""
"Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o"
@@ -620,32 +620,32 @@ msgstr ""
"Os permisos no directorio «%s» están malformados. Esperábase o modo 0700 e "
"obtívose 0%o"
-#: gio/gdbusauthmechanismsha1.c:351 gio/gdbusauthmechanismsha1.c:362
+#: gio/gdbusauthmechanismsha1.c:355 gio/gdbusauthmechanismsha1.c:366
#, c-format
msgid "Error creating directory “%s”: %s"
msgstr "Produciuse un erro ao crear o directorio %s: %s"
-#: gio/gdbusauthmechanismsha1.c:364 gio/gfile.c:1095 gio/gfile.c:1333
+#: gio/gdbusauthmechanismsha1.c:368 gio/gfile.c:1095 gio/gfile.c:1333
#: gio/gfile.c:1471 gio/gfile.c:1709 gio/gfile.c:1764 gio/gfile.c:1822
#: gio/gfile.c:1906 gio/gfile.c:1963 gio/gfile.c:2027 gio/gfile.c:2082
-#: gio/gfile.c:3787 gio/gfile.c:3927 gio/gfile.c:4339 gio/gfile.c:4809
-#: gio/gfile.c:5220 gio/gfile.c:5305 gio/gfile.c:5395 gio/gfile.c:5492
-#: gio/gfile.c:5579 gio/gfile.c:5680 gio/gfile.c:8809 gio/gfile.c:8899
-#: gio/gfile.c:8983 gio/win32/gwinhttpfile.c:453
+#: gio/gfile.c:3797 gio/gfile.c:3937 gio/gfile.c:4349 gio/gfile.c:4819
+#: gio/gfile.c:5230 gio/gfile.c:5315 gio/gfile.c:5405 gio/gfile.c:5502
+#: gio/gfile.c:5589 gio/gfile.c:5690 gio/gfile.c:8819 gio/gfile.c:8909
+#: gio/gfile.c:8993 gio/win32/gwinhttpfile.c:453
msgid "Operation not supported"
msgstr "Operación non permitida"
-#: gio/gdbusauthmechanismsha1.c:407
+#: gio/gdbusauthmechanismsha1.c:411
#, c-format
msgid "Error opening keyring “%s” for reading: "
msgstr "Produciuse un erro ao abrir o anel de chaves «%s» para a súa lectura: "
-#: gio/gdbusauthmechanismsha1.c:430 gio/gdbusauthmechanismsha1.c:771
+#: gio/gdbusauthmechanismsha1.c:434 gio/gdbusauthmechanismsha1.c:775
#, c-format
msgid "Line %d of the keyring at “%s” with content “%s” is malformed"
msgstr "A liña %d do anel de chaves en «%s» con contido «%s» está malformada"
-#: gio/gdbusauthmechanismsha1.c:444 gio/gdbusauthmechanismsha1.c:785
+#: gio/gdbusauthmechanismsha1.c:448 gio/gdbusauthmechanismsha1.c:789
#, c-format
msgid ""
"First token of line %d of the keyring at “%s” with content “%s” is malformed"
@@ -653,7 +653,7 @@ msgstr ""
"O primeiro token da liña %d no anel de chaves en «%s» co contido «%s» está "
"malformado"
-#: gio/gdbusauthmechanismsha1.c:458 gio/gdbusauthmechanismsha1.c:799
+#: gio/gdbusauthmechanismsha1.c:462 gio/gdbusauthmechanismsha1.c:803
#, c-format
msgid ""
"Second token of line %d of the keyring at “%s” with content “%s” is malformed"
@@ -661,56 +661,56 @@ msgstr ""
"O segundo token da liña %d no anel de chaves en «%s» co contido «%s» está "
"malformado"
-#: gio/gdbusauthmechanismsha1.c:482
+#: gio/gdbusauthmechanismsha1.c:486
#, c-format
msgid "Didn’t find cookie with id %d in the keyring at “%s”"
msgstr "Non foi posíbel atopar a cookie co id %d no anel de chave en «%s»"
-#: gio/gdbusauthmechanismsha1.c:539
+#: gio/gdbusauthmechanismsha1.c:543
#, c-format
msgid "Error creating lock file “%s”: %s"
msgstr "Produciuse un erro ao crear o ficheiro de bloqueo «%s»: %s"
-#: gio/gdbusauthmechanismsha1.c:612
+#: gio/gdbusauthmechanismsha1.c:616
#, c-format
msgid "Error deleting stale lock file “%s”: %s"
msgstr "Produciuse un erro ao eliminar o ficheiro de bloqueo antigo «%s»: %s"
-#: gio/gdbusauthmechanismsha1.c:651
+#: gio/gdbusauthmechanismsha1.c:655
#, c-format
msgid "Error closing (unlinked) lock file “%s”: %s"
msgstr "Produciuse un erro ao pechar o ficheiro de bloqueo «%s»: %s"
-#: gio/gdbusauthmechanismsha1.c:662
+#: gio/gdbusauthmechanismsha1.c:666
#, c-format
msgid "Error unlinking lock file “%s”: %s"
msgstr "Produciuse un erro ao abrir o ficheiro de bloqueo «%s»: %s"
-#: gio/gdbusauthmechanismsha1.c:738
+#: gio/gdbusauthmechanismsha1.c:742
#, c-format
msgid "Error opening keyring “%s” for writing: "
msgstr "Produciuse un erro ao abrir o anel de chaves «%s» para escribir: "
-#: gio/gdbusauthmechanismsha1.c:932
+#: gio/gdbusauthmechanismsha1.c:936
#, c-format
msgid "(Additionally, releasing the lock for “%s” also failed: %s) "
msgstr "(Ademais, a liberación do bloqueo para «%s» tamén fallou: %s) "
-#: gio/gdbusconnection.c:590 gio/gdbusconnection.c:2405
+#: gio/gdbusconnection.c:590 gio/gdbusconnection.c:2413
msgid "The connection is closed"
msgstr "A conexión está pechado"
-#: gio/gdbusconnection.c:1889
+#: gio/gdbusconnection.c:1897
msgid "Timeout was reached"
msgstr "Tempo de espera máximo alcanzado"
-#: gio/gdbusconnection.c:2528
+#: gio/gdbusconnection.c:2536
msgid ""
"Unsupported flags encountered when constructing a client-side connection"
msgstr ""
"Atopáronse opcións non compatíbeis ao construír a conexión da parte cliente"
-#: gio/gdbusconnection.c:4257 gio/gdbusconnection.c:4611
+#: gio/gdbusconnection.c:4265 gio/gdbusconnection.c:4619
#, c-format
msgid ""
"No such interface “org.freedesktop.DBus.Properties” on object at path %s"
@@ -718,80 +718,80 @@ msgstr ""
"Non existe a interface «org.freedesktop.DBus.Properties» no obxecto coa ruta "
"%s"
-#: gio/gdbusconnection.c:4402
+#: gio/gdbusconnection.c:4410
#, c-format
msgid "No such property “%s”"
msgstr "Non existe a propiedade «%s»"
-#: gio/gdbusconnection.c:4414
+#: gio/gdbusconnection.c:4422
#, c-format
msgid "Property “%s” is not readable"
msgstr "Non é posíbel escribir a propiedade «%s»"
-#: gio/gdbusconnection.c:4425
+#: gio/gdbusconnection.c:4433
#, c-format
msgid "Property “%s” is not writable"
msgstr "Non é posíbel escribir a propiedade «%s»"
-#: gio/gdbusconnection.c:4445
+#: gio/gdbusconnection.c:4453
#, c-format
msgid "Error setting property “%s”: Expected type “%s” but got “%s”"
msgstr ""
"Produciuse un erro ao estabelecer a propiedade «%s»: Esperábase o tipo «%s» "
"pero obtívose «%s»"
-#: gio/gdbusconnection.c:4550 gio/gdbusconnection.c:4765
-#: gio/gdbusconnection.c:6742
+#: gio/gdbusconnection.c:4558 gio/gdbusconnection.c:4773
+#: gio/gdbusconnection.c:6750
#, c-format
msgid "No such interface “%s”"
msgstr "Non existe a interface «%s»"
-#: gio/gdbusconnection.c:4981 gio/gdbusconnection.c:7256
+#: gio/gdbusconnection.c:4989 gio/gdbusconnection.c:7264
#, c-format
msgid "No such interface “%s” on object at path %s"
msgstr "Non existe a interface «%s» no obxecto coa ruta %s"
-#: gio/gdbusconnection.c:5082
+#: gio/gdbusconnection.c:5090
#, c-format
msgid "No such method “%s”"
msgstr "Non existe a clave «%s»"
-#: gio/gdbusconnection.c:5113
+#: gio/gdbusconnection.c:5121
#, c-format
msgid "Type of message, “%s”, does not match expected type “%s”"
msgstr "O tipo da mensaxe, «%s», non coincide co tipo «%s» esperado"
-#: gio/gdbusconnection.c:5316
+#: gio/gdbusconnection.c:5324
#, c-format
msgid "An object is already exported for the interface %s at %s"
msgstr "Xa hai un obxecto exportado para a interface %s en %s"
-#: gio/gdbusconnection.c:5543
+#: gio/gdbusconnection.c:5551
#, c-format
msgid "Unable to retrieve property %s.%s"
msgstr "Non é posíbel obter a propiedade %s.%s"
-#: gio/gdbusconnection.c:5599
+#: gio/gdbusconnection.c:5607
#, c-format
msgid "Unable to set property %s.%s"
msgstr "Non é posíbel estabelecer a propiedade %s.%s"
-#: gio/gdbusconnection.c:5778
+#: gio/gdbusconnection.c:5786
#, c-format
msgid "Method “%s” returned type “%s”, but expected “%s”"
msgstr "O método «%s» devolveu un tipo «%s» máis esperábase «%s»"
-#: gio/gdbusconnection.c:6854
+#: gio/gdbusconnection.c:6862
#, c-format
msgid "Method “%s” on interface “%s” with signature “%s” does not exist"
msgstr "O método «%s» na interface «%s» coa sinatura «%s» non existe"
-#: gio/gdbusconnection.c:6975
+#: gio/gdbusconnection.c:6983
#, c-format
msgid "A subtree is already exported for %s"
msgstr "Xa se exportou un subárbore para %s"
-#: gio/gdbusconnection.c:7264
+#: gio/gdbusconnection.c:7272
#, c-format
msgid "Object does not exist at path “%s”"
msgstr "O obxecto non existe na ruta «%s»"
@@ -1353,12 +1353,12 @@ msgstr "Erro: Demasiados argumentos.\n"
msgid "Error: %s is not a valid well-known bus name.\n"
msgstr "Erro: %s non é un nome de bus válido e coñecido.\n"
-#: gio/gdebugcontrollerdbus.c:360
+#: gio/gdebugcontrollerdbus.c:361
#, c-format
msgid "Not authorized to change debug settings"
msgstr "Non está autorizado para cambiar as preferencias de depuración"
-#: gio/gdesktopappinfo.c:2242 gio/gdesktopappinfo.c:5223
+#: gio/gdesktopappinfo.c:2242 gio/gdesktopappinfo.c:5226
msgid "Unnamed"
msgstr "Sen nome"
@@ -1375,29 +1375,29 @@ msgstr "Non é posíbel atopar o terminal requirido pola aplicación"
msgid "Program ‘%s’ not found in $PATH"
msgstr "Non se puido atopar o programa «%s» no $PATH"
-#: gio/gdesktopappinfo.c:3735
+#: gio/gdesktopappinfo.c:3738
#, c-format
msgid "Can’t create user application configuration folder %s: %s"
msgstr ""
"Non é posíbel crear o directorio de configuración da aplicación de usuario "
"%s: %s"
-#: gio/gdesktopappinfo.c:3739
+#: gio/gdesktopappinfo.c:3742
#, c-format
msgid "Can’t create user MIME configuration folder %s: %s"
msgstr ""
"Non é posíbel crear o directorio de configuración MIME %s do usuario: %s"
-#: gio/gdesktopappinfo.c:3981 gio/gdesktopappinfo.c:4005
+#: gio/gdesktopappinfo.c:3984 gio/gdesktopappinfo.c:4008
msgid "Application information lacks an identifier"
msgstr "A información da aplicación carece dun identificador"
-#: gio/gdesktopappinfo.c:4241
+#: gio/gdesktopappinfo.c:4244
#, c-format
msgid "Can’t create user desktop file %s"
msgstr "Non é posíbel crear o ficheiro de escritorio %s do usuario"
-#: gio/gdesktopappinfo.c:4377
+#: gio/gdesktopappinfo.c:4380
#, c-format
msgid "Custom definition for %s"
msgstr "Definición personalizada para %s"
@@ -1473,7 +1473,7 @@ msgstr "Esperábase un GEmblem para o GEmblemedIcon"
msgid "Containing mount does not exist"
msgstr "O punto de montaxe contido non existe"
-#: gio/gfile.c:2641 gio/glocalfile.c:2511
+#: gio/gfile.c:2641 gio/glocalfile.c:2515
msgid "Can’t copy over directory"
msgstr "Non é posíbel copiar sobre o directorio"
@@ -1498,50 +1498,50 @@ msgstr "Non se admite a unión"
msgid "Error splicing file: %s"
msgstr "Produciuse un erro ao empalmar o ficheiro: %s"
-#: gio/gfile.c:3185
+#: gio/gfile.c:3195
msgid "Copy (reflink/clone) between mounts is not supported"
msgstr "Copiar (reflink/clonar) entre montaxes non é compatíbel"
-#: gio/gfile.c:3189
+#: gio/gfile.c:3199
msgid "Copy (reflink/clone) is not supported or invalid"
msgstr "Copiar (reflink/clone) non é compatíbel ou non é válido"
-#: gio/gfile.c:3194
+#: gio/gfile.c:3204
msgid "Copy (reflink/clone) is not supported or didn’t work"
msgstr "Copiar (reflink/clone) non é compatíbel ou non funciona"
-#: gio/gfile.c:3259
+#: gio/gfile.c:3269
msgid "Can’t copy special file"
msgstr "Non é posíbel copiar o ficheiro especial"
-#: gio/gfile.c:4153
+#: gio/gfile.c:4163
msgid "Invalid symlink value given"
msgstr "O valor da ligazón simbólica dada non é válido"
-#: gio/gfile.c:4163 glib/gfileutils.c:2392
+#: gio/gfile.c:4173 glib/gfileutils.c:2392
msgid "Symbolic links not supported"
msgstr "As ligazóns simbólicas non se admiten"
-#: gio/gfile.c:4450
+#: gio/gfile.c:4460
msgid "Trash not supported"
msgstr "O Lixo non é compatíbel"
-#: gio/gfile.c:4562
+#: gio/gfile.c:4572
#, c-format
msgid "File names cannot contain “%c”"
msgstr "Os nomes de ficheiro non poden conter «%c»"
-#: gio/gfile.c:6993 gio/gfile.c:7119
+#: gio/gfile.c:7003 gio/gfile.c:7129
#, c-format
msgid "Failed to create a temporary directory for template “%s”: %s"
msgstr ""
"Produciuse un erro ao crear o directorio temporal para o modelo «%s»: %s"
-#: gio/gfile.c:7408 gio/gvolume.c:366
+#: gio/gfile.c:7418 gio/gvolume.c:366
msgid "volume doesn’t implement mount"
msgstr "o volume non implementa o montado"
-#: gio/gfile.c:7522 gio/gfile.c:7599
+#: gio/gfile.c:7532 gio/gfile.c:7609
msgid "No application is registered as handling this file"
msgstr "Non hai ningunha aplicación rexistrado para manexar este ficheiro"
@@ -1550,11 +1550,11 @@ msgid "Enumerator is closed"
msgstr "O enumerador está pechado"
#: gio/gfileenumerator.c:221 gio/gfileenumerator.c:280
-#: gio/gfileenumerator.c:379 gio/gfileenumerator.c:478
+#: gio/gfileenumerator.c:424 gio/gfileenumerator.c:523
msgid "File enumerator has outstanding operation"
msgstr "O enumerador do ficheiro ten unha operación excepcional"
-#: gio/gfileenumerator.c:370 gio/gfileenumerator.c:469
+#: gio/gfileenumerator.c:415 gio/gfileenumerator.c:514
msgid "File enumerator is already closed"
msgstr "O enumerador do ficheiro xa está pechado"
@@ -1797,12 +1797,12 @@ msgid "Error writing to stdout"
msgstr "Produciuse un erro ao escribir ao stdout"
#. Translators: commandline placeholder
-#: gio/gio-tool-cat.c:135 gio/gio-tool-info.c:379 gio/gio-tool-list.c:173
+#: gio/gio-tool-cat.c:135 gio/gio-tool-info.c:382 gio/gio-tool-list.c:176
#: gio/gio-tool-mkdir.c:50 gio/gio-tool-monitor.c:39 gio/gio-tool-monitor.c:41
#: gio/gio-tool-monitor.c:43 gio/gio-tool-monitor.c:45
#: gio/gio-tool-monitor.c:206 gio/gio-tool-mount.c:1210 gio/gio-tool-open.c:72
#: gio/gio-tool-remove.c:50 gio/gio-tool-rename.c:47 gio/gio-tool-set.c:95
-#: gio/gio-tool-trash.c:222 gio/gio-tool-tree.c:241
+#: gio/gio-tool-trash.c:222 gio/gio-tool-tree.c:246
msgid "LOCATION"
msgstr "LOCALIZACIÓN"
@@ -1821,7 +1821,7 @@ msgstr ""
"GIO no lugar de ficheiros locais: por exemplo, pode usar algo así como \n"
"smb:////server/resource/file.txt como localización."
-#: gio/gio-tool-cat.c:164 gio/gio-tool-info.c:410 gio/gio-tool-mkdir.c:78
+#: gio/gio-tool-cat.c:164 gio/gio-tool-info.c:413 gio/gio-tool-mkdir.c:78
#: gio/gio-tool-monitor.c:231 gio/gio-tool-mount.c:1261 gio/gio-tool-open.c:98
#: gio/gio-tool-remove.c:74 gio/gio-tool-trash.c:303
msgid "No locations given"
@@ -1918,57 +1918,57 @@ msgstr "Non seguir as ligazóns simbólicas"
msgid "attributes:\n"
msgstr "atributos:\n"
-#: gio/gio-tool-info.c:165 gio/gio-tool-info.c:174
+#: gio/gio-tool-info.c:166 gio/gio-tool-info.c:176
#, c-format
msgid "display name: %s\n"
msgstr "nome en pantalla: %s\n"
-#: gio/gio-tool-info.c:182
+#: gio/gio-tool-info.c:184
#, c-format
msgid "name: %s\n"
msgstr "nome: %s\n"
-#: gio/gio-tool-info.c:189
+#: gio/gio-tool-info.c:191
#, c-format
msgid "type: %s\n"
msgstr "tipo: %s\n"
-#: gio/gio-tool-info.c:195
+#: gio/gio-tool-info.c:197
msgid "size: "
msgstr "tamaño: "
-#: gio/gio-tool-info.c:200
+#: gio/gio-tool-info.c:203
msgid "hidden\n"
msgstr "oculto\n"
-#: gio/gio-tool-info.c:203
+#: gio/gio-tool-info.c:206
#, c-format
msgid "uri: %s\n"
msgstr "uri: %s\n"
-#: gio/gio-tool-info.c:210
+#: gio/gio-tool-info.c:213
#, c-format
msgid "local path: %s\n"
msgstr "ruta local: %s\n"
-#: gio/gio-tool-info.c:244
+#: gio/gio-tool-info.c:247
#, c-format
msgid "unix mount: %s%s %s %s %s\n"
msgstr "montaxe unix: %s%s %s %s %s\n"
-#: gio/gio-tool-info.c:325
+#: gio/gio-tool-info.c:328
msgid "Settable attributes:\n"
msgstr "Atributos estabelecíbeis:\n"
-#: gio/gio-tool-info.c:349
+#: gio/gio-tool-info.c:352
msgid "Writable attribute namespaces:\n"
msgstr "Espazos de nomes de atributo escribíbeis:\n"
-#: gio/gio-tool-info.c:384
+#: gio/gio-tool-info.c:387
msgid "Show information about locations."
msgstr "Mostrar información sobre as localizacións."
-#: gio/gio-tool-info.c:386
+#: gio/gio-tool-info.c:389
msgid ""
"gio info is similar to the traditional ls utility, but using GIO\n"
"locations instead of local files: for example, you can use something\n"
@@ -2035,11 +2035,11 @@ msgstr "Imprimir nomes que mostrar"
msgid "Print full URIs"
msgstr "Mostrar os URIs completos"
-#: gio/gio-tool-list.c:178
+#: gio/gio-tool-list.c:181
msgid "List the contents of the locations."
msgstr "Lista os contidos das localizacións."
-#: gio/gio-tool-list.c:180
+#: gio/gio-tool-list.c:183
msgid ""
"gio list is similar to the traditional ls utility, but using GIO\n"
"locations instead of local files: for example, you can use something\n"
@@ -2454,7 +2454,7 @@ msgstr "A localización fornecida non comeza por trash:///"
msgid "Follow symbolic links, mounts and shortcuts"
msgstr "Seguir as ligazóns simbólicas, montaxes e atallos"
-#: gio/gio-tool-tree.c:246
+#: gio/gio-tool-tree.c:251
msgid "List contents of directories in a tree-like format."
msgstr "Lista os contidos dos directorios nun formato árbore."
@@ -3087,12 +3087,12 @@ msgstr ""
"Non se atopou ningún ficheiro de esquemas: eliminouse o ficheiro de saída "
"existente."
-#: gio/glocalfile.c:563 gio/win32/gwinhttpfile.c:436
+#: gio/glocalfile.c:567 gio/win32/gwinhttpfile.c:436
#, c-format
msgid "Invalid filename %s"
msgstr "O nome do ficheiro non é válido %s"
-#: gio/glocalfile.c:1005
+#: gio/glocalfile.c:1009
#, c-format
msgid "Error getting filesystem info for %s: %s"
msgstr ""
@@ -3102,264 +3102,264 @@ msgstr ""
#. * the enclosing (user visible) mount of a file, but none
#. * exists.
#.
-#: gio/glocalfile.c:1141
+#: gio/glocalfile.c:1145
#, c-format
msgid "Containing mount for file %s not found"
msgstr "Non se atopa o punto de montaxe que contén o ficheiro %s"
-#: gio/glocalfile.c:1164
+#: gio/glocalfile.c:1168
msgid "Can’t rename root directory"
msgstr "Non é posíbel renomear o directorio raíz"
-#: gio/glocalfile.c:1182 gio/glocalfile.c:1205
+#: gio/glocalfile.c:1186 gio/glocalfile.c:1209
#, c-format
msgid "Error renaming file %s: %s"
msgstr "Produciuse un erro ao renomear o ficheiro %s: %s"
-#: gio/glocalfile.c:1189
+#: gio/glocalfile.c:1193
msgid "Can’t rename file, filename already exists"
msgstr "Non é posíbel renomear o ficheiro, o ficheiro xa existe"
-#: gio/glocalfile.c:1202 gio/glocalfile.c:2405 gio/glocalfile.c:2433
-#: gio/glocalfile.c:2572 gio/glocalfileoutputstream.c:658
+#: gio/glocalfile.c:1206 gio/glocalfile.c:2409 gio/glocalfile.c:2437
+#: gio/glocalfile.c:2576 gio/glocalfileoutputstream.c:658
msgid "Invalid filename"
msgstr "O nome do ficheiro non é válido"
-#: gio/glocalfile.c:1370 gio/glocalfile.c:1381
+#: gio/glocalfile.c:1374 gio/glocalfile.c:1385
#, c-format
msgid "Error opening file %s: %s"
msgstr "Produciuse un erro ao abrir o ficheiro %s: %s"
-#: gio/glocalfile.c:1506
+#: gio/glocalfile.c:1510
#, c-format
msgid "Error removing file %s: %s"
msgstr "Produciuse un erro ao eliminar o ficheiro %s: %s"
-#: gio/glocalfile.c:2000 gio/glocalfile.c:2011 gio/glocalfile.c:2038
+#: gio/glocalfile.c:2004 gio/glocalfile.c:2015 gio/glocalfile.c:2042
#, c-format
msgid "Error trashing file %s: %s"
msgstr "Produciuse un erro ao mover ao lixo o ficheiro %s: %s"
-#: gio/glocalfile.c:2058
+#: gio/glocalfile.c:2062
#, c-format
msgid "Unable to create trash directory %s: %s"
msgstr "Non é posíbel crear o directorio do lixo %s: %s"
-#: gio/glocalfile.c:2079
+#: gio/glocalfile.c:2083
#, c-format
msgid "Unable to find toplevel directory to trash %s"
msgstr ""
"Non é posíbel atopar o directorio de nivel superior para mover ao lixo %s"
-#: gio/glocalfile.c:2087
+#: gio/glocalfile.c:2091
#, c-format
msgid "Trashing on system internal mounts is not supported"
msgstr "Enviar ao lixo en montaxes internos do sistema non se admite"
-#: gio/glocalfile.c:2173 gio/glocalfile.c:2201
+#: gio/glocalfile.c:2177 gio/glocalfile.c:2205
#, c-format
msgid "Unable to find or create trash directory %s to trash %s"
msgstr "Non é posíbel atopar ou crear o directorio do lixo para %s ao lixo %s"
-#: gio/glocalfile.c:2245
+#: gio/glocalfile.c:2249
#, c-format
msgid "Unable to create trashing info file for %s: %s"
msgstr "Non é posíbel crear a información de lixo para o ficheiro %s: %s"
-#: gio/glocalfile.c:2316
+#: gio/glocalfile.c:2320
#, c-format
msgid "Unable to trash file %s across filesystem boundaries"
msgstr ""
"Non é posíbel mover ao lixo o ficheiro %s a través dos límites do sistema de "
"ficheiros"
-#: gio/glocalfile.c:2320 gio/glocalfile.c:2376
+#: gio/glocalfile.c:2324 gio/glocalfile.c:2380
#, c-format
msgid "Unable to trash file %s: %s"
msgstr "Non é posíbel mover ao lixo o ficheiro %s: %s"
-#: gio/glocalfile.c:2382
+#: gio/glocalfile.c:2386
#, c-format
msgid "Unable to trash file %s"
msgstr "Non é posíbel mover ao lixo o ficheiro %s"
-#: gio/glocalfile.c:2408
+#: gio/glocalfile.c:2412
#, c-format
msgid "Error creating directory %s: %s"
msgstr "Produciuse un erro ao crear o directorio %s: %s"
-#: gio/glocalfile.c:2437
+#: gio/glocalfile.c:2441
#, c-format
msgid "Filesystem does not support symbolic links"
msgstr "O sistema de ficheiros non é compatíbel coas ligazóns simbólicas"
-#: gio/glocalfile.c:2440
+#: gio/glocalfile.c:2444
#, c-format
msgid "Error making symbolic link %s: %s"
msgstr "Produciuse un erro ao crear a ligazón simbólica %s: %s"
-#: gio/glocalfile.c:2483 gio/glocalfile.c:2518 gio/glocalfile.c:2575
+#: gio/glocalfile.c:2487 gio/glocalfile.c:2522 gio/glocalfile.c:2579
#, c-format
msgid "Error moving file %s: %s"
msgstr "Produciuse un erro ao mover o ficheiro %s: %s"
-#: gio/glocalfile.c:2506
+#: gio/glocalfile.c:2510
msgid "Can’t move directory over directory"
msgstr "Non é posíbel mover o directorio sobre un directorio"
-#: gio/glocalfile.c:2532 gio/glocalfileoutputstream.c:1110
+#: gio/glocalfile.c:2536 gio/glocalfileoutputstream.c:1110
#: gio/glocalfileoutputstream.c:1124 gio/glocalfileoutputstream.c:1139
#: gio/glocalfileoutputstream.c:1156 gio/glocalfileoutputstream.c:1170
msgid "Backup file creation failed"
msgstr "Fallou a creación do ficheiro de seguranza"
-#: gio/glocalfile.c:2551
+#: gio/glocalfile.c:2555
#, c-format
msgid "Error removing target file: %s"
msgstr "Produciuse un erro ao retirar o ficheiro obxectivo: %s"
-#: gio/glocalfile.c:2565
+#: gio/glocalfile.c:2569
msgid "Move between mounts not supported"
msgstr "Non se permite mover entre puntos de montaxe"
-#: gio/glocalfile.c:2741
+#: gio/glocalfile.c:2745
#, c-format
msgid "Could not determine the disk usage of %s: %s"
msgstr "Non foi posíbel determinar o uso de disco de %s: %s"
-#: gio/glocalfileinfo.c:775
+#: gio/glocalfileinfo.c:779
msgid "Attribute value must be non-NULL"
msgstr "O valor do atributo debe ser non nulo"
-#: gio/glocalfileinfo.c:782
+#: gio/glocalfileinfo.c:786
msgid "Invalid attribute type (string or invalid expected)"
msgstr "Tipo de atributo non válido (agardábase unha cadea ou non válido)"
-#: gio/glocalfileinfo.c:789
+#: gio/glocalfileinfo.c:793
msgid "Invalid extended attribute name"
msgstr "Nome estendido do atributo non válido"
-#: gio/glocalfileinfo.c:840
+#: gio/glocalfileinfo.c:844
#, c-format
msgid "Error setting extended attribute “%s”: %s"
msgstr "Produciuse un erro ao estabelecer o atributo estendido «%s»: %s"
-#: gio/glocalfileinfo.c:1819 gio/win32/gwinhttpfile.c:191
+#: gio/glocalfileinfo.c:1823 gio/win32/gwinhttpfile.c:191
msgid " (invalid encoding)"
msgstr " (codificación non válida)"
-#: gio/glocalfileinfo.c:1978 gio/glocalfileoutputstream.c:945
+#: gio/glocalfileinfo.c:1982 gio/glocalfileoutputstream.c:945
#: gio/glocalfileoutputstream.c:997
#, c-format
msgid "Error when getting information for file “%s”: %s"
msgstr "Produciuse un erro ao obter a información do ficheiro «%s»: %s"
-#: gio/glocalfileinfo.c:2281
+#: gio/glocalfileinfo.c:2288
#, c-format
msgid "Error when getting information for file descriptor: %s"
msgstr "Produciuse un erro ao obter información do descritor do ficheiro: %s"
-#: gio/glocalfileinfo.c:2326
+#: gio/glocalfileinfo.c:2333
msgid "Invalid attribute type (uint32 expected)"
msgstr "O tipo de atributo non é válido (esperábase uint32)"
-#: gio/glocalfileinfo.c:2344
+#: gio/glocalfileinfo.c:2351
msgid "Invalid attribute type (uint64 expected)"
msgstr "O tipo de atributo non é válido (esperábase uint64)"
-#: gio/glocalfileinfo.c:2363 gio/glocalfileinfo.c:2382
+#: gio/glocalfileinfo.c:2370 gio/glocalfileinfo.c:2389
msgid "Invalid attribute type (byte string expected)"
msgstr "O tipo de atributo non é válido (esperábase unha cadea de bytes)"
-#: gio/glocalfileinfo.c:2429
+#: gio/glocalfileinfo.c:2436
msgid "Cannot set permissions on symlinks"
msgstr "Non foi posíbel estabelecer os permisos nas ligazóns simbólicas"
-#: gio/glocalfileinfo.c:2445
+#: gio/glocalfileinfo.c:2452
#, c-format
msgid "Error setting permissions: %s"
msgstr "Produciuse un erro ao estabelecer os permisos: %s"
-#: gio/glocalfileinfo.c:2496
+#: gio/glocalfileinfo.c:2503
#, c-format
msgid "Error setting owner: %s"
msgstr "Produciuse un erro ao estabelecer o propietario: %s"
-#: gio/glocalfileinfo.c:2519
+#: gio/glocalfileinfo.c:2526
msgid "symlink must be non-NULL"
msgstr "a ligazón simbólica debe ser non nula"
-#: gio/glocalfileinfo.c:2529 gio/glocalfileinfo.c:2548
-#: gio/glocalfileinfo.c:2559
+#: gio/glocalfileinfo.c:2536 gio/glocalfileinfo.c:2555
+#: gio/glocalfileinfo.c:2566
#, c-format
msgid "Error setting symlink: %s"
msgstr "Produciuse un erro ao estabelecer a ligazón simbólica: %s"
-#: gio/glocalfileinfo.c:2538
+#: gio/glocalfileinfo.c:2545
msgid "Error setting symlink: file is not a symlink"
msgstr ""
"Produciuse un erro ao estabelecer a ligazón simbólica: o ficheiro non é unha "
"ligazón"
-#: gio/glocalfileinfo.c:2630
+#: gio/glocalfileinfo.c:2637
#, c-format
msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative"
msgstr ""
"Os nanosegundos %d adicionais en marcas de tempo UNIX %lld son negativas"
-#: gio/glocalfileinfo.c:2639
+#: gio/glocalfileinfo.c:2646
#, c-format
msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second"
msgstr ""
"Os nanosegundos %d adicionais en marcas de tempo UNIX %lld alcanzan 1 segundo"
-#: gio/glocalfileinfo.c:2649
+#: gio/glocalfileinfo.c:2656
#, c-format
msgid "UNIX timestamp %lld does not fit into 64 bits"
msgstr "A marca de tempo UNIX %lld non colle nos 64 bits"
-#: gio/glocalfileinfo.c:2660
+#: gio/glocalfileinfo.c:2667
#, c-format
msgid "UNIX timestamp %lld is outside of the range supported by Windows"
msgstr "A marca de tempo %lld está fóra do rango admitido por Windows"
-#: gio/glocalfileinfo.c:2792
+#: gio/glocalfileinfo.c:2799
#, c-format
msgid "File name “%s” cannot be converted to UTF-16"
msgstr "Non é posíbel converter o nome de ficheiro «%s» a UTF-16"
-#: gio/glocalfileinfo.c:2811
+#: gio/glocalfileinfo.c:2818
#, c-format
msgid "File “%s” cannot be opened: Windows Error %lu"
msgstr "Non é posíbel abrir o ficheiro «%s»: Erro de Windows %lu"
-#: gio/glocalfileinfo.c:2824
+#: gio/glocalfileinfo.c:2831
#, c-format
msgid "Error setting modification or access time for file “%s”: %lu"
msgstr ""
"Produciuse un erro ao estabelecer a data de modificación ou acceso para o "
"ficheiro «%s»: %lu"
-#: gio/glocalfileinfo.c:2981
+#: gio/glocalfileinfo.c:2988
#, c-format
msgid "Error setting modification or access time: %s"
msgstr ""
"Produciuse un erro ao modificar a configuración ou o tempo de acceso: %s"
-#: gio/glocalfileinfo.c:3004
+#: gio/glocalfileinfo.c:3011
msgid "SELinux context must be non-NULL"
msgstr "O contexto SELinux debe ser non-NULL"
-#: gio/glocalfileinfo.c:3011
+#: gio/glocalfileinfo.c:3018
msgid "SELinux is not enabled on this system"
msgstr "SELinux non está activado neste sistema"
-#: gio/glocalfileinfo.c:3021
+#: gio/glocalfileinfo.c:3028
#, c-format
msgid "Error setting SELinux context: %s"
msgstr "Produciuse un erro ao estabelecer o contexto SELinux: %s"
-#: gio/glocalfileinfo.c:3118
+#: gio/glocalfileinfo.c:3125
#, c-format
msgid "Setting attribute %s not supported"
msgstr "Non se permite estabelecer o atributo %s"
@@ -3597,8 +3597,8 @@ msgstr "Dominio non válido"
#: gio/gresource.c:683 gio/gresource.c:945 gio/gresource.c:985
#: gio/gresource.c:1109 gio/gresource.c:1181 gio/gresource.c:1255
-#: gio/gresource.c:1336 gio/gresourcefile.c:478 gio/gresourcefile.c:601
-#: gio/gresourcefile.c:752
+#: gio/gresource.c:1336 gio/gresourcefile.c:478 gio/gresourcefile.c:602
+#: gio/gresourcefile.c:753
#, c-format
msgid "The resource at “%s” does not exist"
msgstr "Non existe o recurso en «%s»"
@@ -3608,16 +3608,16 @@ msgstr "Non existe o recurso en «%s»"
msgid "The resource at “%s” failed to decompress"
msgstr "Produciuse un erro ao descomprimir o recurso en «%s»"
-#: gio/gresourcefile.c:658
+#: gio/gresourcefile.c:659
msgid "Resource files cannot be renamed"
msgstr "Os ficheiros de recurso non se poden renomear"
-#: gio/gresourcefile.c:748
+#: gio/gresourcefile.c:749
#, c-format
msgid "The resource at “%s” is not a directory"
msgstr "O recurso en «%s» non é un cartafol"
-#: gio/gresourcefile.c:956
+#: gio/gresourcefile.c:957
msgid "Input stream doesn’t implement seek"
msgstr "O fluxo de entrada non implementa seek"
@@ -3985,7 +3985,7 @@ msgstr "O socket non é válido, a inicialización fallou debido a: %s"
msgid "Socket is already closed"
msgstr "O fluxo de orixe xa está pechado"
-#: gio/gsocket.c:449 gio/gsocket.c:3201 gio/gsocket.c:4434 gio/gsocket.c:4492
+#: gio/gsocket.c:449 gio/gsocket.c:3225 gio/gsocket.c:4458 gio/gsocket.c:4516
msgid "Socket I/O timed out"
msgstr "Tempo de espera do Socket de E/S superado"
@@ -4083,74 +4083,74 @@ msgstr "Non se admite o multicast IPv4 específico da fonte"
msgid "No support for IPv6 source-specific multicast"
msgstr "Non se admite o multicast IPv6 específico da fonte"
-#: gio/gsocket.c:2900
+#: gio/gsocket.c:2924
#, c-format
msgid "Error accepting connection: %s"
msgstr "Produciuse un erro ao aceptar a conexión: %s"
-#: gio/gsocket.c:3026
+#: gio/gsocket.c:3050
msgid "Connection in progress"
msgstr "Conexión en marcha"
-#: gio/gsocket.c:3077
+#: gio/gsocket.c:3101
msgid "Unable to get pending error: "
msgstr "Non é posíbel obter o erro pendente: "
-#: gio/gsocket.c:3266
+#: gio/gsocket.c:3290
#, c-format
msgid "Error receiving data: %s"
msgstr "Produciuse un erro ao recibir datos: %s"
-#: gio/gsocket.c:3463
+#: gio/gsocket.c:3487
#, c-format
msgid "Error sending data: %s"
msgstr "Produciuse un erro ao enviar datos: %s"
-#: gio/gsocket.c:3650
+#: gio/gsocket.c:3674
#, c-format
msgid "Unable to shutdown socket: %s"
msgstr "Non é posíbel desconectar o socket: %s"
-#: gio/gsocket.c:3731
+#: gio/gsocket.c:3755
#, c-format
msgid "Error closing socket: %s"
msgstr "Produciuse un erro ao pechar o socket: %s"
-#: gio/gsocket.c:4427
+#: gio/gsocket.c:4451
#, c-format
msgid "Waiting for socket condition: %s"
msgstr "Agardando pola situación do socket: %s"
-#: gio/gsocket.c:4817 gio/gsocket.c:4833 gio/gsocket.c:4846
+#: gio/gsocket.c:4841 gio/gsocket.c:4857 gio/gsocket.c:4870
#, c-format
msgid "Unable to send message: %s"
msgstr "Non foi posíbel enviar a mensaxe: %s"
-#: gio/gsocket.c:4818 gio/gsocket.c:4834 gio/gsocket.c:4847
+#: gio/gsocket.c:4842 gio/gsocket.c:4858 gio/gsocket.c:4871
msgid "Message vectors too large"
msgstr "Os vectores de mensaxes son moi largos"
-#: gio/gsocket.c:4863 gio/gsocket.c:4865 gio/gsocket.c:5012 gio/gsocket.c:5097
-#: gio/gsocket.c:5275 gio/gsocket.c:5315 gio/gsocket.c:5317
+#: gio/gsocket.c:4887 gio/gsocket.c:4889 gio/gsocket.c:5036 gio/gsocket.c:5121
+#: gio/gsocket.c:5299 gio/gsocket.c:5339 gio/gsocket.c:5341
#, c-format
msgid "Error sending message: %s"
msgstr "Produciuse un erro ao enviar a mensaxe: %s"
-#: gio/gsocket.c:5039
+#: gio/gsocket.c:5063
msgid "GSocketControlMessage not supported on Windows"
msgstr "O GSocketControlMessage non está permitido en Windows"
-#: gio/gsocket.c:5512 gio/gsocket.c:5588 gio/gsocket.c:5814
+#: gio/gsocket.c:5536 gio/gsocket.c:5612 gio/gsocket.c:5838
#, c-format
msgid "Error receiving message: %s"
msgstr "Produciuse un erro ao recibir a mensaxe: %s"
-#: gio/gsocket.c:6099 gio/gsocket.c:6110 gio/gsocket.c:6173
+#: gio/gsocket.c:6123 gio/gsocket.c:6134 gio/gsocket.c:6197
#, c-format
msgid "Unable to read socket credentials: %s"
msgstr "Non é posíbel ler as credenciais do socket: %s"
-#: gio/gsocket.c:6182
+#: gio/gsocket.c:6206
msgid "g_socket_get_credentials not implemented for this OS"
msgstr ""
"g_socket_get_credentials non está implementado para este sistema operativo"
@@ -4277,14 +4277,14 @@ msgstr "O proxy SOCKSv5 non é compatíbel co tipo de enderezo fornecido."
msgid "Unknown SOCKSv5 proxy error."
msgstr "Erro no proxy SOCKSv5 descoñecido."
-#: gio/gtestdbus.c:614 glib/gspawn-win32.c:354
+#: gio/gtestdbus.c:615 glib/gspawn-win32.c:354
#, c-format
msgid "Failed to create pipe for communicating with child process (%s)"
msgstr ""
"Produciuse un erro ao crear a canalización para comunicarse co proceso fillo "
"(%s)"
-#: gio/gtestdbus.c:621
+#: gio/gtestdbus.c:622
#, c-format
msgid "Pipes are not supported in this platform"
msgstr "As tuberías non están soportadas nesta plataforma"
@@ -5197,16 +5197,16 @@ msgstr "O canal termina nun carácter parcial"
msgid "Can’t do a raw read in g_io_channel_read_to_end"
msgstr "Non é posíbel facer unha lectura en bruto en g_io_channel_read_to_end"
-#: glib/gkeyfile.c:796
+#: glib/gkeyfile.c:800
msgid "Valid key file could not be found in search dirs"
msgstr ""
"Non é posíbel atopar un ficheiro de clave correcto nos directorios de busca"
-#: glib/gkeyfile.c:833
+#: glib/gkeyfile.c:837
msgid "Not a regular file"
msgstr "Non é un ficheiro normal"
-#: glib/gkeyfile.c:1291
+#: glib/gkeyfile.c:1295
#, c-format
msgid ""
"Key file contains line “%s” which is not a key-value pair, group, or comment"
@@ -5214,43 +5214,43 @@ msgstr ""
"O ficheiro clave contén a liña «%s» que non é un par valor-clave, grupo ou "
"comentario"
-#: glib/gkeyfile.c:1348
+#: glib/gkeyfile.c:1352
#, c-format
msgid "Invalid group name: %s"
msgstr "Nome de grupo non válido: %s"
-#: glib/gkeyfile.c:1372
+#: glib/gkeyfile.c:1376
msgid "Key file does not start with a group"
msgstr "O ficheiro clave non comeza cun grupo"
-#: glib/gkeyfile.c:1396
+#: glib/gkeyfile.c:1400
#, c-format
msgid "Invalid key name: %.*s"
msgstr "Nome de chave non válido: %.*s"
-#: glib/gkeyfile.c:1424
+#: glib/gkeyfile.c:1428
#, c-format
msgid "Key file contains unsupported encoding “%s”"
msgstr "O ficheiro clave contén unha codificación non permitida «%s»"
-#: glib/gkeyfile.c:1679 glib/gkeyfile.c:1852 glib/gkeyfile.c:3299
-#: glib/gkeyfile.c:3363 glib/gkeyfile.c:3493 glib/gkeyfile.c:3622
-#: glib/gkeyfile.c:3768 glib/gkeyfile.c:4003 glib/gkeyfile.c:4070
+#: glib/gkeyfile.c:1683 glib/gkeyfile.c:1856 glib/gkeyfile.c:3303
+#: glib/gkeyfile.c:3367 glib/gkeyfile.c:3497 glib/gkeyfile.c:3626
+#: glib/gkeyfile.c:3772 glib/gkeyfile.c:4007 glib/gkeyfile.c:4074
#, c-format
msgid "Key file does not have group “%s”"
msgstr "O ficheiro clave non ten un grupo «%s»"
-#: glib/gkeyfile.c:1807
+#: glib/gkeyfile.c:1811
#, c-format
msgid "Key file does not have key “%s” in group “%s”"
msgstr "O ficheiro clave non ten a clave «%s» no grupo «%s»"
-#: glib/gkeyfile.c:1969 glib/gkeyfile.c:2085
+#: glib/gkeyfile.c:1973 glib/gkeyfile.c:2089
#, c-format
msgid "Key file contains key “%s” with value “%s” which is not UTF-8"
msgstr "O ficheiro clave contén a clave «%s» co valor «%s» que non é UTF-8"
-#: glib/gkeyfile.c:1989 glib/gkeyfile.c:2105 glib/gkeyfile.c:2544
+#: glib/gkeyfile.c:1993 glib/gkeyfile.c:2109 glib/gkeyfile.c:2548
#, c-format
msgid ""
"Key file contains key “%s” which has a value that cannot be interpreted."
@@ -5258,7 +5258,7 @@ msgstr ""
"O ficheiro clave contén a clave «%s» que ten un valor que non é posíbel "
"interpretar."
-#: glib/gkeyfile.c:2759 glib/gkeyfile.c:3128
+#: glib/gkeyfile.c:2763 glib/gkeyfile.c:3132
#, c-format
msgid ""
"Key file contains key “%s” in group “%s” which has a value that cannot be "
@@ -5267,83 +5267,83 @@ msgstr ""
"O ficheiro clave contén a clave «%s» no grupo «%s» que ten un valor que non "
"é posíbel interpretar."
-#: glib/gkeyfile.c:2837 glib/gkeyfile.c:2914
+#: glib/gkeyfile.c:2841 glib/gkeyfile.c:2918
#, c-format
msgid "Key “%s” in group “%s” has value “%s” where %s was expected"
msgstr "A clave «%s» do grupo «%s» ten o valor «%s», pero agardábase %s"
-#: glib/gkeyfile.c:4323
+#: glib/gkeyfile.c:4327
msgid "Key file contains escape character at end of line"
msgstr "O ficheiro clave contén un carácter de escape ao final da liña"
-#: glib/gkeyfile.c:4345
+#: glib/gkeyfile.c:4349
#, c-format
msgid "Key file contains invalid escape sequence “%s”"
msgstr "O ficheiro clave contén a secuencia de escape non válida «%s»"
-#: glib/gkeyfile.c:4490
+#: glib/gkeyfile.c:4494
#, c-format
msgid "Value “%s” cannot be interpreted as a number."
msgstr "Non é posíbel interpretar o valor «%s» como un número."
-#: glib/gkeyfile.c:4504
+#: glib/gkeyfile.c:4508
#, c-format
msgid "Integer value “%s” out of range"
msgstr "O valor enteiro «%s» está fóra do intervalo"
-#: glib/gkeyfile.c:4537
+#: glib/gkeyfile.c:4541
#, c-format
msgid "Value “%s” cannot be interpreted as a float number."
msgstr "Non é posíbel interpretar o valor «%s» como un número flotante."
-#: glib/gkeyfile.c:4576
+#: glib/gkeyfile.c:4580
#, c-format
msgid "Value “%s” cannot be interpreted as a boolean."
msgstr "Non é posíbel interpretar o valor «%s» como un booleano."
-#: glib/gmappedfile.c:131
+#: glib/gmappedfile.c:135
#, c-format
msgid "Failed to get attributes of file “%s%s%s%s”: fstat() failed: %s"
msgstr ""
"Produciuse un erro ao obter os atributos do ficheiro «%s%s%s%s»: fstat() "
"fallou: %s"
-#: glib/gmappedfile.c:197
+#: glib/gmappedfile.c:201
#, c-format
msgid "Failed to map %s%s%s%s: mmap() failed: %s"
msgstr "Produciuse un erro ao mapear «%s%s%s%s»: mmap() fallou: %s"
-#: glib/gmappedfile.c:264
+#: glib/gmappedfile.c:268
#, c-format
msgid "Failed to open file “%s”: open() failed: %s"
msgstr "Produciuse un erro ao abrir o ficheiro «%s»: open() fallou: %s"
-#: glib/gmarkup.c:393 glib/gmarkup.c:435
+#: glib/gmarkup.c:398 glib/gmarkup.c:440
#, c-format
msgid "Error on line %d char %d: "
msgstr "Erro na liña %d carácter %d: "
-#: glib/gmarkup.c:457 glib/gmarkup.c:540
+#: glib/gmarkup.c:462 glib/gmarkup.c:545
#, c-format
msgid "Invalid UTF-8 encoded text in name — not valid “%s”"
msgstr "O texto do nome codificado en UTF-8 non é válido - «%s» non válido"
-#: glib/gmarkup.c:468
+#: glib/gmarkup.c:473
#, c-format
msgid "“%s” is not a valid name"
msgstr "«%s» non é un nome válido"
-#: glib/gmarkup.c:484
+#: glib/gmarkup.c:489
#, c-format
msgid "“%s” is not a valid name: “%c”"
msgstr "«%s» non é un nome válido: '%c'"
-#: glib/gmarkup.c:608
+#: glib/gmarkup.c:613
#, c-format
msgid "Error on line %d: %s"
msgstr "Erro na liña %d: %s"
-#: glib/gmarkup.c:685
+#: glib/gmarkup.c:690
#, c-format
msgid ""
"Failed to parse “%-.*s”, which should have been a digit inside a character "
@@ -5353,7 +5353,7 @@ msgstr ""
"dunha referencia de carácter (por exemplo &#234;) - pode que o díxito sexa "
"grande de máis"
-#: glib/gmarkup.c:697
+#: glib/gmarkup.c:702
msgid ""
"Character reference did not end with a semicolon; most likely you used an "
"ampersand character without intending to start an entity — escape ampersand "
@@ -5363,24 +5363,24 @@ msgstr ""
"utilizou un carácter & sen intención de comezar unha entidade - escape o & "
"como &amp;"
-#: glib/gmarkup.c:723
+#: glib/gmarkup.c:728
#, c-format
msgid "Character reference “%-.*s” does not encode a permitted character"
msgstr "A referencia de carácter «%-.*s» non codifica un carácter permitido"
-#: glib/gmarkup.c:761
+#: glib/gmarkup.c:766
msgid ""
"Empty entity “&;” seen; valid entities are: &amp; &quot; &lt; &gt; &apos;"
msgstr ""
"Detectada unha entidade baleira «&;»; as entidades válidas son: &amp; &quot; "
"&lt; &gt; &apos;"
-#: glib/gmarkup.c:769
+#: glib/gmarkup.c:774
#, c-format
msgid "Entity name “%-.*s” is not known"
msgstr "Non se coñece o nome de entidade «%-.*s»"
-#: glib/gmarkup.c:774
+#: glib/gmarkup.c:779
msgid ""
"Entity did not end with a semicolon; most likely you used an ampersand "
"character without intending to start an entity — escape ampersand as &amp;"
@@ -5388,11 +5388,11 @@ msgstr ""
"A entidade non remata cun punto e coma, probabelmente usou o carácter & sen "
"a intención de comezar unha entidade, escriba o & como &amp;"
-#: glib/gmarkup.c:1188
+#: glib/gmarkup.c:1193
msgid "Document must begin with an element (e.g. <book>)"
msgstr "O documento debe comezar cun elemento (por exemplo <book>)"
-#: glib/gmarkup.c:1228
+#: glib/gmarkup.c:1233
#, c-format
msgid ""
"“%s” is not a valid character following a “<” character; it may not begin an "
@@ -5401,7 +5401,7 @@ msgstr ""
"«%s» non é un carácter válido despois dun carácter «<»; non pode iniciar un "
"nome de elemento"
-#: glib/gmarkup.c:1271
+#: glib/gmarkup.c:1276
#, c-format
msgid ""
"Odd character “%s”, expected a “>” character to end the empty-element tag "
@@ -5410,12 +5410,12 @@ msgstr ""
"Carácter estraño «%s», esperábase un carácter «>» para pechar a etiqueta de "
"elemento baleiro «%s»"
-#: glib/gmarkup.c:1341
+#: glib/gmarkup.c:1346
#, c-format
msgid "Too many attributes in element “%s”"
msgstr "Hai demasiados atributos no elemento «%s»"
-#: glib/gmarkup.c:1361
+#: glib/gmarkup.c:1366
#, c-format
msgid ""
"Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”"
@@ -5423,7 +5423,7 @@ msgstr ""
"Carácter estraño «%s», esperábase un «=» despois do nome do atributo «%s» do "
"elemento «%s»"
-#: glib/gmarkup.c:1403
+#: glib/gmarkup.c:1408
#, c-format
msgid ""
"Odd character “%s”, expected a “>” or “/” character to end the start tag of "
@@ -5434,7 +5434,7 @@ msgstr ""
"etiqueta de comezo do elemento «%s» ou opcionalmente un atributo; quizais "
"usou un carácter non válido no nome dun atributo"
-#: glib/gmarkup.c:1448
+#: glib/gmarkup.c:1453
#, c-format
msgid ""
"Odd character “%s”, expected an open quote mark after the equals sign when "
@@ -5443,7 +5443,7 @@ msgstr ""
"Carácter estraño «%s», esperábase unhas comiñas de apertura despois do signo "
"igual para dar un valor ao atributo «%s» do elemento «%s»"
-#: glib/gmarkup.c:1582
+#: glib/gmarkup.c:1587
#, c-format
msgid ""
"“%s” is not a valid character following the characters “</”; “%s” may not "
@@ -5452,7 +5452,7 @@ msgstr ""
"«%s» non é un carácter válido despois dos caracteres «</»; «%s» non pode "
"comezar o nome dun elemento"
-#: glib/gmarkup.c:1620
+#: glib/gmarkup.c:1625
#, c-format
msgid ""
"“%s” is not a valid character following the close element name “%s”; the "
@@ -5461,25 +5461,25 @@ msgstr ""
"«%s» non é un carácter válido despois do nome de elemento de peche «%s»; o "
"carácter permitido é «>»"
-#: glib/gmarkup.c:1632
+#: glib/gmarkup.c:1637
#, c-format
msgid "Element “%s” was closed, no element is currently open"
msgstr "Pechouse o elemento «%s», actualmente non hai ningún elemento aberto"
-#: glib/gmarkup.c:1641
+#: glib/gmarkup.c:1646
#, c-format
msgid "Element “%s” was closed, but the currently open element is “%s”"
msgstr "Pechouse o elemento «%s», mais o elemento aberto actualmente é «%s»"
-#: glib/gmarkup.c:1794
+#: glib/gmarkup.c:1799
msgid "Document was empty or contained only whitespace"
msgstr "O documento estaba baleiro ou só contiña espazos en branco"
-#: glib/gmarkup.c:1808
+#: glib/gmarkup.c:1813
msgid "Document ended unexpectedly just after an open angle bracket “<”"
msgstr "O documento rematou inesperadamente despois dun símbolo menor que «<»"
-#: glib/gmarkup.c:1816 glib/gmarkup.c:1861
+#: glib/gmarkup.c:1821 glib/gmarkup.c:1866
#, c-format
msgid ""
"Document ended unexpectedly with elements still open — “%s” was the last "
@@ -5488,7 +5488,7 @@ msgstr ""
"O documento rematou inesperadamente con elementos aínda abertos - «%s» foi o "
"último elemento aberto"
-#: glib/gmarkup.c:1824
+#: glib/gmarkup.c:1829
#, c-format
msgid ""
"Document ended unexpectedly, expected to see a close angle bracket ending "
@@ -5497,21 +5497,21 @@ msgstr ""
"O documento rematou inesperadamente, esperábase ver un símbolo maior que '>' "
"que pechase a etiqueta <%s/>"
-#: glib/gmarkup.c:1830
+#: glib/gmarkup.c:1835
msgid "Document ended unexpectedly inside an element name"
msgstr "O documento rematou inesperadamente dentro dun nome de elemento"
-#: glib/gmarkup.c:1836
+#: glib/gmarkup.c:1841
msgid "Document ended unexpectedly inside an attribute name"
msgstr "O documento rematou inesperadamente dentro dun nome de atributo"
-#: glib/gmarkup.c:1841
+#: glib/gmarkup.c:1846
msgid "Document ended unexpectedly inside an element-opening tag."
msgstr ""
"O documento rematou inesperadamente dentro dunha etiqueta de comezo de "
"elemento."
-#: glib/gmarkup.c:1847
+#: glib/gmarkup.c:1852
msgid ""
"Document ended unexpectedly after the equals sign following an attribute "
"name; no attribute value"
@@ -5519,25 +5519,25 @@ msgstr ""
"O documento rematou inesperadamente despois do signo igual que segue a un "
"nome de atributo; non hai valor de atributo"
-#: glib/gmarkup.c:1854
+#: glib/gmarkup.c:1859
msgid "Document ended unexpectedly while inside an attribute value"
msgstr "O documento rematou inesperadamente dentro dun valor de atributo"
-#: glib/gmarkup.c:1871
+#: glib/gmarkup.c:1876
#, c-format
msgid "Document ended unexpectedly inside the close tag for element “%s”"
msgstr ""
"O documento rematou inesperadamente dentro da etiqueta que pechaba o "
"elemento «%s»"
-#: glib/gmarkup.c:1875
+#: glib/gmarkup.c:1880
msgid ""
"Document ended unexpectedly inside the close tag for an unopened element"
msgstr ""
"O documento rematou inesperadamente dentro da etiqueta que pechaba o "
"elemento «%s»"
-#: glib/gmarkup.c:1881
+#: glib/gmarkup.c:1886
msgid "Document ended unexpectedly inside a comment or processing instruction"
msgstr ""
"O documento rematou inesperadamente dentro dun comentario ou instrución de "
@@ -6084,21 +6084,21 @@ msgstr ""
"Erro inesperado en g_io_channel_win32_poll() ao ler datos desde un proceso "
"fillo"
-#: glib/gstrfuncs.c:3370 glib/gstrfuncs.c:3472
+#: glib/gstrfuncs.c:3373 glib/gstrfuncs.c:3475
msgid "Empty string is not a number"
msgstr "A cadea baleira non é un número"
-#: glib/gstrfuncs.c:3394
+#: glib/gstrfuncs.c:3397
#, c-format
msgid "“%s” is not a signed number"
msgstr "«%s» non é un número con signo"
-#: glib/gstrfuncs.c:3404 glib/gstrfuncs.c:3508
+#: glib/gstrfuncs.c:3407 glib/gstrfuncs.c:3511
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "O número «%s» está fóra de rango [%s, %s]"
-#: glib/gstrfuncs.c:3498
+#: glib/gstrfuncs.c:3501
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "«%s» non é un número sen signo"
@@ -6300,7 +6300,7 @@ msgstr "Eib"
msgid "byte"
msgid_plural "bytes"
msgstr[0] "byte"
-msgstr[1] "%u bytes"
+msgstr[1] "bytes"
#: glib/gutils.c:3060
msgid "bit"
diff --git a/po/sv.po b/po/sv.po
index 213a2930b..d8a16e312 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: glib\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n"
-"POT-Creation-Date: 2023-02-15 16:30+0000\n"
+"POT-Creation-Date: 2023-04-14 15:48+0000\n"
"PO-Revision-Date: 2023-02-15 18:07+0100\n"
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -275,7 +275,7 @@ msgstr ""
#: gio/gbufferedinputstream.c:422 gio/gbufferedinputstream.c:500
#: gio/ginputstream.c:181 gio/ginputstream.c:381 gio/ginputstream.c:650
#: gio/ginputstream.c:1052 gio/goutputstream.c:225 gio/goutputstream.c:1051
-#: gio/gpollableinputstream.c:207 gio/gpollableoutputstream.c:279
+#: gio/gpollableinputstream.c:221 gio/gpollableoutputstream.c:293
#, c-format
msgid "Too large count value passed to %s"
msgstr "För stort räknevärde skickat till %s"
@@ -298,7 +298,7 @@ msgstr "Strömmen är redan stängd"
msgid "Truncate not supported on base stream"
msgstr "Kapning stöds inte på basströmmen"
-#: gio/gcancellable.c:326 gio/gdbusconnection.c:1859 gio/gdbusprivate.c:1420
+#: gio/gcancellable.c:326 gio/gdbusconnection.c:1867 gio/gdbusprivate.c:1434
#: gio/gsimpleasyncresult.c:873 gio/gsimpleasyncresult.c:899
#, c-format
msgid "Operation was cancelled"
@@ -381,17 +381,17 @@ msgstr "Inloggningsuppgiftsspoofning är inte möjligt i detta OS"
msgid "Unexpected early end-of-stream"
msgstr "Oväntat tidig end-of-stream"
-#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:234 gio/gdbusaddress.c:321
+#: gio/gdbusaddress.c:168 gio/gdbusaddress.c:240 gio/gdbusaddress.c:327
#, c-format
msgid "Unsupported key “%s” in address entry “%s”"
msgstr "Nyckeln ”%s” stöds inte i adressposten ”%s”"
-#: gio/gdbusaddress.c:175
+#: gio/gdbusaddress.c:181
#, c-format
msgid "Meaningless key/value pair combination in address entry “%s”"
msgstr "Betydelselös kombination av nyckel/värde-par i adressposten ”%s”"
-#: gio/gdbusaddress.c:184
+#: gio/gdbusaddress.c:190
#, c-format
msgid ""
"Address “%s” is invalid (need exactly one of path, dir, tmpdir, or abstract "
@@ -400,28 +400,28 @@ msgstr ""
"Adressen ”%s” är ogiltig (behöver exakt en av sökväg, katalog, "
"temporärkatalog eller abstrakta nycklar)"
-#: gio/gdbusaddress.c:249 gio/gdbusaddress.c:260 gio/gdbusaddress.c:275
-#: gio/gdbusaddress.c:336 gio/gdbusaddress.c:347
+#: gio/gdbusaddress.c:255 gio/gdbusaddress.c:266 gio/gdbusaddress.c:281
+#: gio/gdbusaddress.c:342 gio/gdbusaddress.c:353
#, c-format
msgid "Error in address “%s” — the “%s” attribute is malformed"
msgstr "Fel i adressen ”%s” — attributet ”%s” är felformulerat"
-#: gio/gdbusaddress.c:417 gio/gdbusaddress.c:676
+#: gio/gdbusaddress.c:423 gio/gdbusaddress.c:682
#, c-format
msgid "Unknown or unsupported transport “%s” for address “%s”"
msgstr "Transport ”%s” är okänd eller saknar stöd för adressen ”%s”"
-#: gio/gdbusaddress.c:461
+#: gio/gdbusaddress.c:467
#, c-format
msgid "Address element “%s” does not contain a colon (:)"
msgstr "Adresselementet ”%s” innehåller inte ett kolontecken (:)"
-#: gio/gdbusaddress.c:470
+#: gio/gdbusaddress.c:476
#, c-format
msgid "Transport name in address element “%s” must not be empty"
msgstr "Transportnamn i adresselementet ”%s” får inte vara tomt"
-#: gio/gdbusaddress.c:491
+#: gio/gdbusaddress.c:497
#, c-format
msgid ""
"Key/Value pair %d, “%s”, in address element “%s” does not contain an equal "
@@ -430,14 +430,14 @@ msgstr ""
"Nyckel/Värde-par %d, ”%s”, i adresselementet ”%s” innehåller inte ett "
"likhetstecken"
-#: gio/gdbusaddress.c:502
+#: gio/gdbusaddress.c:508
#, c-format
msgid ""
"Key/Value pair %d, “%s”, in address element “%s” must not have an empty key"
msgstr ""
"Nyckel/Värde-par %d, ”%s”, i adresselementet ”%s” får inte ha en tom nyckel"
-#: gio/gdbusaddress.c:516
+#: gio/gdbusaddress.c:522
#, c-format
msgid ""
"Error unescaping key or value in Key/Value pair %d, “%s”, in address element "
@@ -446,7 +446,7 @@ msgstr ""
"Fel vid borttagning av escape i nyckel eller värde i Nyckel/Värde-par %d, "
"”%s”, i adresselementet ”%s”"
-#: gio/gdbusaddress.c:584
+#: gio/gdbusaddress.c:590
#, c-format
msgid ""
"Error in address “%s” — the unix transport requires exactly one of the keys "
@@ -455,77 +455,77 @@ msgstr ""
"Fel i adressen ”%s” — unix-transporten kräver att exakt en av nycklarna "
"”path” eller ”abstract” har ställts in"
-#: gio/gdbusaddress.c:619
+#: gio/gdbusaddress.c:625
#, c-format
msgid "Error in address “%s” — the host attribute is missing or malformed"
msgstr "Fel i adressen ”%s” — värdattributet saknas eller är felformulerat"
-#: gio/gdbusaddress.c:633
+#: gio/gdbusaddress.c:639
#, c-format
msgid "Error in address “%s” — the port attribute is missing or malformed"
msgstr "Fel i adressen ”%s” — portattributet saknas eller är felformulerat"
-#: gio/gdbusaddress.c:647
+#: gio/gdbusaddress.c:653
#, c-format
msgid "Error in address “%s” — the noncefile attribute is missing or malformed"
msgstr ""
"Fel i adressen ”%s” — attributet noncefile saknas eller är felformulerat"
-#: gio/gdbusaddress.c:668
+#: gio/gdbusaddress.c:674
msgid "Error auto-launching: "
msgstr "Fel vid automatisk körning: "
-#: gio/gdbusaddress.c:721
+#: gio/gdbusaddress.c:727
#, c-format
msgid "Error opening nonce file “%s”: %s"
msgstr "Fel vid öppning av nonce-filen ”%s”: %s"
-#: gio/gdbusaddress.c:740
+#: gio/gdbusaddress.c:746
#, c-format
msgid "Error reading from nonce file “%s”: %s"
msgstr "Fel vid läsning från nonce-filen ”%s”: %s"
-#: gio/gdbusaddress.c:749
+#: gio/gdbusaddress.c:755
#, c-format
msgid "Error reading from nonce file “%s”, expected 16 bytes, got %d"
msgstr "Fel vid läsning från nonce-filen ”%s”, förväntade 16 byte, fick %d"
-#: gio/gdbusaddress.c:767
+#: gio/gdbusaddress.c:773
#, c-format
msgid "Error writing contents of nonce file “%s” to stream:"
msgstr "Fel vid skrivning av innehåll i nonce-filen ”%s” till ström:"
-#: gio/gdbusaddress.c:982
+#: gio/gdbusaddress.c:988
msgid "The given address is empty"
msgstr "Angivna adressen är tom"
-#: gio/gdbusaddress.c:1095
+#: gio/gdbusaddress.c:1101
#, c-format
msgid "Cannot spawn a message bus when AT_SECURE is set"
msgstr "Kan inte starta en meddelandebuss när AT_SECURE har ställts in"
-#: gio/gdbusaddress.c:1102
+#: gio/gdbusaddress.c:1108
msgid "Cannot spawn a message bus without a machine-id: "
msgstr "Kan inte starta en meddelandebuss utan ett maskin-id: "
-#: gio/gdbusaddress.c:1109
+#: gio/gdbusaddress.c:1115
#, c-format
msgid "Cannot autolaunch D-Bus without X11 $DISPLAY"
msgstr "Kan inte starta D-Bus automatiskt utan X11-miljövariabeln $DISPLAY"
-#: gio/gdbusaddress.c:1151
+#: gio/gdbusaddress.c:1157
#, c-format
msgid "Error spawning command line “%s”: "
msgstr "Fel vid körning av kommandoraden ”%s”: "
-#: gio/gdbusaddress.c:1220
+#: gio/gdbusaddress.c:1226
#, c-format
msgid "Cannot determine session bus address (not implemented for this OS)"
msgstr ""
"Kan inte fastställa adress för sessionsbuss (inte implementerat för detta "
"operativsystem)"
-#: gio/gdbusaddress.c:1374 gio/gdbusconnection.c:7316
+#: gio/gdbusaddress.c:1380 gio/gdbusconnection.c:7326
#, c-format
msgid ""
"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable "
@@ -534,7 +534,7 @@ msgstr ""
"Kan inte fastställa bussadressen från miljövariabeln DBUS_STARTER_BUS_TYPE — "
"okänt värde ”%s”"
-#: gio/gdbusaddress.c:1383 gio/gdbusconnection.c:7325
+#: gio/gdbusaddress.c:1389 gio/gdbusconnection.c:7335
msgid ""
"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment "
"variable is not set"
@@ -542,7 +542,7 @@ msgstr ""
"Kan inte fastställa bussadress därför att miljövariabeln "
"DBUS_STARTER_BUS_TYPE inte är inställd"
-#: gio/gdbusaddress.c:1393
+#: gio/gdbusaddress.c:1399
#, c-format
msgid "Unknown bus type %d"
msgstr "Okänd busstyp %d"
@@ -575,12 +575,12 @@ msgstr "Användar-ID:n måste vara samma för motpart och server"
msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer"
msgstr "Avbröts via GDBusAuthObserver::authorize-authenticated-peer"
-#: gio/gdbusauthmechanismsha1.c:303
+#: gio/gdbusauthmechanismsha1.c:307
#, c-format
msgid "Error when getting information for directory “%s”: %s"
msgstr "Fel vid hämtning av information för katalogen ”%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:318
+#: gio/gdbusauthmechanismsha1.c:322
#, c-format
msgid ""
"Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o"
@@ -588,32 +588,32 @@ msgstr ""
"Rättigheter på katalogen ”%s” är felformulerade. Förväntade rättigheten "
"0700, fick 0%o"
-#: gio/gdbusauthmechanismsha1.c:351 gio/gdbusauthmechanismsha1.c:362
+#: gio/gdbusauthmechanismsha1.c:355 gio/gdbusauthmechanismsha1.c:366
#, c-format
msgid "Error creating directory “%s”: %s"
msgstr "Fel vid skapandet av katalogen ”%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:364 gio/gfile.c:1095 gio/gfile.c:1333
+#: gio/gdbusauthmechanismsha1.c:368 gio/gfile.c:1095 gio/gfile.c:1333
#: gio/gfile.c:1471 gio/gfile.c:1709 gio/gfile.c:1764 gio/gfile.c:1822
#: gio/gfile.c:1906 gio/gfile.c:1963 gio/gfile.c:2027 gio/gfile.c:2082
-#: gio/gfile.c:3787 gio/gfile.c:3927 gio/gfile.c:4339 gio/gfile.c:4809
-#: gio/gfile.c:5220 gio/gfile.c:5305 gio/gfile.c:5395 gio/gfile.c:5492
-#: gio/gfile.c:5579 gio/gfile.c:5680 gio/gfile.c:8809 gio/gfile.c:8899
-#: gio/gfile.c:8983 gio/win32/gwinhttpfile.c:453
+#: gio/gfile.c:3797 gio/gfile.c:3937 gio/gfile.c:4349 gio/gfile.c:4819
+#: gio/gfile.c:5230 gio/gfile.c:5315 gio/gfile.c:5405 gio/gfile.c:5502
+#: gio/gfile.c:5589 gio/gfile.c:5690 gio/gfile.c:8819 gio/gfile.c:8909
+#: gio/gfile.c:8993 gio/win32/gwinhttpfile.c:453
msgid "Operation not supported"
msgstr "Åtgärden stöds inte"
-#: gio/gdbusauthmechanismsha1.c:407
+#: gio/gdbusauthmechanismsha1.c:411
#, c-format
msgid "Error opening keyring “%s” for reading: "
msgstr "Fel vid öppnandet av nyckelringen ”%s” för läsning: "
-#: gio/gdbusauthmechanismsha1.c:430 gio/gdbusauthmechanismsha1.c:771
+#: gio/gdbusauthmechanismsha1.c:434 gio/gdbusauthmechanismsha1.c:775
#, c-format
msgid "Line %d of the keyring at “%s” with content “%s” is malformed"
msgstr "Rad %d av nyckelringen vid ”%s” med innehåll ”%s” är felformulerad"
-#: gio/gdbusauthmechanismsha1.c:444 gio/gdbusauthmechanismsha1.c:785
+#: gio/gdbusauthmechanismsha1.c:448 gio/gdbusauthmechanismsha1.c:789
#, c-format
msgid ""
"First token of line %d of the keyring at “%s” with content “%s” is malformed"
@@ -621,7 +621,7 @@ msgstr ""
"Första token på rad %d av nyckelringen i ”%s” med innehållet ”%s” är "
"felformulerad"
-#: gio/gdbusauthmechanismsha1.c:458 gio/gdbusauthmechanismsha1.c:799
+#: gio/gdbusauthmechanismsha1.c:462 gio/gdbusauthmechanismsha1.c:803
#, c-format
msgid ""
"Second token of line %d of the keyring at “%s” with content “%s” is malformed"
@@ -629,57 +629,57 @@ msgstr ""
"Andra token på rad %d av nyckelringen i ”%s” med innehållet ”%s” är "
"felformulerad"
-#: gio/gdbusauthmechanismsha1.c:482
+#: gio/gdbusauthmechanismsha1.c:486
#, c-format
msgid "Didn’t find cookie with id %d in the keyring at “%s”"
msgstr "Hittade inte kaka med id %d i nyckelringen vid ”%s”"
-#: gio/gdbusauthmechanismsha1.c:539
+#: gio/gdbusauthmechanismsha1.c:543
#, c-format
msgid "Error creating lock file “%s”: %s"
msgstr "Fel vid skapandet av låsfilen ”%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:612
+#: gio/gdbusauthmechanismsha1.c:616
#, c-format
msgid "Error deleting stale lock file “%s”: %s"
msgstr "Fel vid borttagning av gamla låsfilen ”%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:651
+#: gio/gdbusauthmechanismsha1.c:655
#, c-format
msgid "Error closing (unlinked) lock file “%s”: %s"
msgstr "Fel vid stängning av (avlänkad) låsfil ”%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:662
+#: gio/gdbusauthmechanismsha1.c:666
#, c-format
msgid "Error unlinking lock file “%s”: %s"
msgstr "Fel vid avlänkning av låsfilen ”%s”: %s"
-#: gio/gdbusauthmechanismsha1.c:738
+#: gio/gdbusauthmechanismsha1.c:742
#, c-format
msgid "Error opening keyring “%s” for writing: "
msgstr "Fel vid öppning av nyckelringen ”%s” för skrivning: "
-#: gio/gdbusauthmechanismsha1.c:932
+#: gio/gdbusauthmechanismsha1.c:936
#, c-format
msgid "(Additionally, releasing the lock for “%s” also failed: %s) "
msgstr "(I tillägg misslyckades även upplåsningen för ”%s”: %s) "
-#: gio/gdbusconnection.c:590 gio/gdbusconnection.c:2405
+#: gio/gdbusconnection.c:590 gio/gdbusconnection.c:2415
msgid "The connection is closed"
msgstr "Anslutningen är stängd"
-#: gio/gdbusconnection.c:1889
+#: gio/gdbusconnection.c:1899
msgid "Timeout was reached"
msgstr "Tidsgränsen uppnåddes"
-#: gio/gdbusconnection.c:2528
+#: gio/gdbusconnection.c:2538
msgid ""
"Unsupported flags encountered when constructing a client-side connection"
msgstr ""
"Flaggor som inte stöds påträffades vid konstruktion av en anslutning på "
"klientsidan"
-#: gio/gdbusconnection.c:4257 gio/gdbusconnection.c:4611
+#: gio/gdbusconnection.c:4267 gio/gdbusconnection.c:4621
#, c-format
msgid ""
"No such interface “org.freedesktop.DBus.Properties” on object at path %s"
@@ -687,79 +687,79 @@ msgstr ""
"Inget sådant gränssnitt ”org.freedesktop.DBus.Properties” på objekt med "
"sökvägen %s"
-#: gio/gdbusconnection.c:4402
+#: gio/gdbusconnection.c:4412
#, c-format
msgid "No such property “%s”"
msgstr "Ingen sådan egenskap ”%s”"
-#: gio/gdbusconnection.c:4414
+#: gio/gdbusconnection.c:4424
#, c-format
msgid "Property “%s” is not readable"
msgstr "Egenskapen ”%s” är inte läsbar"
-#: gio/gdbusconnection.c:4425
+#: gio/gdbusconnection.c:4435
#, c-format
msgid "Property “%s” is not writable"
msgstr "Egenskapen ”%s” är inte skrivbar"
-#: gio/gdbusconnection.c:4445
+#: gio/gdbusconnection.c:4455
#, c-format
msgid "Error setting property “%s”: Expected type “%s” but got “%s”"
msgstr ""
"Fel vid inställning av egenskapen ”%s”: Förväntade typen ”%s” men fick ”%s”"
-#: gio/gdbusconnection.c:4550 gio/gdbusconnection.c:4765
-#: gio/gdbusconnection.c:6742
+#: gio/gdbusconnection.c:4560 gio/gdbusconnection.c:4775
+#: gio/gdbusconnection.c:6752
#, c-format
msgid "No such interface “%s”"
msgstr "Inget sådan gränssnitt ”%s”"
-#: gio/gdbusconnection.c:4981 gio/gdbusconnection.c:7256
+#: gio/gdbusconnection.c:4991 gio/gdbusconnection.c:7266
#, c-format
msgid "No such interface “%s” on object at path %s"
msgstr "Inget sådant gränssnitt ”%s” på objekt med sökvägen %s"
-#: gio/gdbusconnection.c:5082
+#: gio/gdbusconnection.c:5092
#, c-format
msgid "No such method “%s”"
msgstr "Ingen sådan metod ”%s”"
-#: gio/gdbusconnection.c:5113
+#: gio/gdbusconnection.c:5123
#, c-format
msgid "Type of message, “%s”, does not match expected type “%s”"
msgstr "Typ av meddelande, ”%s”, matchar inte förväntade typen ”%s”"
-#: gio/gdbusconnection.c:5316
+#: gio/gdbusconnection.c:5326
#, c-format
msgid "An object is already exported for the interface %s at %s"
msgstr "Ett objekt är redan exporterat för gränssnittet %s vid %s"
-#: gio/gdbusconnection.c:5543
+#: gio/gdbusconnection.c:5553
#, c-format
msgid "Unable to retrieve property %s.%s"
msgstr "Kunde inte hämta egenskap %s.%s"
-#: gio/gdbusconnection.c:5599
+#: gio/gdbusconnection.c:5609
#, c-format
msgid "Unable to set property %s.%s"
msgstr "Kunde inte sätta egenskap %s.%s"
-#: gio/gdbusconnection.c:5778
+#: gio/gdbusconnection.c:5788
#, c-format
msgid "Method “%s” returned type “%s”, but expected “%s”"
msgstr "Metoden ”%s” returnerade typen ”%s”, men förväntade ”%s”"
-#: gio/gdbusconnection.c:6854
+#: gio/gdbusconnection.c:6864
#, c-format
msgid "Method “%s” on interface “%s” with signature “%s” does not exist"
msgstr "Metoden ”%s” på gränssnittet ”%s” med signaturen ”%s” finns inte"
-#: gio/gdbusconnection.c:6975
+#: gio/gdbusconnection.c:6985
#, c-format
msgid "A subtree is already exported for %s"
msgstr "Ett underträd har redan exporterats för %s"
-#: gio/gdbusconnection.c:7264
+#: gio/gdbusconnection.c:7274
#, c-format
msgid "Object does not exist at path “%s”"
msgstr "Objektet finns inte på sökvägen ”%s”"
@@ -960,23 +960,23 @@ msgstr "Fel returnerades med kropp av typen ”%s”"
msgid "Error return with empty body"
msgstr "Fel returnerade med tom kropp"
-#: gio/gdbusprivate.c:2187
+#: gio/gdbusprivate.c:2201
#, c-format
msgid "(Type any character to close this window)\n"
msgstr "(Skriv vilket tecken som helst för att stänga detta fönster)\n"
-#: gio/gdbusprivate.c:2373
+#: gio/gdbusprivate.c:2387
#, c-format
msgid "Session dbus not running, and autolaunch failed"
msgstr "Sessions-dbus kör inte, och autostart misslyckades"
-#: gio/gdbusprivate.c:2396
+#: gio/gdbusprivate.c:2410
#, c-format
msgid "Unable to get Hardware profile: %s"
msgstr "Kunde inte hämta hårdvaruprofil: %s"
#. Translators: Both placeholders are file paths
-#: gio/gdbusprivate.c:2447
+#: gio/gdbusprivate.c:2461
#, c-format
msgid "Unable to load %s or %s: "
msgstr "Kunde inte läsa in %s eller %s: "
@@ -1304,12 +1304,12 @@ msgstr "Fel: För många argument.\n"
msgid "Error: %s is not a valid well-known bus name.\n"
msgstr "Fel: %s är inte ett giltigt välkänt bussnamn.\n"
-#: gio/gdebugcontrollerdbus.c:360
+#: gio/gdebugcontrollerdbus.c:361
#, c-format
msgid "Not authorized to change debug settings"
msgstr "Inte behörig att ändra felsökningsinställningar"
-#: gio/gdesktopappinfo.c:2242 gio/gdesktopappinfo.c:5223
+#: gio/gdesktopappinfo.c:2242 gio/gdesktopappinfo.c:5226
msgid "Unnamed"
msgstr "Namnlös"
@@ -1326,26 +1326,26 @@ msgstr "Kunde inte hitta terminal som krävs för programmet"
msgid "Program ‘%s’ not found in $PATH"
msgstr "Programmet ”%s” hittades inte i $PATH"
-#: gio/gdesktopappinfo.c:3735
+#: gio/gdesktopappinfo.c:3738
#, c-format
msgid "Can’t create user application configuration folder %s: %s"
msgstr "Kan inte skapa programkonfigurationsmapp för användare %s: %s"
-#: gio/gdesktopappinfo.c:3739
+#: gio/gdesktopappinfo.c:3742
#, c-format
msgid "Can’t create user MIME configuration folder %s: %s"
msgstr "Kan inte skapa MIME-konfigurationsmapp för användare %s: %s"
-#: gio/gdesktopappinfo.c:3981 gio/gdesktopappinfo.c:4005
+#: gio/gdesktopappinfo.c:3984 gio/gdesktopappinfo.c:4008
msgid "Application information lacks an identifier"
msgstr "Programinformation saknar en identifierare"
-#: gio/gdesktopappinfo.c:4241
+#: gio/gdesktopappinfo.c:4244
#, c-format
msgid "Can’t create user desktop file %s"
msgstr "Kan inte skapa desktop-fil %s för användare"
-#: gio/gdesktopappinfo.c:4377
+#: gio/gdesktopappinfo.c:4380
#, c-format
msgid "Custom definition for %s"
msgstr "Anpassad definition för %s"
@@ -1418,7 +1418,7 @@ msgstr "Förväntade en GEmblem för GEmblemedIcon"
msgid "Containing mount does not exist"
msgstr "Innefattande montering finns inte"
-#: gio/gfile.c:2641 gio/glocalfile.c:2511
+#: gio/gfile.c:2641 gio/glocalfile.c:2515
msgid "Can’t copy over directory"
msgstr "Kan inte kopiera över katalog"
@@ -1443,49 +1443,49 @@ msgstr "Splice stöds inte"
msgid "Error splicing file: %s"
msgstr "Fel vid splice av fil: %s"
-#: gio/gfile.c:3185
+#: gio/gfile.c:3195
msgid "Copy (reflink/clone) between mounts is not supported"
msgstr "Kopiering (reflänk/klon) mellan monteringar stöds inte"
-#: gio/gfile.c:3189
+#: gio/gfile.c:3199
msgid "Copy (reflink/clone) is not supported or invalid"
msgstr "Kopiering (reflänk/klon) stöds inte eller är ogiltigt"
-#: gio/gfile.c:3194
+#: gio/gfile.c:3204
msgid "Copy (reflink/clone) is not supported or didn’t work"
msgstr "Kopiering (reflänk/klon) stöds inte eller fungerade inte"
-#: gio/gfile.c:3259
+#: gio/gfile.c:3269
msgid "Can’t copy special file"
msgstr "Kan inte kopiera specialfil"
-#: gio/gfile.c:4153
+#: gio/gfile.c:4163
msgid "Invalid symlink value given"
msgstr "Ogiltigt värde för symbolisk länk angivet"
-#: gio/gfile.c:4163 glib/gfileutils.c:2392
+#: gio/gfile.c:4173 glib/gfileutils.c:2392
msgid "Symbolic links not supported"
msgstr "Symboliska länkar stöds inte"
-#: gio/gfile.c:4450
+#: gio/gfile.c:4460
msgid "Trash not supported"
msgstr "Papperskorgen stöds inte"
-#: gio/gfile.c:4562
+#: gio/gfile.c:4572
#, c-format
msgid "File names cannot contain “%c”"
msgstr "Filnamn får inte innehålla ”%c”"
-#: gio/gfile.c:6993 gio/gfile.c:7119
+#: gio/gfile.c:7003 gio/gfile.c:7129
#, c-format
msgid "Failed to create a temporary directory for template “%s”: %s"
msgstr "Misslyckades med att skapa en temporär katalog för mallen ”%s”: %s"
-#: gio/gfile.c:7408 gio/gvolume.c:366
+#: gio/gfile.c:7418 gio/gvolume.c:366
msgid "volume doesn’t implement mount"
msgstr "volymen har inte implementerat montering"
-#: gio/gfile.c:7522 gio/gfile.c:7599
+#: gio/gfile.c:7532 gio/gfile.c:7609
msgid "No application is registered as handling this file"
msgstr "Inget program är registrerat för hantering av denna fil"
@@ -1494,11 +1494,11 @@ msgid "Enumerator is closed"
msgstr "Numreraren är stängd"
#: gio/gfileenumerator.c:221 gio/gfileenumerator.c:280
-#: gio/gfileenumerator.c:379 gio/gfileenumerator.c:478
+#: gio/gfileenumerator.c:424 gio/gfileenumerator.c:523
msgid "File enumerator has outstanding operation"
msgstr "Filnumreraren har kvarstående åtgärd"
-#: gio/gfileenumerator.c:370 gio/gfileenumerator.c:469
+#: gio/gfileenumerator.c:415 gio/gfileenumerator.c:514
msgid "File enumerator is already closed"
msgstr "Filnumreraren är redan stängd"
@@ -1741,12 +1741,12 @@ msgid "Error writing to stdout"
msgstr "Fel vid skrivning till standard ut"
#. Translators: commandline placeholder
-#: gio/gio-tool-cat.c:135 gio/gio-tool-info.c:379 gio/gio-tool-list.c:173
+#: gio/gio-tool-cat.c:135 gio/gio-tool-info.c:382 gio/gio-tool-list.c:176
#: gio/gio-tool-mkdir.c:50 gio/gio-tool-monitor.c:39 gio/gio-tool-monitor.c:41
#: gio/gio-tool-monitor.c:43 gio/gio-tool-monitor.c:45
#: gio/gio-tool-monitor.c:206 gio/gio-tool-mount.c:1210 gio/gio-tool-open.c:72
#: gio/gio-tool-remove.c:50 gio/gio-tool-rename.c:47 gio/gio-tool-set.c:95
-#: gio/gio-tool-trash.c:222 gio/gio-tool-tree.c:241
+#: gio/gio-tool-trash.c:222 gio/gio-tool-tree.c:246
msgid "LOCATION"
msgstr "PLATS"
@@ -1764,7 +1764,7 @@ msgstr ""
"använder GIO-platser i stället för lokala filer: exempelvis kan du använda\n"
"något liknande smb://server/resurs/fil.txt som plats."
-#: gio/gio-tool-cat.c:164 gio/gio-tool-info.c:410 gio/gio-tool-mkdir.c:78
+#: gio/gio-tool-cat.c:164 gio/gio-tool-info.c:413 gio/gio-tool-mkdir.c:78
#: gio/gio-tool-monitor.c:231 gio/gio-tool-mount.c:1261 gio/gio-tool-open.c:98
#: gio/gio-tool-remove.c:74 gio/gio-tool-trash.c:303
msgid "No locations given"
@@ -1861,57 +1861,62 @@ msgstr "Följ inte symboliska länkar"
msgid "attributes:\n"
msgstr "attribut:\n"
-#: gio/gio-tool-info.c:165 gio/gio-tool-info.c:174
+#: gio/gio-tool-info.c:166
#, c-format
msgid "display name: %s\n"
msgstr "visningsnamn: %s\n"
-#: gio/gio-tool-info.c:182
+#: gio/gio-tool-info.c:176
+#, c-format
+msgid "edit name: %s\n"
+msgstr "redigeringsnamn: %s\n"
+
+#: gio/gio-tool-info.c:184
#, c-format
msgid "name: %s\n"
msgstr "namn: %s\n"
-#: gio/gio-tool-info.c:189
+#: gio/gio-tool-info.c:191
#, c-format
msgid "type: %s\n"
msgstr "typ: %s\n"
-#: gio/gio-tool-info.c:195
+#: gio/gio-tool-info.c:197
msgid "size: "
msgstr "storlek: "
-#: gio/gio-tool-info.c:200
+#: gio/gio-tool-info.c:203
msgid "hidden\n"
msgstr "dold\n"
-#: gio/gio-tool-info.c:203
+#: gio/gio-tool-info.c:206
#, c-format
msgid "uri: %s\n"
msgstr "uri: %s\n"
-#: gio/gio-tool-info.c:210
+#: gio/gio-tool-info.c:213
#, c-format
msgid "local path: %s\n"
msgstr "lokal sökväg: %s\n"
-#: gio/gio-tool-info.c:244
+#: gio/gio-tool-info.c:247
#, c-format
msgid "unix mount: %s%s %s %s %s\n"
msgstr "unix-montering: %s%s %s %s %s\n"
-#: gio/gio-tool-info.c:325
+#: gio/gio-tool-info.c:328
msgid "Settable attributes:\n"
msgstr "Inställningsbara attribut:\n"
-#: gio/gio-tool-info.c:349
+#: gio/gio-tool-info.c:352
msgid "Writable attribute namespaces:\n"
msgstr "Skrivbara namnrymder för attribut:\n"
-#: gio/gio-tool-info.c:384
+#: gio/gio-tool-info.c:387
msgid "Show information about locations."
msgstr "Visa information om platser."
-#: gio/gio-tool-info.c:386
+#: gio/gio-tool-info.c:389
msgid ""
"gio info is similar to the traditional ls utility, but using GIO\n"
"locations instead of local files: for example, you can use something\n"
@@ -1977,11 +1982,11 @@ msgstr "Skriv ut visningsnamn"
msgid "Print full URIs"
msgstr "Skriv ut fullständiga URI:er"
-#: gio/gio-tool-list.c:178
+#: gio/gio-tool-list.c:181
msgid "List the contents of the locations."
msgstr "Lista innehållet för platserna."
-#: gio/gio-tool-list.c:180
+#: gio/gio-tool-list.c:183
msgid ""
"gio list is similar to the traditional ls utility, but using GIO\n"
"locations instead of local files: for example, you can use something\n"
@@ -2391,7 +2396,7 @@ msgstr "Den angivna platsen börjar inte med trash:///"
msgid "Follow symbolic links, mounts and shortcuts"
msgstr "Följ symboliska länkar, monteringar och genvägar"
-#: gio/gio-tool-tree.c:246
+#: gio/gio-tool-tree.c:251
msgid "List contents of directories in a tree-like format."
msgstr "Lista innehållet i kataloger i ett trädliknande format."
@@ -3012,12 +3017,12 @@ msgstr "Inga schemafiler hittades: gör ingenting."
msgid "No schema files found: removed existing output file."
msgstr "Inga schemafiler hittades: tog bort befintlig utmatningsfil."
-#: gio/glocalfile.c:563 gio/win32/gwinhttpfile.c:436
+#: gio/glocalfile.c:567 gio/win32/gwinhttpfile.c:436
#, c-format
msgid "Invalid filename %s"
msgstr "Ogiltigt filnamn %s"
-#: gio/glocalfile.c:1005
+#: gio/glocalfile.c:1009
#, c-format
msgid "Error getting filesystem info for %s: %s"
msgstr "Fel vid hämtning av filsystemsinformation för %s: %s"
@@ -3026,254 +3031,254 @@ msgstr "Fel vid hämtning av filsystemsinformation för %s: %s"
#. * the enclosing (user visible) mount of a file, but none
#. * exists.
#.
-#: gio/glocalfile.c:1141
+#: gio/glocalfile.c:1145
#, c-format
msgid "Containing mount for file %s not found"
msgstr "Innefattande montering för filen %s hittades inte"
-#: gio/glocalfile.c:1164
+#: gio/glocalfile.c:1168
msgid "Can’t rename root directory"
msgstr "Kan inte byta namn på rotkatalog"
-#: gio/glocalfile.c:1182 gio/glocalfile.c:1205
+#: gio/glocalfile.c:1186 gio/glocalfile.c:1209
#, c-format
msgid "Error renaming file %s: %s"
msgstr "Fel vid namnbyte av filen %s: %s"
-#: gio/glocalfile.c:1189
+#: gio/glocalfile.c:1193
msgid "Can’t rename file, filename already exists"
msgstr "Kan inte byta namn på filen, filnamnet finns redan"
-#: gio/glocalfile.c:1202 gio/glocalfile.c:2405 gio/glocalfile.c:2433
-#: gio/glocalfile.c:2572 gio/glocalfileoutputstream.c:658
+#: gio/glocalfile.c:1206 gio/glocalfile.c:2409 gio/glocalfile.c:2437
+#: gio/glocalfile.c:2576 gio/glocalfileoutputstream.c:658
msgid "Invalid filename"
msgstr "Ogiltigt filnamn"
-#: gio/glocalfile.c:1370 gio/glocalfile.c:1381
+#: gio/glocalfile.c:1374 gio/glocalfile.c:1385
#, c-format
msgid "Error opening file %s: %s"
msgstr "Fel vid öppning av filen %s: %s"
-#: gio/glocalfile.c:1506
+#: gio/glocalfile.c:1510
#, c-format
msgid "Error removing file %s: %s"
msgstr "Fel vid borttagning av filen %s: %s"
-#: gio/glocalfile.c:2000 gio/glocalfile.c:2011 gio/glocalfile.c:2038
+#: gio/glocalfile.c:2004 gio/glocalfile.c:2015 gio/glocalfile.c:2042
#, c-format
msgid "Error trashing file %s: %s"
msgstr "Fel vid kastande av filen %s: %s"
-#: gio/glocalfile.c:2058
+#: gio/glocalfile.c:2062
#, c-format
msgid "Unable to create trash directory %s: %s"
msgstr "Kunde inte skapa papperskorgskatalogen %s: %s"
-#: gio/glocalfile.c:2079
+#: gio/glocalfile.c:2083
#, c-format
msgid "Unable to find toplevel directory to trash %s"
msgstr "Kunde inte hitta toppnivåkatalog för att kasta %s"
-#: gio/glocalfile.c:2087
+#: gio/glocalfile.c:2091
#, c-format
msgid "Trashing on system internal mounts is not supported"
msgstr "Att kasta i papperskorg på systeminterna monteringar stöds inte"
-#: gio/glocalfile.c:2173 gio/glocalfile.c:2201
+#: gio/glocalfile.c:2177 gio/glocalfile.c:2205
#, c-format
msgid "Unable to find or create trash directory %s to trash %s"
msgstr "Kunde inte hitta eller skapa papperskorgskatalog %s att slänga %s i"
-#: gio/glocalfile.c:2245
+#: gio/glocalfile.c:2249
#, c-format
msgid "Unable to create trashing info file for %s: %s"
msgstr "Kunde inte skapa fil med information om vad som kastats för %s: %s"
-#: gio/glocalfile.c:2316
+#: gio/glocalfile.c:2320
#, c-format
msgid "Unable to trash file %s across filesystem boundaries"
msgstr "Kunde inte kasta filen %s över filsystemsgränser"
-#: gio/glocalfile.c:2320 gio/glocalfile.c:2376
+#: gio/glocalfile.c:2324 gio/glocalfile.c:2380
#, c-format
msgid "Unable to trash file %s: %s"
msgstr "Kunde inte kasta filen %s: %s"
-#: gio/glocalfile.c:2382
+#: gio/glocalfile.c:2386
#, c-format
msgid "Unable to trash file %s"
msgstr "Kunde inte kasta filen %s"
-#: gio/glocalfile.c:2408
+#: gio/glocalfile.c:2412
#, c-format
msgid "Error creating directory %s: %s"
msgstr "Fel vid skapandet av katalogen %s: %s"
-#: gio/glocalfile.c:2437
+#: gio/glocalfile.c:2441
#, c-format
msgid "Filesystem does not support symbolic links"
msgstr "Filsystemet saknar stöd för symboliska länkar"
-#: gio/glocalfile.c:2440
+#: gio/glocalfile.c:2444
#, c-format
msgid "Error making symbolic link %s: %s"
msgstr "Fel vid skapande av symboliska länken %s: %s"
-#: gio/glocalfile.c:2483 gio/glocalfile.c:2518 gio/glocalfile.c:2575
+#: gio/glocalfile.c:2487 gio/glocalfile.c:2522 gio/glocalfile.c:2579
#, c-format
msgid "Error moving file %s: %s"
msgstr "Fel vid flyttning av filen %s: %s"
-#: gio/glocalfile.c:2506
+#: gio/glocalfile.c:2510
msgid "Can’t move directory over directory"
msgstr "Kan inte flytta katalog över katalog"
-#: gio/glocalfile.c:2532 gio/glocalfileoutputstream.c:1110
+#: gio/glocalfile.c:2536 gio/glocalfileoutputstream.c:1110
#: gio/glocalfileoutputstream.c:1124 gio/glocalfileoutputstream.c:1139
#: gio/glocalfileoutputstream.c:1156 gio/glocalfileoutputstream.c:1170
msgid "Backup file creation failed"
msgstr "Misslyckades med att skapa säkerhetskopiefil"
-#: gio/glocalfile.c:2551
+#: gio/glocalfile.c:2555
#, c-format
msgid "Error removing target file: %s"
msgstr "Fel vid borttagning av målfil: %s"
-#: gio/glocalfile.c:2565
+#: gio/glocalfile.c:2569
msgid "Move between mounts not supported"
msgstr "Flyttning mellan monteringar stöds inte"
-#: gio/glocalfile.c:2741
+#: gio/glocalfile.c:2745
#, c-format
msgid "Could not determine the disk usage of %s: %s"
msgstr "Kunde inte bestämma diskanvändningen för %s: %s"
-#: gio/glocalfileinfo.c:775
+#: gio/glocalfileinfo.c:779
msgid "Attribute value must be non-NULL"
msgstr "Attributvärde måste vara icke-NULL"
-#: gio/glocalfileinfo.c:782
+#: gio/glocalfileinfo.c:786
msgid "Invalid attribute type (string or invalid expected)"
msgstr "Ogiltig attributtyp (sträng eller ogiltig förväntades)"
-#: gio/glocalfileinfo.c:789
+#: gio/glocalfileinfo.c:793
msgid "Invalid extended attribute name"
msgstr "Ogiltigt utökat attributnamn"
-#: gio/glocalfileinfo.c:840
+#: gio/glocalfileinfo.c:844
#, c-format
msgid "Error setting extended attribute “%s”: %s"
msgstr "Fel vid inställning av utökat attribut ”%s”: %s"
-#: gio/glocalfileinfo.c:1819 gio/win32/gwinhttpfile.c:191
+#: gio/glocalfileinfo.c:1823 gio/win32/gwinhttpfile.c:191
msgid " (invalid encoding)"
msgstr " (ogiltig kodning)"
-#: gio/glocalfileinfo.c:1978 gio/glocalfileoutputstream.c:945
+#: gio/glocalfileinfo.c:1982 gio/glocalfileoutputstream.c:945
#: gio/glocalfileoutputstream.c:997
#, c-format
msgid "Error when getting information for file “%s”: %s"
msgstr "Fel vid hämtning av information om filen ”%s”: %s"
-#: gio/glocalfileinfo.c:2281
+#: gio/glocalfileinfo.c:2288
#, c-format
msgid "Error when getting information for file descriptor: %s"
msgstr "Fel vid hämtning av information om filhandtag: %s"
-#: gio/glocalfileinfo.c:2326
+#: gio/glocalfileinfo.c:2333
msgid "Invalid attribute type (uint32 expected)"
msgstr "Ogiltig attributtyp (uint32 förväntades)"
-#: gio/glocalfileinfo.c:2344
+#: gio/glocalfileinfo.c:2351
msgid "Invalid attribute type (uint64 expected)"
msgstr "Ogiltig attributtyp (uint64 förväntades)"
-#: gio/glocalfileinfo.c:2363 gio/glocalfileinfo.c:2382
+#: gio/glocalfileinfo.c:2370 gio/glocalfileinfo.c:2389
msgid "Invalid attribute type (byte string expected)"
msgstr "Ogiltig attributtyp (bytesträng förväntades)"
-#: gio/glocalfileinfo.c:2429
+#: gio/glocalfileinfo.c:2436
msgid "Cannot set permissions on symlinks"
msgstr "Kan inte ställa in rättigheter på symboliska länkar"
-#: gio/glocalfileinfo.c:2445
+#: gio/glocalfileinfo.c:2452
#, c-format
msgid "Error setting permissions: %s"
msgstr "Fel vid inställning av rättigheter: %s"
-#: gio/glocalfileinfo.c:2496
+#: gio/glocalfileinfo.c:2503
#, c-format
msgid "Error setting owner: %s"
msgstr "Fel vid inställning av ägare: %s"
-#: gio/glocalfileinfo.c:2519
+#: gio/glocalfileinfo.c:2526
msgid "symlink must be non-NULL"
msgstr "symbolisk länk måste vara icke-NULL"
-#: gio/glocalfileinfo.c:2529 gio/glocalfileinfo.c:2548
-#: gio/glocalfileinfo.c:2559
+#: gio/glocalfileinfo.c:2536 gio/glocalfileinfo.c:2555
+#: gio/glocalfileinfo.c:2566
#, c-format
msgid "Error setting symlink: %s"
msgstr "Fel vid inställning av symbolisk länk: %s"
-#: gio/glocalfileinfo.c:2538
+#: gio/glocalfileinfo.c:2545
msgid "Error setting symlink: file is not a symlink"
msgstr "Fel vid inställning av symbolisk länk: filen är inte en symbolisk länk"
-#: gio/glocalfileinfo.c:2630
+#: gio/glocalfileinfo.c:2637
#, c-format
msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative"
msgstr "Extra nanosekunder %d för UNIX-tidsstämpeln %lld är negativa"
-#: gio/glocalfileinfo.c:2639
+#: gio/glocalfileinfo.c:2646
#, c-format
msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second"
msgstr "Extra nanosekunder %d för UNIX-tidsstämpeln %lld överstiger 1 sekund"
-#: gio/glocalfileinfo.c:2649
+#: gio/glocalfileinfo.c:2656
#, c-format
msgid "UNIX timestamp %lld does not fit into 64 bits"
msgstr "UNIX-tidstämpeln %lld ryms inte i 64 bitar"
-#: gio/glocalfileinfo.c:2660
+#: gio/glocalfileinfo.c:2667
#, c-format
msgid "UNIX timestamp %lld is outside of the range supported by Windows"
msgstr "UNIX-tidstämpeln %lld är utanför intervallet som stöds av Windows"
-#: gio/glocalfileinfo.c:2792
+#: gio/glocalfileinfo.c:2799
#, c-format
msgid "File name “%s” cannot be converted to UTF-16"
msgstr "Filnamnet ”%s” kan inte konverteras till UTF-16"
-#: gio/glocalfileinfo.c:2811
+#: gio/glocalfileinfo.c:2818
#, c-format
msgid "File “%s” cannot be opened: Windows Error %lu"
msgstr "Filen ”%s” kan inte öppnas: Windows-fel %lu"
-#: gio/glocalfileinfo.c:2824
+#: gio/glocalfileinfo.c:2831
#, c-format
msgid "Error setting modification or access time for file “%s”: %lu"
msgstr "Fel vid inställning av ändrings- eller åtkomsttid för filen ”%s”: %lu"
-#: gio/glocalfileinfo.c:2981
+#: gio/glocalfileinfo.c:2988
#, c-format
msgid "Error setting modification or access time: %s"
msgstr "Fel vid inställning av ändrings- eller åtkomsttid: %s"
-#: gio/glocalfileinfo.c:3004
+#: gio/glocalfileinfo.c:3011
msgid "SELinux context must be non-NULL"
msgstr "SELinux-kontext måste vara icke-NULL"
-#: gio/glocalfileinfo.c:3011
+#: gio/glocalfileinfo.c:3018
msgid "SELinux is not enabled on this system"
msgstr "SELinux är inte aktiverat på detta system"
-#: gio/glocalfileinfo.c:3021
+#: gio/glocalfileinfo.c:3028
#, c-format
msgid "Error setting SELinux context: %s"
msgstr "Fel vid inställning av SELinux-kontext: %s"
-#: gio/glocalfileinfo.c:3118
+#: gio/glocalfileinfo.c:3125
#, c-format
msgid "Setting attribute %s not supported"
msgstr "Inställning av attributet %s stöds inte"
@@ -3508,8 +3513,8 @@ msgstr "Ogiltig domän"
#: gio/gresource.c:683 gio/gresource.c:945 gio/gresource.c:985
#: gio/gresource.c:1109 gio/gresource.c:1181 gio/gresource.c:1255
-#: gio/gresource.c:1336 gio/gresourcefile.c:478 gio/gresourcefile.c:601
-#: gio/gresourcefile.c:752
+#: gio/gresource.c:1336 gio/gresourcefile.c:478 gio/gresourcefile.c:602
+#: gio/gresourcefile.c:753
#, c-format
msgid "The resource at “%s” does not exist"
msgstr "Resursen på ”%s” finns inte"
@@ -3519,16 +3524,16 @@ msgstr "Resursen på ”%s” finns inte"
msgid "The resource at “%s” failed to decompress"
msgstr "Resursen på ”%s” gick inte att dekomprimera"
-#: gio/gresourcefile.c:658
+#: gio/gresourcefile.c:659
msgid "Resource files cannot be renamed"
msgstr "Resursfiler går inte att byta namn på"
-#: gio/gresourcefile.c:748
+#: gio/gresourcefile.c:749
#, c-format
msgid "The resource at “%s” is not a directory"
msgstr "Resursen på ”%s” är inte en katalog"
-#: gio/gresourcefile.c:956
+#: gio/gresourcefile.c:957
msgid "Input stream doesn’t implement seek"
msgstr "Inmatningsströmmen har inte implementerat spolning"
@@ -3893,7 +3898,7 @@ msgstr "Ogiltigt uttag, initiering misslyckades på grund av: %s"
msgid "Socket is already closed"
msgstr "Uttaget är redan stängt"
-#: gio/gsocket.c:449 gio/gsocket.c:3201 gio/gsocket.c:4434 gio/gsocket.c:4492
+#: gio/gsocket.c:449 gio/gsocket.c:3225 gio/gsocket.c:4458 gio/gsocket.c:4516
msgid "Socket I/O timed out"
msgstr "Tidsgräns för in/ut på uttaget överstegs"
@@ -3987,74 +3992,74 @@ msgstr "Inget stöd för IPv4-källspecifik multicast"
msgid "No support for IPv6 source-specific multicast"
msgstr "Inget stöd för IPv6-källspecifik multicast"
-#: gio/gsocket.c:2900
+#: gio/gsocket.c:2924
#, c-format
msgid "Error accepting connection: %s"
msgstr "Fel vid godkännande av anslutning: %s"
-#: gio/gsocket.c:3026
+#: gio/gsocket.c:3050
msgid "Connection in progress"
msgstr "Anslutningsförsök pågår"
-#: gio/gsocket.c:3077
+#: gio/gsocket.c:3101
msgid "Unable to get pending error: "
msgstr "Kunde inte få tag på väntande fel: "
-#: gio/gsocket.c:3266
+#: gio/gsocket.c:3290
#, c-format
msgid "Error receiving data: %s"
msgstr "Fel vid mottagning av data: %s"
-#: gio/gsocket.c:3463
+#: gio/gsocket.c:3487
#, c-format
msgid "Error sending data: %s"
msgstr "Fel vid sändning av data: %s"
-#: gio/gsocket.c:3650
+#: gio/gsocket.c:3674
#, c-format
msgid "Unable to shutdown socket: %s"
msgstr "Kunde inte stänga ner uttag: %s"
-#: gio/gsocket.c:3731
+#: gio/gsocket.c:3755
#, c-format
msgid "Error closing socket: %s"
msgstr "Fel vid stängning av uttag: %s"
-#: gio/gsocket.c:4427
+#: gio/gsocket.c:4451
#, c-format
msgid "Waiting for socket condition: %s"
msgstr "Väntar på uttagstillstånd: %s"
-#: gio/gsocket.c:4817 gio/gsocket.c:4833 gio/gsocket.c:4846
+#: gio/gsocket.c:4841 gio/gsocket.c:4857 gio/gsocket.c:4870
#, c-format
msgid "Unable to send message: %s"
msgstr "Kunde inte skicka meddelande: %s"
-#: gio/gsocket.c:4818 gio/gsocket.c:4834 gio/gsocket.c:4847
+#: gio/gsocket.c:4842 gio/gsocket.c:4858 gio/gsocket.c:4871
msgid "Message vectors too large"
msgstr "Meddelandevektorerna är för stora"
-#: gio/gsocket.c:4863 gio/gsocket.c:4865 gio/gsocket.c:5012 gio/gsocket.c:5097
-#: gio/gsocket.c:5275 gio/gsocket.c:5315 gio/gsocket.c:5317
+#: gio/gsocket.c:4887 gio/gsocket.c:4889 gio/gsocket.c:5036 gio/gsocket.c:5121
+#: gio/gsocket.c:5299 gio/gsocket.c:5339 gio/gsocket.c:5341
#, c-format
msgid "Error sending message: %s"
msgstr "Fel vid sändning av meddelande: %s"
-#: gio/gsocket.c:5039
+#: gio/gsocket.c:5063
msgid "GSocketControlMessage not supported on Windows"
msgstr "GSocketControlMessage stöds inte på Windows"
-#: gio/gsocket.c:5512 gio/gsocket.c:5588 gio/gsocket.c:5814
+#: gio/gsocket.c:5536 gio/gsocket.c:5612 gio/gsocket.c:5838
#, c-format
msgid "Error receiving message: %s"
msgstr "Fel vid mottagning av meddelande: %s"
-#: gio/gsocket.c:6099 gio/gsocket.c:6110 gio/gsocket.c:6173
+#: gio/gsocket.c:6123 gio/gsocket.c:6134 gio/gsocket.c:6197
#, c-format
msgid "Unable to read socket credentials: %s"
msgstr "Kunde inte läsa uttagets inloggningsuppgifter: %s"
-#: gio/gsocket.c:6182
+#: gio/gsocket.c:6206
msgid "g_socket_get_credentials not implemented for this OS"
msgstr ""
"g_socket_get_credentials har inte implementerats för detta operativsystem"
@@ -4177,12 +4182,12 @@ msgstr "SOCKSv5-proxyservern saknar stöd för angiven adresstyp."
msgid "Unknown SOCKSv5 proxy error."
msgstr "Okänt fel i SOCKSv5-proxyserver."
-#: gio/gtestdbus.c:614 glib/gspawn-win32.c:354
+#: gio/gtestdbus.c:615 glib/gspawn-win32.c:354
#, c-format
msgid "Failed to create pipe for communicating with child process (%s)"
msgstr "Misslyckades med att skapa rör för kommunikation med barnprocess (%s)"
-#: gio/gtestdbus.c:621
+#: gio/gtestdbus.c:622
#, c-format
msgid "Pipes are not supported in this platform"
msgstr "Rör stöds inte på denna plattform"
@@ -5092,15 +5097,15 @@ msgstr "Kanalen slutar med ett ofullständigt tecken"
msgid "Can’t do a raw read in g_io_channel_read_to_end"
msgstr "Kan inte göra en rå läsning i g_io_channel_read_to_end"
-#: glib/gkeyfile.c:796
+#: glib/gkeyfile.c:800
msgid "Valid key file could not be found in search dirs"
msgstr "Giltig nyckelfil kunde inte hittas i sökkatalogerna"
-#: glib/gkeyfile.c:833
+#: glib/gkeyfile.c:837
msgid "Not a regular file"
msgstr "Inte en vanlig fil"
-#: glib/gkeyfile.c:1291
+#: glib/gkeyfile.c:1295
#, c-format
msgid ""
"Key file contains line “%s” which is not a key-value pair, group, or comment"
@@ -5108,43 +5113,43 @@ msgstr ""
"Nyckelfilen innehåller raden ”%s” som inte är ett nyckel-värde-par, grupp "
"eller kommentar"
-#: glib/gkeyfile.c:1348
+#: glib/gkeyfile.c:1352
#, c-format
msgid "Invalid group name: %s"
msgstr "Ogiltigt gruppnamn: %s"
-#: glib/gkeyfile.c:1372
+#: glib/gkeyfile.c:1376
msgid "Key file does not start with a group"
msgstr "Nyckelfilen börjar inte med en grupp"
-#: glib/gkeyfile.c:1396
+#: glib/gkeyfile.c:1400
#, c-format
msgid "Invalid key name: %.*s"
msgstr "Ogiltigt nyckelnamn: %.*s"
-#: glib/gkeyfile.c:1424
+#: glib/gkeyfile.c:1428
#, c-format
msgid "Key file contains unsupported encoding “%s”"
msgstr "Nyckelfilen innehåller kodningen ”%s” som inte stöds"
-#: glib/gkeyfile.c:1679 glib/gkeyfile.c:1852 glib/gkeyfile.c:3299
-#: glib/gkeyfile.c:3363 glib/gkeyfile.c:3493 glib/gkeyfile.c:3622
-#: glib/gkeyfile.c:3768 glib/gkeyfile.c:4003 glib/gkeyfile.c:4070
+#: glib/gkeyfile.c:1683 glib/gkeyfile.c:1856 glib/gkeyfile.c:3303
+#: glib/gkeyfile.c:3367 glib/gkeyfile.c:3497 glib/gkeyfile.c:3626
+#: glib/gkeyfile.c:3772 glib/gkeyfile.c:4007 glib/gkeyfile.c:4074
#, c-format
msgid "Key file does not have group “%s”"
msgstr "Nyckelfilen har inte gruppen ”%s”"
-#: glib/gkeyfile.c:1807
+#: glib/gkeyfile.c:1811
#, c-format
msgid "Key file does not have key “%s” in group “%s”"
msgstr "Nyckelfilen har inte nyckeln ”%s” i gruppen ”%s”"
-#: glib/gkeyfile.c:1969 glib/gkeyfile.c:2085
+#: glib/gkeyfile.c:1973 glib/gkeyfile.c:2089
#, c-format
msgid "Key file contains key “%s” with value “%s” which is not UTF-8"
msgstr "Nyckelfilen innehåller nyckeln ”%s” med värdet ”%s” som inte är UTF-8"
-#: glib/gkeyfile.c:1989 glib/gkeyfile.c:2105 glib/gkeyfile.c:2544
+#: glib/gkeyfile.c:1993 glib/gkeyfile.c:2109 glib/gkeyfile.c:2548
#, c-format
msgid ""
"Key file contains key “%s” which has a value that cannot be interpreted."
@@ -5152,7 +5157,7 @@ msgstr ""
"Nyckelfilen innehåller nyckeln ”%s” som innehåller ett värde som inte kan "
"tolkas."
-#: glib/gkeyfile.c:2759 glib/gkeyfile.c:3128
+#: glib/gkeyfile.c:2763 glib/gkeyfile.c:3132
#, c-format
msgid ""
"Key file contains key “%s” in group “%s” which has a value that cannot be "
@@ -5161,83 +5166,83 @@ msgstr ""
"Nyckelfilen innehåller nyckeln ”%s” i gruppen ”%s” vilken innehåller ett "
"värde som inte kan tolkas."
-#: glib/gkeyfile.c:2837 glib/gkeyfile.c:2914
+#: glib/gkeyfile.c:2841 glib/gkeyfile.c:2918
#, c-format
msgid "Key “%s” in group “%s” has value “%s” where %s was expected"
msgstr "Nyckeln ”%s” i gruppen ”%s” innehåller värdet ”%s” där %s förväntades"
-#: glib/gkeyfile.c:4323
+#: glib/gkeyfile.c:4327
msgid "Key file contains escape character at end of line"
msgstr "Nyckelfilen innehåller kontrolltecken i slutet på en rad"
-#: glib/gkeyfile.c:4345
+#: glib/gkeyfile.c:4349
#, c-format
msgid "Key file contains invalid escape sequence “%s”"
msgstr "Nyckelfilen innehåller ogiltiga kontrollsekvensen ”%s”"
-#: glib/gkeyfile.c:4490
+#: glib/gkeyfile.c:4494
#, c-format
msgid "Value “%s” cannot be interpreted as a number."
msgstr "Värdet ”%s” kan inte tolkas som ett tal."
-#: glib/gkeyfile.c:4504
+#: glib/gkeyfile.c:4508
#, c-format
msgid "Integer value “%s” out of range"
msgstr "Heltalsvärdet ”%s” är utanför intervallet"
-#: glib/gkeyfile.c:4537
+#: glib/gkeyfile.c:4541
#, c-format
msgid "Value “%s” cannot be interpreted as a float number."
msgstr "Värdet ”%s” kan inte tolkas som ett flyttal."
-#: glib/gkeyfile.c:4576
+#: glib/gkeyfile.c:4580
#, c-format
msgid "Value “%s” cannot be interpreted as a boolean."
msgstr "Värdet ”%s” kan inte tolkas som ett booleskt värde."
-#: glib/gmappedfile.c:131
+#: glib/gmappedfile.c:135
#, c-format
msgid "Failed to get attributes of file “%s%s%s%s”: fstat() failed: %s"
msgstr ""
"Misslyckades med att få attribut för filen ”%s%s%s%s”: fstat() misslyckades: "
"%s"
-#: glib/gmappedfile.c:197
+#: glib/gmappedfile.c:201
#, c-format
msgid "Failed to map %s%s%s%s: mmap() failed: %s"
msgstr "Misslyckades med att mappa %s%s%s%s: mmap() misslyckades: %s"
-#: glib/gmappedfile.c:264
+#: glib/gmappedfile.c:268
#, c-format
msgid "Failed to open file “%s”: open() failed: %s"
msgstr "Misslyckades med att öppna filen ”%s”: open() misslyckades: %s"
-#: glib/gmarkup.c:393 glib/gmarkup.c:435
+#: glib/gmarkup.c:398 glib/gmarkup.c:440
#, c-format
msgid "Error on line %d char %d: "
msgstr "Fel på rad %d tecken %d: "
-#: glib/gmarkup.c:457 glib/gmarkup.c:540
+#: glib/gmarkup.c:462 glib/gmarkup.c:545
#, c-format
msgid "Invalid UTF-8 encoded text in name — not valid “%s”"
msgstr "Ogiltig UTF-8-kodad text i namnet — inte giltig ”%s”"
-#: glib/gmarkup.c:468
+#: glib/gmarkup.c:473
#, c-format
msgid "“%s” is not a valid name"
msgstr "”%s” är inte ett giltigt namn"
-#: glib/gmarkup.c:484
+#: glib/gmarkup.c:489
#, c-format
msgid "“%s” is not a valid name: “%c”"
msgstr "”%s” är inte ett giltigt namn: ”%c”"
-#: glib/gmarkup.c:608
+#: glib/gmarkup.c:613
#, c-format
msgid "Error on line %d: %s"
msgstr "Fel på rad %d: %s"
-#: glib/gmarkup.c:685
+#: glib/gmarkup.c:690
#, c-format
msgid ""
"Failed to parse “%-.*s”, which should have been a digit inside a character "
@@ -5246,7 +5251,7 @@ msgstr ""
"Misslyckades med att tolka ”%-.*s”, som skulle ha varit en siffra inuti en "
"teckenreferens (&#234; till exempel) — siffran är kanske för stor"
-#: glib/gmarkup.c:697
+#: glib/gmarkup.c:702
msgid ""
"Character reference did not end with a semicolon; most likely you used an "
"ampersand character without intending to start an entity — escape ampersand "
@@ -5255,24 +5260,24 @@ msgstr ""
"Teckenreferensen slutade inte med ett semikolon. Troligtvis använde du ett &-"
"tecken utan att avse att starta en entitet. Skriv om &-tecknet som &amp;"
-#: glib/gmarkup.c:723
+#: glib/gmarkup.c:728
#, c-format
msgid "Character reference “%-.*s” does not encode a permitted character"
msgstr "Teckenreferensen ”%-.*s” kodar inte ett tillåtet tecken"
-#: glib/gmarkup.c:761
+#: glib/gmarkup.c:766
msgid ""
"Empty entity “&;” seen; valid entities are: &amp; &quot; &lt; &gt; &apos;"
msgstr ""
"Tom entitet ”&;” hittades, giltiga entiteter är: &amp; &quot; &lt; &gt; "
"&apos;"
-#: glib/gmarkup.c:769
+#: glib/gmarkup.c:774
#, c-format
msgid "Entity name “%-.*s” is not known"
msgstr "Entitetsnamnet ”%-.*s” är okänt"
-#: glib/gmarkup.c:774
+#: glib/gmarkup.c:779
msgid ""
"Entity did not end with a semicolon; most likely you used an ampersand "
"character without intending to start an entity — escape ampersand as &amp;"
@@ -5280,11 +5285,11 @@ msgstr ""
"Entiteten slutade inte med ett semikolon. Troligtvis använde du ett &-tecken "
"utan att avse att starta en entitet. Skriv om &-tecknet som &amp;"
-#: glib/gmarkup.c:1188
+#: glib/gmarkup.c:1193
msgid "Document must begin with an element (e.g. <book>)"
msgstr "Dokumentet måste börja med ett element (exempelvis <book>)"
-#: glib/gmarkup.c:1228
+#: glib/gmarkup.c:1233
#, c-format
msgid ""
"“%s” is not a valid character following a “<” character; it may not begin an "
@@ -5293,7 +5298,7 @@ msgstr ""
"”%s” är inte ett giltigt tecken efter ett ”<”-tecken. Det får inte inleda "
"ett elementnamn"
-#: glib/gmarkup.c:1271
+#: glib/gmarkup.c:1276
#, c-format
msgid ""
"Odd character “%s”, expected a “>” character to end the empty-element tag "
@@ -5302,12 +5307,12 @@ msgstr ""
"Konstigt tecken ”%s”, ett ”>”-tecken förväntades för att avsluta tomma "
"elementtaggen ”%s”"
-#: glib/gmarkup.c:1341
+#: glib/gmarkup.c:1346
#, c-format
msgid "Too many attributes in element “%s”"
msgstr "För många attribut i elementet ”%s”"
-#: glib/gmarkup.c:1361
+#: glib/gmarkup.c:1366
#, c-format
msgid ""
"Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”"
@@ -5315,7 +5320,7 @@ msgstr ""
"Konstigt tecken ”%s”, ett ”=” förväntades efter attributnamnet ”%s” till "
"elementet ”%s”"
-#: glib/gmarkup.c:1403
+#: glib/gmarkup.c:1408
#, c-format
msgid ""
"Odd character “%s”, expected a “>” or “/” character to end the start tag of "
@@ -5326,7 +5331,7 @@ msgstr ""
"starttaggen för elementet ”%s”, eller möjligtvis ett attribut. Du kanske "
"använde ett ogiltigt tecken i ett attributnamn"
-#: glib/gmarkup.c:1448
+#: glib/gmarkup.c:1453
#, c-format
msgid ""
"Odd character “%s”, expected an open quote mark after the equals sign when "
@@ -5335,7 +5340,7 @@ msgstr ""
"Konstigt tecken ”%s”, ett startcitattecken förväntades efter likhetstecknet "
"när värdet av attributet ”%s” till elementet ”%s” tilldelades"
-#: glib/gmarkup.c:1582
+#: glib/gmarkup.c:1587
#, c-format
msgid ""
"“%s” is not a valid character following the characters “</”; “%s” may not "
@@ -5344,7 +5349,7 @@ msgstr ""
"”%s” är inte ett giltigt tecken efter tecknen ”</”. ”%s” får inte inleda ett "
"elementnamn"
-#: glib/gmarkup.c:1620
+#: glib/gmarkup.c:1625
#, c-format
msgid ""
"“%s” is not a valid character following the close element name “%s”; the "
@@ -5353,26 +5358,26 @@ msgstr ""
"”%s” är inte ett giltigt tecken efter stängelementnamnet ”%s”. Det tillåtna "
"tecknet är ”>”"
-#: glib/gmarkup.c:1632
+#: glib/gmarkup.c:1637
#, c-format
msgid "Element “%s” was closed, no element is currently open"
msgstr "Elementet ”%s” stängdes, inget element är öppet för tillfället"
-#: glib/gmarkup.c:1641
+#: glib/gmarkup.c:1646
#, c-format
msgid "Element “%s” was closed, but the currently open element is “%s”"
msgstr ""
"Elementet ”%s” stängdes, men det element som är öppet för tillfället är ”%s”"
-#: glib/gmarkup.c:1794
+#: glib/gmarkup.c:1799
msgid "Document was empty or contained only whitespace"
msgstr "Dokumentet var tomt eller innehöll endast tomrum"
-#: glib/gmarkup.c:1808
+#: glib/gmarkup.c:1813
msgid "Document ended unexpectedly just after an open angle bracket “<”"
msgstr "Dokumentet tog oväntat slut efter ett öppningsklammer ”<”"
-#: glib/gmarkup.c:1816 glib/gmarkup.c:1861
+#: glib/gmarkup.c:1821 glib/gmarkup.c:1866
#, c-format
msgid ""
"Document ended unexpectedly with elements still open — “%s” was the last "
@@ -5381,7 +5386,7 @@ msgstr ""
"Dokumentet tog oväntat slut då element fortfarande var öppna. ”%s” var det "
"senast öppnade elementet"
-#: glib/gmarkup.c:1824
+#: glib/gmarkup.c:1829
#, c-format
msgid ""
"Document ended unexpectedly, expected to see a close angle bracket ending "
@@ -5390,19 +5395,19 @@ msgstr ""
"Dokumentet tog oväntat slut, en stängningsklammer förväntades för att "
"avsluta taggen <%s/>"
-#: glib/gmarkup.c:1830
+#: glib/gmarkup.c:1835
msgid "Document ended unexpectedly inside an element name"
msgstr "Dokumentet tog oväntat slut inuti ett elementnamn"
-#: glib/gmarkup.c:1836
+#: glib/gmarkup.c:1841
msgid "Document ended unexpectedly inside an attribute name"
msgstr "Dokumentet tog oväntat slut inuti ett attributnamn"
-#: glib/gmarkup.c:1841
+#: glib/gmarkup.c:1846
msgid "Document ended unexpectedly inside an element-opening tag."
msgstr "Dokumentet tog oväntat slut inuti en elementöppnande tagg."
-#: glib/gmarkup.c:1847
+#: glib/gmarkup.c:1852
msgid ""
"Document ended unexpectedly after the equals sign following an attribute "
"name; no attribute value"
@@ -5410,22 +5415,22 @@ msgstr ""
"Dokumentet tog oväntat slut efter likhetstecknet som följde ett "
"attributnamn. Inget attributvärde"
-#: glib/gmarkup.c:1854
+#: glib/gmarkup.c:1859
msgid "Document ended unexpectedly while inside an attribute value"
msgstr "Dokumentet tog oväntat slut inuti ett attributvärde"
-#: glib/gmarkup.c:1871
+#: glib/gmarkup.c:1876
#, c-format
msgid "Document ended unexpectedly inside the close tag for element “%s”"
msgstr "Dokumentet tog oväntat slut inuti stängningstaggen för elementet ”%s”"
-#: glib/gmarkup.c:1875
+#: glib/gmarkup.c:1880
msgid ""
"Document ended unexpectedly inside the close tag for an unopened element"
msgstr ""
"Dokumentet tog oväntat slut inuti stängningstaggen för ett oöppnat element"
-#: glib/gmarkup.c:1881
+#: glib/gmarkup.c:1886
msgid "Document ended unexpectedly inside a comment or processing instruction"
msgstr ""
"Dokumentet tog oväntat slut inuti en kommentar eller behandlingsinstruktion"
@@ -5958,21 +5963,21 @@ msgstr ""
"Oväntat fel i g_io_channel_win32_poll() vid inläsning av data från en "
"barnprocess"
-#: glib/gstrfuncs.c:3370 glib/gstrfuncs.c:3472
+#: glib/gstrfuncs.c:3373 glib/gstrfuncs.c:3475
msgid "Empty string is not a number"
msgstr "Tom sträng är inte ett tal"
-#: glib/gstrfuncs.c:3394
+#: glib/gstrfuncs.c:3397
#, c-format
msgid "“%s” is not a signed number"
msgstr "”%s” är inte ett tal med tecken"
-#: glib/gstrfuncs.c:3404 glib/gstrfuncs.c:3508
+#: glib/gstrfuncs.c:3407 glib/gstrfuncs.c:3511
#, c-format
msgid "Number “%s” is out of bounds [%s, %s]"
msgstr "Talet ”%s” är utanför gränserna [%s, %s]"
-#: glib/gstrfuncs.c:3498
+#: glib/gstrfuncs.c:3501
#, c-format
msgid "“%s” is not an unsigned number"
msgstr "”%s” är inte ett teckenlöst tal"
@@ -6273,10 +6278,6 @@ msgstr "%.1f PB"
msgid "%.1f EB"
msgstr "%.1f EB"
-#, c-format
-#~ msgid "edit name: %s\n"
-#~ msgstr "redigeringsnamn: %s\n"
-
#~ msgid "internal error or corrupted object"
#~ msgstr "internt fel eller skadat objekt"
diff --git a/tools/meson.build b/tools/meson.build
index 2d4192e46..e80d4be98 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -17,8 +17,8 @@ endif
if host_system != 'windows'
# Install Valgrind suppression file (except on Windows,
# as Valgrind is currently not supported on Windows)
- install_data('glib.supp',
- install_dir : get_option('datadir') / 'glib-2.0' / 'valgrind',
+ install_data(fs.name(valgrind_suppression_file),
+ install_dir : get_option('datadir') / valgrind_suppression_file_install_subdir,
install_tag : 'devel',
)
endif