summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorHyunjee Kim <hj0426.kim@samsung.com>2019-12-03 10:35:59 +0900
committerHyunjee Kim <hj0426.kim@samsung.com>2019-12-03 10:35:59 +0900
commitaedbffaae7e80f2e7d90374faea486abbc5e57f7 (patch)
treeb32b9c1e815ddc6804f1b96f191688f1dd860802 /gio
parent5de945120591a487ffe65d50419ef336d3fe14d5 (diff)
downloadglib-aedbffaae7e80f2e7d90374faea486abbc5e57f7.tar.gz
glib-aedbffaae7e80f2e7d90374faea486abbc5e57f7.tar.bz2
glib-aedbffaae7e80f2e7d90374faea486abbc5e57f7.zip
Imported Upstream version 2.57.1
Diffstat (limited to 'gio')
-rw-r--r--gio/Makefile.am1
-rw-r--r--gio/gcontenttype.c4
-rw-r--r--gio/gcredentials.c3
-rw-r--r--gio/gdbus-2.0/codegen/codegen.py15
-rwxr-xr-xgio/gdbus-2.0/codegen/codegen_main.py4
-rw-r--r--gio/gdbusaddress.c4
-rw-r--r--gio/gdbusauth.c43
-rw-r--r--gio/gdbusauthmechanismanon.c8
-rw-r--r--gio/gdbusauthmechanismexternal.c19
-rw-r--r--gio/gdbusauthmechanismsha1.c52
-rw-r--r--gio/gdbusconnection.c18
-rw-r--r--gio/gdbusdaemon.c4
-rw-r--r--gio/gdbusmessage.c34
-rw-r--r--gio/gdbusobjectmanagerclient.c2
-rw-r--r--gio/gdbusprivate.c37
-rw-r--r--gio/gdbusprivate.h4
-rw-r--r--gio/gdbusproxy.c2
-rw-r--r--gio/gdesktopappinfo.c31
-rw-r--r--gio/gdocumentportal.c4
-rw-r--r--gio/gfdonotificationbackend.c55
-rw-r--r--gio/gfile.c2
-rw-r--r--gio/gfileattribute.c2
-rw-r--r--gio/gfileinfo.c2
-rw-r--r--gio/gio-tool-mount.c23
-rw-r--r--gio/giomodule.c6
-rw-r--r--gio/glib-compile-resources.c181
-rw-r--r--gio/glib-compile-schemas.c4
-rw-r--r--gio/gliststore.c2
-rw-r--r--gio/glocalfile.c107
-rw-r--r--gio/glocalfileinfo.c30
-rw-r--r--gio/glocalvfs.c13
-rw-r--r--gio/gmenuexporter.c2
-rw-r--r--gio/gnetworkmonitornetlink.c14
-rw-r--r--gio/gnetworkmonitorportal.c251
-rw-r--r--gio/gopenuriportal.c4
-rw-r--r--gio/gregistrysettingsbackend.c2
-rw-r--r--gio/gsettings-mapping.c4
-rw-r--r--gio/gsettings.c27
-rw-r--r--gio/gsimpleaction.c29
-rw-r--r--gio/gsocket.c4
-rw-r--r--gio/gsocketlistener.c19
-rw-r--r--gio/gsubprocess.c7
-rw-r--r--gio/gtestdbus.c3
-rw-r--r--gio/gunixmounts.c72
-rw-r--r--gio/gunixmounts.h2
-rw-r--r--gio/gunixvolume.c9
-rw-r--r--gio/gunixvolumemonitor.c19
-rw-r--r--gio/gunixvolumemonitor.h1
-rw-r--r--gio/gwin32notificationbackend.c90
-rw-r--r--gio/gzlibcompressor.c6
-rw-r--r--gio/gzlibdecompressor.c6
-rw-r--r--gio/inotify/inotify-helper.c2
-rw-r--r--gio/kqueue/Makefile.am10
-rw-r--r--gio/kqueue/dep-list.c54
-rw-r--r--gio/kqueue/gkqueuefilemonitor.c368
-rw-r--r--gio/kqueue/gkqueuefilemonitor.h51
-rw-r--r--gio/kqueue/kqueue-exclusions.c65
-rw-r--r--gio/kqueue/kqueue-exclusions.h28
-rw-r--r--gio/kqueue/kqueue-helper.c380
-rw-r--r--gio/kqueue/kqueue-helper.h31
-rw-r--r--gio/kqueue/kqueue-missing.c53
-rw-r--r--gio/kqueue/kqueue-missing.h32
-rw-r--r--gio/kqueue/kqueue-sub.c79
-rw-r--r--gio/kqueue/kqueue-sub.h50
-rw-r--r--gio/kqueue/kqueue-thread.c304
-rw-r--r--gio/kqueue/kqueue-thread.h45
-rw-r--r--gio/kqueue/kqueue-utils.c210
-rw-r--r--gio/kqueue/kqueue-utils.h53
-rw-r--r--gio/kqueue/meson.build7
-rw-r--r--gio/meson.build72
-rw-r--r--gio/org.freedesktop.portal.NetworkMonitor.xml81
-rw-r--r--gio/tests/Makefile.am3
-rw-r--r--gio/tests/desktop-app-info.c15
-rw-r--r--gio/tests/desktop-files/usr/applications/frobnicator.desktop9
-rw-r--r--gio/tests/desktop-files/usr/applications/gnome-clocks.desktop41
-rwxr-xr-xgio/tests/desktop-files/usr/applications/org.gnome.clocks.desktop404
-rw-r--r--gio/tests/file.c8
-rw-r--r--gio/tests/fileattributematcher.c12
-rw-r--r--gio/tests/g-file-info-filesystem-readonly.c10
-rw-r--r--gio/tests/gdbus-addresses.c79
-rw-r--r--gio/tests/gdbus-connection-slow.c2
-rw-r--r--gio/tests/gdbus-serialization.c196
-rw-r--r--gio/tests/gengiotypefuncs.py6
-rw-r--r--gio/tests/glistmodel.c537
-rw-r--r--gio/tests/gschema-compile.c6
-rw-r--r--gio/tests/gsettings.c46
-rw-r--r--gio/tests/gsubprocess.c258
-rw-r--r--gio/tests/meson.build3
-rw-r--r--gio/tests/network-address.c6
-rw-r--r--gio/tests/network-monitor-race.c2
-rw-r--r--gio/tests/org.gtk.test.gschema.xml.orig4
-rw-r--r--gio/tests/pollable.c2
-rw-r--r--gio/tests/send-data.c6
-rw-r--r--gio/tests/simple-proxy.c14
-rw-r--r--gio/tests/socket-client.c2
-rw-r--r--gio/tests/unix-mounts.c6
-rw-r--r--gio/xdgmime/xdgmime.c18
-rw-r--r--gio/xdgmime/xdgmime.h6
-rw-r--r--gio/xdgmime/xdgmimecache.c9
-rw-r--r--gio/xdgmime/xdgmimeint.c15
-rw-r--r--gio/xdgmime/xdgmimeint.h1
101 files changed, 2252 insertions, 2736 deletions
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 16c638732..df4f24014 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -334,6 +334,7 @@ win32_actual_sources = \
gwin32networking.h \
gwin32networkmonitor.c \
gwin32networkmonitor.h \
+ gwin32notificationbackend.c \
$(NULL)
win32_more_sources_for_vcproj = \
diff --git a/gio/gcontenttype.c b/gio/gcontenttype.c
index 820e54258..af8ef44c6 100644
--- a/gio/gcontenttype.c
+++ b/gio/gcontenttype.c
@@ -1052,7 +1052,7 @@ read_tree_magic_from_directory (const gchar *prefix)
}
else
{
- g_warning ("%s: header corrupt; skipping\n", filename);
+ g_warning ("%s: header corrupt; skipping", filename);
break;
}
}
@@ -1060,7 +1060,7 @@ read_tree_magic_from_directory (const gchar *prefix)
g_strfreev (lines);
}
else
- g_warning ("%s: header not found, skipping\n", filename);
+ g_warning ("%s: header not found, skipping", filename);
g_free (text);
}
diff --git a/gio/gcredentials.c b/gio/gcredentials.c
index 2e050776c..cc0cd82ce 100644
--- a/gio/gcredentials.c
+++ b/gio/gcredentials.c
@@ -95,7 +95,10 @@ struct _GCredentials
ucred_t *native;
#else
#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic warning "-Wcpp"
#warning Please add GCredentials support for your OS
+ #pragma GCC diagnostic pop
#endif
#endif
};
diff --git a/gio/gdbus-2.0/codegen/codegen.py b/gio/gdbus-2.0/codegen/codegen.py
index d98f8973b..032a29ed5 100644
--- a/gio/gdbus-2.0/codegen/codegen.py
+++ b/gio/gdbus-2.0/codegen/codegen.py
@@ -29,7 +29,7 @@ from . import dbustypes
from .utils import print_error
LICENSE_STR = '''/*
- * Generated by gdbus-codegen {!s}. DO NOT EDIT.
+ * Generated by gdbus-codegen {!s} from {!s}. DO NOT EDIT.
*
* The license of this code is the same as for the D-Bus interface description
* it was derived from.
@@ -53,19 +53,22 @@ def generate_namespace(namespace):
class HeaderCodeGenerator:
def __init__(self, ifaces, namespace, generate_objmanager,
- generate_autocleanup, header_name, use_pragma, outfile):
+ generate_autocleanup, header_name, input_files_basenames,
+ use_pragma, outfile):
self.ifaces = ifaces
self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
self.generate_objmanager = generate_objmanager
self.generate_autocleanup = generate_autocleanup
self.header_guard = header_name.upper().replace('.', '_').replace('-', '_').replace('/', '_').replace(':', '_')
+ self.input_files_basenames = input_files_basenames
self.use_pragma = use_pragma
self.outfile = outfile
# ----------------------------------------------------------------------------------------------------
def generate_header_preamble(self):
- self.outfile.write(LICENSE_STR.format(config.VERSION))
+ basenames = ', '.join(self.input_files_basenames)
+ self.outfile.write(LICENSE_STR.format(config.VERSION, basenames))
self.outfile.write('\n')
if self.use_pragma:
@@ -612,18 +615,20 @@ class HeaderCodeGenerator:
class CodeGenerator:
def __init__(self, ifaces, namespace, generate_objmanager, header_name,
- docbook_gen, outfile):
+ input_files_basenames, docbook_gen, outfile):
self.ifaces = ifaces
self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
self.generate_objmanager = generate_objmanager
self.header_name = header_name
+ self.input_files_basenames = input_files_basenames
self.docbook_gen = docbook_gen
self.outfile = outfile
# ----------------------------------------------------------------------------------------------------
def generate_body_preamble(self):
- self.outfile.write(LICENSE_STR.format(config.VERSION))
+ basenames = ', '.join(self.input_files_basenames)
+ self.outfile.write(LICENSE_STR.format(config.VERSION, basenames))
self.outfile.write('\n')
self.outfile.write('#ifdef HAVE_CONFIG_H\n'
'# include "config.h"\n'
diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py
index 1cfe7c1bb..65876a2e8 100755
--- a/gio/gdbus-2.0/codegen/codegen_main.py
+++ b/gio/gdbus-2.0/codegen/codegen_main.py
@@ -212,11 +212,13 @@ def codegen_main():
header_name = os.path.splitext(os.path.basename(c_file))[0] + '.h'
all_ifaces = []
+ input_files_basenames = []
for fname in args.files + args.xml_files:
with open(fname, 'rb') as f:
xml_data = f.read()
parsed_ifaces = parser.parse_dbus_xml(xml_data)
all_ifaces.extend(parsed_ifaces)
+ input_files_basenames.append(os.path.basename(fname))
if args.annotate != None:
apply_annotations(all_ifaces, args.annotate)
@@ -236,6 +238,7 @@ def codegen_main():
args.c_generate_object_manager,
args.c_generate_autocleanup,
header_name,
+ input_files_basenames,
args.pragma_once,
outfile)
gen.generate()
@@ -246,6 +249,7 @@ def codegen_main():
args.c_namespace,
args.c_generate_object_manager,
header_name,
+ input_files_basenames,
docbook_gen,
outfile)
gen.generate()
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index f377378ec..2191c115a 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -418,10 +418,6 @@ g_dbus_is_supported_address (const gchar *string,
supported = is_valid_nonce_tcp (a[n], key_value_pairs, error);
else if (g_strcmp0 (a[n], "autolaunch:") == 0)
supported = TRUE;
- else
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Unknown or unsupported transport “%s” for address “%s”"),
- transport_name, a[n]);
g_free (transport_name);
g_hash_table_unref (key_value_pairs);
diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c
index 1a0ada5bf..1f8ea8057 100644
--- a/gio/gdbusauth.c
+++ b/gio/gdbusauth.c
@@ -365,12 +365,6 @@ _my_g_input_stream_read_line_safe (GInputStream *i,
/* ---------------------------------------------------------------------------------------------------- */
-static void
-append_nibble (GString *s, gint val)
-{
- g_string_append_c (s, val >= 10 ? ('a' + val - 10) : ('0' + val));
-}
-
static gchar *
hexdecode (const gchar *str,
gsize *out_len,
@@ -404,38 +398,17 @@ hexdecode (const gchar *str,
g_string_append_c (s, value);
}
+ *out_len = s->len;
ret = g_string_free (s, FALSE);
s = NULL;
out:
if (s != NULL)
- g_string_free (s, TRUE);
- return ret;
-}
-
-/* TODO: take len */
-static gchar *
-hexencode (const gchar *str)
-{
- guint n;
- GString *s;
-
- s = g_string_new (NULL);
- for (n = 0; str[n] != '\0'; n++)
{
- gint val;
- gint upper_nibble;
- gint lower_nibble;
-
- val = ((const guchar *) str)[n];
- upper_nibble = val >> 4;
- lower_nibble = val & 0x0f;
-
- append_nibble (s, upper_nibble);
- append_nibble (s, lower_nibble);
+ *out_len = 0;
+ g_string_free (s, TRUE);
}
-
- return g_string_free (s, FALSE);
+ return ret;
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -532,7 +505,7 @@ client_choose_mech_and_send_initial_response (GDBusAuth *auth,
goto again;
}
- initial_response_len = -1;
+ initial_response_len = 0;
initial_response = _g_dbus_auth_mechanism_client_initiate (mech,
&initial_response_len);
#if 0
@@ -544,7 +517,7 @@ client_choose_mech_and_send_initial_response (GDBusAuth *auth,
if (initial_response != NULL)
{
//g_printerr ("initial_response = '%s'\n", initial_response);
- encoded = hexencode (initial_response);
+ encoded = _g_dbus_hexencode (initial_response, initial_response_len);
s = g_strdup_printf ("AUTH %s %s\r\n",
_g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype),
encoded);
@@ -836,7 +809,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth,
gsize data_len;
gchar *encoded_data;
data = _g_dbus_auth_mechanism_client_data_send (mech, &data_len);
- encoded_data = hexencode (data);
+ encoded_data = _g_dbus_hexencode (data, data_len);
s = g_strdup_printf ("DATA %s\r\n", encoded_data);
g_free (encoded_data);
g_free (data);
@@ -1211,7 +1184,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth,
{
gchar *encoded_data;
- encoded_data = hexencode (data);
+ encoded_data = _g_dbus_hexencode (data, data_len);
s = g_strdup_printf ("DATA %s\r\n", encoded_data);
g_free (encoded_data);
g_free (data);
diff --git a/gio/gdbusauthmechanismanon.c b/gio/gdbusauthmechanismanon.c
index a166ede01..dd57826ff 100644
--- a/gio/gdbusauthmechanismanon.c
+++ b/gio/gdbusauthmechanismanon.c
@@ -262,6 +262,7 @@ mechanism_client_initiate (GDBusAuthMechanism *mechanism,
gsize *out_initial_response_len)
{
GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
+ gchar *result;
g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), NULL);
g_return_val_if_fail (!m->priv->is_server && !m->priv->is_client, NULL);
@@ -269,10 +270,11 @@ mechanism_client_initiate (GDBusAuthMechanism *mechanism,
m->priv->is_client = TRUE;
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
- *out_initial_response_len = -1;
-
/* just return our library name and version */
- return g_strdup ("GDBus 0.1");
+ result = g_strdup ("GDBus 0.1");
+ *out_initial_response_len = strlen (result);
+
+ return result;
}
static void
diff --git a/gio/gdbusauthmechanismexternal.c b/gio/gdbusauthmechanismexternal.c
index a4473a443..182c57278 100644
--- a/gio/gdbusauthmechanismexternal.c
+++ b/gio/gdbusauthmechanismexternal.c
@@ -177,7 +177,8 @@ mechanism_server_get_state (GDBusAuthMechanism *mechanism)
}
static gboolean
-data_matches_credentials (const gchar *data,
+data_matches_credentials (const gchar *data,
+ gsize data_len,
GCredentials *credentials)
{
gboolean match;
@@ -187,7 +188,7 @@ data_matches_credentials (const gchar *data,
if (credentials == NULL)
goto out;
- if (data == NULL || strlen (data) == 0)
+ if (data == NULL || data_len == 0)
goto out;
#if defined(G_OS_UNIX)
@@ -227,7 +228,9 @@ mechanism_server_initiate (GDBusAuthMechanism *mechanism,
if (initial_response != NULL)
{
- if (data_matches_credentials (initial_response, _g_dbus_auth_mechanism_get_credentials (mechanism)))
+ if (data_matches_credentials (initial_response,
+ initial_response_len,
+ _g_dbus_auth_mechanism_get_credentials (mechanism)))
{
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
}
@@ -253,7 +256,9 @@ mechanism_server_data_receive (GDBusAuthMechanism *mechanism,
g_return_if_fail (m->priv->is_server && !m->priv->is_client);
g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA);
- if (data_matches_credentials (data, _g_dbus_auth_mechanism_get_credentials (mechanism)))
+ if (data_matches_credentials (data,
+ data_len,
+ _g_dbus_auth_mechanism_get_credentials (mechanism)))
{
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
}
@@ -332,7 +337,7 @@ mechanism_client_initiate (GDBusAuthMechanism *mechanism,
m->priv->is_client = TRUE;
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
- *out_initial_response_len = -1;
+ *out_initial_response_len = 0;
credentials = _g_dbus_auth_mechanism_get_credentials (mechanism);
g_assert (credentials != NULL);
@@ -340,9 +345,13 @@ mechanism_client_initiate (GDBusAuthMechanism *mechanism,
/* return the uid */
#if defined(G_OS_UNIX)
initial_response = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) g_credentials_get_unix_user (credentials, NULL));
+ *out_initial_response_len = strlen (initial_response);
#elif defined(G_OS_WIN32)
#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic warning "-Wcpp"
#warning Dont know how to send credentials on this OS. The EXTERNAL D-Bus authentication mechanism will not work.
+#pragma GCC diagnostic pop
#endif
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
#endif
diff --git a/gio/gdbusauthmechanismsha1.c b/gio/gdbusauthmechanismsha1.c
index 0cbaf946d..aba9cea59 100644
--- a/gio/gdbusauthmechanismsha1.c
+++ b/gio/gdbusauthmechanismsha1.c
@@ -280,7 +280,10 @@ ensure_keyring_directory (GError **error)
}
#else
#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic warning "-Wcpp"
#warning Please implement permission checking on this non-UNIX platform
+#pragma GCC diagnostic pop
#endif
#endif
}
@@ -307,42 +310,6 @@ out:
/* ---------------------------------------------------------------------------------------------------- */
-static void
-append_nibble (GString *s, gint val)
-{
- g_string_append_c (s, val >= 10 ? ('a' + val - 10) : ('0' + val));
-}
-
-static gchar *
-hexencode (const gchar *str,
- gssize len)
-{
- guint n;
- GString *s;
-
- if (len == -1)
- len = strlen (str);
-
- s = g_string_new (NULL);
- for (n = 0; n < len; n++)
- {
- gint val;
- gint upper_nibble;
- gint lower_nibble;
-
- val = ((const guchar *) str)[n];
- upper_nibble = val >> 4;
- lower_nibble = val & 0x0f;
-
- append_nibble (s, upper_nibble);
- append_nibble (s, lower_nibble);
- }
-
- return g_string_free (s, FALSE);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
/* looks up an entry in the keyring */
static gchar *
keyring_lookup_entry (const gchar *cookie_context,
@@ -836,7 +803,7 @@ keyring_generate_entry (const gchar *cookie_context,
gchar *raw_cookie;
*out_id = max_line_id + 1;
raw_cookie = random_blob (32);
- *out_cookie = hexencode (raw_cookie, 32);
+ *out_cookie = _g_dbus_hexencode (raw_cookie, 32);
g_free (raw_cookie);
g_string_append_printf (new_contents,
@@ -949,7 +916,7 @@ mechanism_server_initiate (GDBusAuthMechanism *mechanism,
m->priv->is_server = TRUE;
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
- if (initial_response != NULL && strlen (initial_response) > 0)
+ if (initial_response != NULL && initial_response_len > 0)
{
#ifdef G_OS_UNIX
gint64 uid;
@@ -1035,6 +1002,7 @@ mechanism_server_data_send (GDBusAuthMechanism *mechanism,
g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL);
s = NULL;
+ *out_data_len = 0;
/* TODO: use GDBusAuthObserver here to get the cookie context to use? */
cookie_context = "org_gtk_gdbus_general";
@@ -1057,6 +1025,7 @@ mechanism_server_data_send (GDBusAuthMechanism *mechanism,
cookie_context,
cookie_id,
m->priv->server_challenge);
+ *out_data_len = strlen (s);
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA;
@@ -1116,12 +1085,14 @@ mechanism_client_initiate (GDBusAuthMechanism *mechanism,
m->priv->is_client = TRUE;
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA;
- *out_initial_response_len = -1;
+ *out_initial_response_len = 0;
#ifdef G_OS_UNIX
initial_response = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) getuid ());
+ *out_initial_response_len = strlen (initial_response);
#elif defined (G_OS_WIN32)
-initial_response = _g_dbus_win32_get_user_sid ();
+ initial_response = _g_dbus_win32_get_user_sid ();
+ *out_initial_response_len = strlen (initial_response);
#else
#error Please implement for your OS
#endif
@@ -1208,6 +1179,7 @@ mechanism_client_data_send (GDBusAuthMechanism *mechanism,
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
+ *out_data_len = strlen (m->priv->to_send);
return g_strdup (m->priv->to_send);
}
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 6f7e5fefc..ae463e430 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -1500,7 +1500,7 @@ sync_close_cb (GObject *source_object,
* @cancellable: (nullable): a #GCancellable or %NULL
* @error: return location for error or %NULL
*
- * Synchronously closees @connection. The calling thread is blocked
+ * Synchronously closes @connection. The calling thread is blocked
* until this is done. See g_dbus_connection_close() for the
* asynchronous version of this method and more details about what it
* does.
@@ -7233,6 +7233,22 @@ _g_bus_get_singleton_if_exists (GBusType bus_type)
return ret;
}
+/* May be called from any thread. Must not hold message_bus_lock. */
+void
+_g_bus_forget_singleton (GBusType bus_type)
+{
+ GWeakRef *singleton;
+
+ G_LOCK (message_bus_lock);
+
+ singleton = message_bus_get_singleton (bus_type, NULL);
+
+ if (singleton != NULL)
+ g_weak_ref_set (singleton, NULL);
+
+ G_UNLOCK (message_bus_lock);
+}
+
/**
* g_bus_get_sync:
* @bus_type: a #GBusType
diff --git a/gio/gdbusdaemon.c b/gio/gdbusdaemon.c
index 2e67b5d67..3516183f9 100644
--- a/gio/gdbusdaemon.c
+++ b/gio/gdbusdaemon.c
@@ -204,7 +204,7 @@ name_lookup (GDBusDaemon *daemon, const char *str)
}
static gboolean
-is_key (const char *key_start, const char *key_end, char *value)
+is_key (const char *key_start, const char *key_end, const char *value)
{
gsize len = strlen (value);
@@ -1463,7 +1463,7 @@ filter_function (GDBusConnection *connection,
gpointer user_data)
{
Client *client = user_data;
- char *types[] = {"invalid", "method_call", "method_return", "error", "signal" };
+ const char *types[] = {"invalid", "method_call", "method_return", "error", "signal" };
if (0)
g_printerr ("%s%s %s %d(%d) sender: %s destination: %s %s %s.%s\n",
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index 04bcf776f..be001ae55 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -983,10 +983,7 @@ g_dbus_message_set_serial (GDBusMessage *message,
*
* Gets a header field on @message.
*
- * The caller is responsible for checking the type of the returned #GVariant
- * matches what is expected.
- *
- * Returns: (transfer none) (nullable): A #GVariant with the value if the header was found, %NULL
+ * Returns: A #GVariant with the value if the header was found, %NULL
* otherwise. Do not free, it is owned by @message.
*
* Since: 2.26
@@ -1844,11 +1841,8 @@ parse_value_from_blob (GMemoryBuffer *buf,
sig = read_string (buf, (gsize) siglen, &local_error);
if (sig == NULL)
goto fail;
- if (!g_variant_is_signature (sig) ||
- !g_variant_type_string_is_valid (sig))
+ if (!g_variant_is_signature (sig))
{
- /* A D-Bus signature can contain zero or more complete types,
- * but a GVariant has to be exactly one complete type. */
g_set_error (&local_error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
@@ -1930,7 +1924,7 @@ parse_value_from_blob (GMemoryBuffer *buf,
/**
* g_dbus_message_bytes_needed:
- * @blob: (array length=blob_len) (element-type guint8): A blob representing a binary D-Bus message.
+ * @blob: (array length=blob_len) (element-type guint8): A blob represent a binary D-Bus message.
* @blob_len: The length of @blob (must be at least 16).
* @error: Return location for error or %NULL.
*
@@ -2007,9 +2001,6 @@ g_dbus_message_bytes_needed (guchar *blob,
* order that the message was in can be retrieved using
* g_dbus_message_get_byte_order().
*
- * If the @blob cannot be parsed, contains invalid fields, or contains invalid
- * headers, %G_IO_ERROR_INVALID_ARGUMENT will be returned.
- *
* Returns: A new #GDBusMessage or %NULL if @error is set. Free with
* g_object_unref().
*
@@ -2122,15 +2113,6 @@ g_dbus_message_new_from_blob (guchar *blob,
const gchar *signature_str;
gsize signature_str_len;
- if (!g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE))
- {
- g_set_error_literal (error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- _("Signature header found but is not of type signature"));
- goto out;
- }
-
signature_str = g_variant_get_string (signature, &signature_str_len);
/* signature but no body */
@@ -2711,16 +2693,6 @@ g_dbus_message_to_blob (GDBusMessage *message,
body_start_offset = mbuf.valid_len;
signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
-
- if (signature != NULL && !g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE))
- {
- g_set_error_literal (error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- _("Signature header found but is not of type signature"));
- goto out;
- }
-
signature_str = NULL;
if (signature != NULL)
signature_str = g_variant_get_string (signature, NULL);
diff --git a/gio/gdbusobjectmanagerclient.c b/gio/gdbusobjectmanagerclient.c
index 08c94d506..6a59c28b4 100644
--- a/gio/gdbusobjectmanagerclient.c
+++ b/gio/gdbusobjectmanagerclient.c
@@ -531,7 +531,7 @@ g_dbus_object_manager_client_class_init (GDBusObjectManagerClientClass *klass)
* @manager: The #GDBusObjectManagerClient emitting the signal.
* @object_proxy: The #GDBusObjectProxy on which an interface has properties that are changing.
* @interface_proxy: The #GDBusProxy that has properties that are changing.
- * @changed_properties: A #GVariant containing the properties that changed.
+ * @changed_properties: A #GVariant containing the properties that changed (type: `a{sv}`).
* @invalidated_properties: (array zero-terminated=1) (element-type utf8): A %NULL terminated
* array of properties that were invalidated.
*
diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c
index 288c31f40..b5f8b6509 100644
--- a/gio/gdbusprivate.c
+++ b/gio/gdbusprivate.c
@@ -752,7 +752,7 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream,
g_warning ("Error decoding D-Bus message of %" G_GSIZE_FORMAT " bytes\n"
"The error is: %s\n"
"The payload is as follows:\n"
- "%s\n",
+ "%s",
worker->read_buffer_cur_size,
error->message,
s);
@@ -2232,3 +2232,38 @@ _g_signal_accumulator_false_handled (GSignalInvocationHint *ihint,
return continue_emission;
}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+append_nibble (GString *s, gint val)
+{
+ g_string_append_c (s, val >= 10 ? ('a' + val - 10) : ('0' + val));
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+gchar *
+_g_dbus_hexencode (const gchar *str,
+ gsize str_len)
+{
+ gsize n;
+ GString *s;
+
+ s = g_string_new (NULL);
+ for (n = 0; n < str_len; n++)
+ {
+ gint val;
+ gint upper_nibble;
+ gint lower_nibble;
+
+ val = ((const guchar *) str)[n];
+ upper_nibble = val >> 4;
+ lower_nibble = val & 0x0f;
+
+ append_nibble (s, upper_nibble);
+ append_nibble (s, lower_nibble);
+ }
+
+ return g_string_free (s, FALSE);
+}
diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h
index 6a6a08014..0d85c1d85 100644
--- a/gio/gdbusprivate.h
+++ b/gio/gdbusprivate.h
@@ -141,8 +141,12 @@ void _g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy,
void _g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy,
const gchar *interface_name);
+gchar *_g_dbus_hexencode (const gchar *str,
+ gsize str_len);
+
/* Implemented in gdbusconnection.c */
GDBusConnection *_g_bus_get_singleton_if_exists (GBusType bus_type);
+void _g_bus_forget_singleton (GBusType bus_type);
G_END_DECLS
diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c
index 38ccd285a..ae7058371 100644
--- a/gio/gdbusproxy.c
+++ b/gio/gdbusproxy.c
@@ -572,7 +572,7 @@ g_dbus_proxy_class_init (GDBusProxyClass *klass)
/**
* GDBusProxy::g-properties-changed:
* @proxy: The #GDBusProxy emitting the signal.
- * @changed_properties: A #GVariant containing the properties that changed
+ * @changed_properties: A #GVariant containing the properties that changed (type: `a{sv}`)
* @invalidated_properties: A %NULL terminated array of properties that was invalidated
*
* Emitted when one or more D-Bus properties on @proxy changes. The
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index 26bc53bd5..a2aa760c7 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -387,6 +387,22 @@ const gchar desktop_key_match_category[N_DESKTOP_KEYS] = {
[DESKTOP_KEY_Comment] = 6
};
+/* Common prefix commands to ignore from Exec= lines */
+const char * const exec_key_match_blacklist[] = {
+ "bash",
+ "env",
+ "flatpak",
+ "gjs",
+ "pkexec",
+ "python",
+ "python2",
+ "python3",
+ "sh",
+ "wine",
+ "wine64",
+ NULL
+};
+
static gchar *
desktop_key_get_name (guint key_id)
{
@@ -1089,6 +1105,10 @@ desktop_file_dir_unindexed_setup_search (DesktopFileDir *dir)
/* Skip the pathname, if any */
if ((slash = strrchr (raw, '/')))
value = slash + 1;
+
+ /* Don't match on blacklisted binaries like interpreters */
+ if (g_strv_contains (exec_key_match_blacklist, value))
+ value = NULL;
}
if (value)
@@ -1838,7 +1858,7 @@ g_desktop_app_info_load_file (GDesktopAppInfo *self)
*
* Creates a new #GDesktopAppInfo.
*
- * Returns: a new #GDesktopAppInfo or %NULL on error.
+ * Returns: (nullable): a new #GDesktopAppInfo or %NULL on error.
*
* Since: 2.18
**/
@@ -1864,7 +1884,7 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
*
* Creates a new #GDesktopAppInfo.
*
- * Returns: a new #GDesktopAppInfo or %NULL on error.
+ * Returns: (nullable): a new #GDesktopAppInfo or %NULL on error.
**/
GDesktopAppInfo *
g_desktop_app_info_new_from_filename (const char *filename)
@@ -1896,7 +1916,8 @@ g_desktop_app_info_new_from_filename (const char *filename)
* (i.e. a desktop id of kde-foo.desktop will match
* `/usr/share/applications/kde/foo.desktop`).
*
- * Returns: a new #GDesktopAppInfo, or %NULL if no desktop file with that id
+ * Returns: (nullable): a new #GDesktopAppInfo, or %NULL if no desktop
+ * file with that id exists.
*/
GDesktopAppInfo *
g_desktop_app_info_new (const char *desktop_id)
@@ -2886,7 +2907,7 @@ g_desktop_app_info_launch_uris_with_dbus (GDesktopAppInfo *info,
GAppLaunchContext *launch_context)
{
GList *ruris = uris;
- g_autofree char *app_id = NULL;
+ char *app_id = NULL;
g_return_val_if_fail (info != NULL, FALSE);
@@ -2905,6 +2926,8 @@ g_desktop_app_info_launch_uris_with_dbus (GDesktopAppInfo *info,
if (ruris != uris)
g_list_free_full (ruris, g_free);
+ g_free (app_id);
+
return TRUE;
}
diff --git a/gio/gdocumentportal.c b/gio/gdocumentportal.c
index 3e85bd22c..56378b1e6 100644
--- a/gio/gdocumentportal.c
+++ b/gio/gdocumentportal.c
@@ -203,7 +203,7 @@ g_document_portal_add_documents (GList *uris,
{
const char *uri = l->data;
int idx = -1;
- g_autofree char *path = NULL;
+ char *path = NULL;
path = g_filename_from_uri (uri, NULL, NULL);
if (path != NULL)
@@ -221,6 +221,8 @@ g_document_portal_add_documents (GList *uris,
}
}
+ g_free (path);
+
if (idx != -1)
g_variant_builder_add (&builder, "h", idx);
else
diff --git a/gio/gfdonotificationbackend.c b/gio/gfdonotificationbackend.c
index ab5329497..a0d481433 100644
--- a/gio/gfdonotificationbackend.c
+++ b/gio/gfdonotificationbackend.c
@@ -62,6 +62,7 @@ typedef struct
GVariant *default_action_target;
} FreedesktopNotification;
+
static void
freedesktop_notification_free (gpointer data)
{
@@ -76,24 +77,6 @@ freedesktop_notification_free (gpointer data)
}
static FreedesktopNotification *
-freedesktop_notification_new (GFdoNotificationBackend *backend,
- const gchar *id,
- GNotification *notification)
-{
- FreedesktopNotification *n;
-
- n = g_slice_new0 (FreedesktopNotification);
- n->backend = backend;
- n->id = g_strdup (id);
- n->notify_id = 0;
- g_notification_get_default_action (notification,
- &n->default_action,
- &n->default_action_target);
-
- return n;
-}
-
-static FreedesktopNotification *
g_fdo_notification_backend_find_notification (GFdoNotificationBackend *backend,
const gchar *id)
{
@@ -336,19 +319,8 @@ notification_sent (GObject *source_object,
val = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), result, &error);
if (val)
{
- GFdoNotificationBackend *backend = n->backend;
- FreedesktopNotification *match;
-
g_variant_get (val, "(u)", &n->notify_id);
g_variant_unref (val);
-
- match = g_fdo_notification_backend_find_notification_by_notify_id (backend, n->notify_id);
- if (match != NULL)
- {
- backend->notifications = g_slist_remove (backend->notifications, match);
- freedesktop_notification_free (match);
- }
- backend->notifications = g_slist_prepend (backend->notifications, n);
}
else
{
@@ -359,7 +331,9 @@ notification_sent (GObject *source_object,
warning_printed = TRUE;
}
+ n->backend->notifications = g_slist_remove (n->backend->notifications, n);
freedesktop_notification_free (n);
+
g_error_free (error);
}
}
@@ -404,7 +378,7 @@ g_fdo_notification_backend_send_notification (GNotificationBackend *backend,
GNotification *notification)
{
GFdoNotificationBackend *self = G_FDO_NOTIFICATION_BACKEND (backend);
- FreedesktopNotification *n, *tmp;
+ FreedesktopNotification *n;
if (self->notify_subscription == 0)
{
@@ -417,11 +391,24 @@ g_fdo_notification_backend_send_notification (GNotificationBackend *backend,
notify_signal, backend, NULL);
}
- n = freedesktop_notification_new (self, id, notification);
+ n = g_fdo_notification_backend_find_notification (self, id);
+ if (n == NULL)
+ {
+ n = g_slice_new0 (FreedesktopNotification);
+ n->backend = self;
+ n->id = g_strdup (id);
+ n->notify_id = 0;
+
+ n->backend->notifications = g_slist_prepend (n->backend->notifications, n);
+ }
+ else
+ {
+ /* Only clear default action. All other fields are still valid */
+ g_clear_pointer (&n->default_action, g_free);
+ g_clear_pointer (&n->default_action_target, g_variant_unref);
+ }
- tmp = g_fdo_notification_backend_find_notification (self, id);
- if (tmp)
- n->notify_id = tmp->notify_id;
+ g_notification_get_default_action (notification, &n->default_action, &n->default_action_target);
call_notify (backend->dbus_connection, backend->application, n->notify_id, notification, notification_sent, n);
}
diff --git a/gio/gfile.c b/gio/gfile.c
index a67aad383..c17aeb040 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -392,7 +392,7 @@ g_file_default_init (GFileIface *iface)
*
* Checks to see if a file is native to the platform.
*
- * A native file s one expressed in the platform-native filename format,
+ * A native file is one expressed in the platform-native filename format,
* e.g. "C:\Windows" or "/usr/bin/". This does not mean the file is local,
* as it might be on a locally mounted remote filesystem.
*
diff --git a/gio/gfileattribute.c b/gio/gfileattribute.c
index 9b16a765f..c3a8ebf4b 100644
--- a/gio/gfileattribute.c
+++ b/gio/gfileattribute.c
@@ -612,7 +612,7 @@ _g_file_attribute_value_set_from_pointer (GFileAttributeValue *value,
break;
default:
- g_warning ("Unknown type specified in g_file_info_set_attribute\n");
+ g_warning ("Unknown type specified in g_file_info_set_attribute");
break;
}
}
diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c
index be7bef019..a595c6f4a 100644
--- a/gio/gfileinfo.c
+++ b/gio/gfileinfo.c
@@ -1113,7 +1113,7 @@ _g_file_info_set_attribute_by_id (GFileInfo *info,
* @value_p: (not nullable): pointer to the value
*
* Sets the @attribute to contain the given value, if possible. To unset the
- * attribute, use %G_ATTRIBUTE_TYPE_INVALID for @type.
+ * attribute, use %G_FILE_ATTRIBUTE_TYPE_INVALID for @type.
**/
void
g_file_info_set_attribute (GFileInfo *info,
diff --git a/gio/gio-tool-mount.c b/gio/gio-tool-mount.c
index 1f51d7c77..9522713e9 100644
--- a/gio/gio-tool-mount.c
+++ b/gio/gio-tool-mount.c
@@ -39,7 +39,6 @@ typedef enum {
static int outstanding_mounts = 0;
static GMainLoop *main_loop;
-static GVolumeMonitor *volume_monitor;
static gboolean mount_mountable = FALSE;
static gboolean mount_unmount = FALSE;
@@ -814,8 +813,11 @@ list_drives (GList *drives,
static void
list_monitor_items (void)
{
+ GVolumeMonitor *volume_monitor;
GList *drives, *volumes, *mounts;
+ volume_monitor = g_volume_monitor_get();
+
/* populate gvfs network mounts */
iterate_gmain();
@@ -830,14 +832,19 @@ list_monitor_items (void)
mounts = g_volume_monitor_get_mounts (volume_monitor);
list_mounts (mounts, 0, TRUE);
g_list_free_full (mounts, g_object_unref);
+
+ g_object_unref (volume_monitor);
}
static void
unmount_all_with_scheme (const char *scheme)
{
+ GVolumeMonitor *volume_monitor;
GList *mounts;
GList *l;
+ volume_monitor = g_volume_monitor_get();
+
/* populate gvfs network mounts */
iterate_gmain();
@@ -853,6 +860,8 @@ unmount_all_with_scheme (const char *scheme)
g_object_unref (root);
}
g_list_free_full (mounts, g_object_unref);
+
+ g_object_unref (volume_monitor);
}
static void
@@ -903,9 +912,12 @@ mount_with_device_file_cb (GObject *object,
static void
mount_with_device_file (const char *device_file)
{
+ GVolumeMonitor *volume_monitor;
GList *volumes;
GList *l;
+ volume_monitor = g_volume_monitor_get();
+
volumes = g_volume_monitor_get_volumes (volume_monitor);
for (l = volumes; l != NULL; l = l->next)
{
@@ -938,6 +950,8 @@ mount_with_device_file (const char *device_file)
print_error ("%s: %s", device_file, _("No volume for device file"));
success = FALSE;
}
+
+ g_object_unref (volume_monitor);
}
static void
@@ -1091,6 +1105,10 @@ monitor_drive_eject_button (GVolumeMonitor *volume_monitor, GDrive *drive)
static void
monitor (void)
{
+ GVolumeMonitor *volume_monitor;
+
+ volume_monitor = g_volume_monitor_get ();
+
g_signal_connect (volume_monitor, "mount-added", (GCallback) monitor_mount_added, NULL);
g_signal_connect (volume_monitor, "mount-removed", (GCallback) monitor_mount_removed, NULL);
g_signal_connect (volume_monitor, "mount-changed", (GCallback) monitor_mount_changed, NULL);
@@ -1145,7 +1163,6 @@ handle_mount (int argc, char *argv[], gboolean do_help)
g_option_context_free (context);
main_loop = g_main_loop_new (NULL, FALSE);
- volume_monitor = g_volume_monitor_get ();
if (mount_list)
list_monitor_items ();
@@ -1173,7 +1190,5 @@ handle_mount (int argc, char *argv[], gboolean do_help)
if (outstanding_mounts > 0)
g_main_loop_run (main_loop);
- g_object_unref (volume_monitor);
-
return success ? 0 : 2;
}
diff --git a/gio/giomodule.c b/gio/giomodule.c
index 1ead84cf8..30731f7c2 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -722,8 +722,8 @@ try_class (GIOExtension *extension,
* The result is cached after it is generated the first time, and
* the function is thread-safe.
*
- * Returns: (transfer none): an object implementing
- * @extension_point, or %NULL if there are no usable
+ * Returns: (transfer none): the type to instantiate to implement
+ * @extension_point, or %G_TYPE_INVALID if there are no usable
* implementations.
*/
GType
@@ -962,6 +962,7 @@ extern GType g_cocoa_notification_backend_get_type (void);
#endif
#ifdef G_PLATFORM_WIN32
+extern GType g_win32_notification_backend_get_type (void);
#include <windows.h>
extern GType _g_win32_network_monitor_get_type (void);
@@ -1166,6 +1167,7 @@ _g_io_modules_ensure_loaded (void)
g_type_ensure (g_cocoa_notification_backend_get_type ());
#endif
#ifdef G_OS_WIN32
+ g_type_ensure (g_win32_notification_backend_get_type ());
g_type_ensure (_g_winhttp_vfs_get_type ());
#endif
g_type_ensure (_g_local_vfs_get_type ());
diff --git a/gio/glib-compile-resources.c b/gio/glib-compile-resources.c
index 8a1a07dd1..99bcc58ba 100644
--- a/gio/glib-compile-resources.c
+++ b/gio/glib-compile-resources.c
@@ -76,6 +76,7 @@ typedef struct
static gchar **sourcedirs = NULL;
static gchar *xmllint = NULL;
+static gchar *jsonformat = NULL;
static gchar *gdk_pixbuf_pixdata = NULL;
static void
@@ -219,7 +220,6 @@ end_element (GMarkupParseContext *context,
gchar *key;
FileData *data = NULL;
char *tmp_file = NULL;
- char *tmp_file2 = NULL;
file = state->string->str;
key = file;
@@ -274,6 +274,7 @@ end_element (GMarkupParseContext *context,
gchar **options;
guint i;
gboolean xml_stripblanks = FALSE;
+ gboolean json_stripblanks = FALSE;
gboolean to_pixdata = FALSE;
options = g_strsplit (state->preproc_options, ",", -1);
@@ -284,6 +285,8 @@ end_element (GMarkupParseContext *context,
xml_stripblanks = TRUE;
else if (!strcmp (options[i], "to-pixdata"))
to_pixdata = TRUE;
+ else if (!strcmp (options[i], "json-stripblanks"))
+ json_stripblanks = TRUE;
else
{
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
@@ -294,73 +297,148 @@ end_element (GMarkupParseContext *context,
}
g_strfreev (options);
- if (xml_stripblanks && xmllint != NULL)
+ if (xml_stripblanks)
{
- int fd;
- GSubprocess *proc;
-
- tmp_file = g_strdup ("resource-XXXXXXXX");
- if ((fd = g_mkstemp (tmp_file)) == -1)
+ /* This is not fatal: pretty-printed XML is still valid XML */
+ if (xmllint == NULL)
{
- int errsv = errno;
-
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
- _("Failed to create temp file: %s"),
- g_strerror (errsv));
- g_free (tmp_file);
- tmp_file = NULL;
- goto cleanup;
+ static gboolean xmllint_warned = FALSE;
+
+ if (!xmllint_warned)
+ {
+ /* Translators: the first %s is a gresource XML attribute,
+ * the second %s is an environment variable, and the third
+ * %s is a command line tool
+ */
+ char *warn = g_strdup_printf (_("%s preprocessing requested, but %s is not set, and %s is not in PATH"),
+ "xml-stripblanks",
+ "XMLLINT",
+ "xmllint");
+ g_printerr ("%s\n", warn);
+ g_free (warn);
+
+ /* Only warn once */
+ xmllint_warned = TRUE;
+ }
}
- close (fd);
+ else
+ {
+ GSubprocess *proc;
+ int fd;
- proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
- xmllint, "--nonet", "--noblanks", "--output", tmp_file, real_file, NULL);
- g_free (real_file);
- real_file = NULL;
+ fd = g_file_open_tmp ("resource-XXXXXXXX", &tmp_file, error);
+ if (fd < 0)
+ goto cleanup;
- if (!proc)
- goto cleanup;
+ close (fd);
- if (!g_subprocess_wait_check (proc, NULL, error))
- {
- g_object_unref (proc);
- goto cleanup;
+ proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
+ xmllint, "--nonet", "--noblanks", "--output", tmp_file, real_file, NULL);
+ g_free (real_file);
+ real_file = NULL;
+
+ if (!proc)
+ goto cleanup;
+
+ if (!g_subprocess_wait_check (proc, NULL, error))
+ {
+ g_object_unref (proc);
+ goto cleanup;
+ }
+
+ g_object_unref (proc);
+
+ real_file = g_strdup (tmp_file);
}
+ }
- g_object_unref (proc);
+ if (json_stripblanks)
+ {
+ /* As above, this is not fatal: pretty-printed JSON is still
+ * valid JSON
+ */
+ if (jsonformat == NULL)
+ {
+ static gboolean jsonformat_warned = FALSE;
+
+ if (!jsonformat_warned)
+ {
+ /* Translators: the first %s is a gresource XML attribute,
+ * the second %s is an environment variable, and the third
+ * %s is a command line tool
+ */
+ char *warn = g_strdup_printf (_("%s preprocessing requested, but %s is not set, and %s is not in PATH"),
+ "json-stripblanks",
+ "JSON_GLIB_FORMAT",
+ "json-glib-format");
+ g_printerr ("%s\n", warn);
+ g_free (warn);
+
+ /* Only warn once */
+ jsonformat_warned = TRUE;
+ }
+ }
+ else
+ {
+ GSubprocess *proc;
+ int fd;
- real_file = g_strdup (tmp_file);
+ fd = g_file_open_tmp ("resource-XXXXXXXX", &tmp_file, error);
+ if (fd < 0)
+ goto cleanup;
+
+ close (fd);
+
+ proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
+ jsonformat, "--output", tmp_file, real_file, NULL);
+ g_free (real_file);
+ real_file = NULL;
+
+ if (!proc)
+ goto cleanup;
+
+ if (!g_subprocess_wait_check (proc, NULL, error))
+ {
+ g_object_unref (proc);
+ goto cleanup;
+ }
+
+ g_object_unref (proc);
+
+ real_file = g_strdup (tmp_file);
+ }
}
if (to_pixdata)
{
- int fd;
GSubprocess *proc;
+ int fd;
+ /* This is a fatal error: if to-pixdata is used it means that
+ * the code loading the GResource expects a specific data format
+ */
if (gdk_pixbuf_pixdata == NULL)
{
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "to-pixbuf preprocessing requested but GDK_PIXBUF_PIXDATA "
- "not set and gdk-pixbuf-pixdata not found in path");
+ /* Translators: the first %s is a gresource XML attribute,
+ * the second %s is an environment variable, and the third
+ * %s is a command line tool
+ */
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("%s preprocessing requested, but %s is not set, and %s is not in PATH"),
+ "to-pixdata",
+ "GDK_PIXBUF_PIXDATA",
+ "gdk-pixbuf-pixdata");
goto cleanup;
}
- tmp_file2 = g_strdup ("resource-XXXXXXXX");
- if ((fd = g_mkstemp (tmp_file2)) == -1)
- {
- int errsv = errno;
+ fd = g_file_open_tmp ("resource-XXXXXXXX", &tmp_file, error);
+ if (fd < 0)
+ goto cleanup;
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
- _("Failed to create temp file: %s"),
- g_strerror (errsv));
- g_free (tmp_file2);
- tmp_file2 = NULL;
- goto cleanup;
- }
close (fd);
proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
- gdk_pixbuf_pixdata, real_file, tmp_file2, NULL);
+ gdk_pixbuf_pixdata, real_file, tmp_file, NULL);
g_free (real_file);
real_file = NULL;
@@ -372,7 +450,7 @@ end_element (GMarkupParseContext *context,
g_object_unref (proc);
- real_file = g_strdup (tmp_file2);
+ real_file = g_strdup (tmp_file);
}
}
@@ -437,12 +515,6 @@ done:
g_free (tmp_file);
}
- if (tmp_file2)
- {
- unlink (tmp_file2);
- g_free (tmp_file2);
- }
-
if (data != NULL)
file_data_free (data);
}
@@ -733,8 +805,10 @@ main (int argc, char **argv)
xmllint = g_strdup (g_getenv ("XMLLINT"));
if (xmllint == NULL)
xmllint = g_find_program_in_path ("xmllint");
- if (xmllint == NULL)
- g_printerr ("XMLLINT not set and xmllint not found in path; skipping xml preprocessing.\n");
+
+ jsonformat = g_strdup (g_getenv ("JSON_GLIB_FORMAT"));
+ if (jsonformat == NULL)
+ jsonformat = g_find_program_in_path ("json-glib-format");
gdk_pixbuf_pixdata = g_strdup (g_getenv ("GDK_PIXBUF_PIXDATA"));
if (gdk_pixbuf_pixdata == NULL)
@@ -1096,6 +1170,7 @@ main (int argc, char **argv)
g_free (target);
g_hash_table_destroy (table);
g_free (xmllint);
+ g_free (jsonformat);
g_free (c_name);
g_hash_table_unref (files);
diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c
index 2dc8c7171..f6e1b4036 100644
--- a/gio/glib-compile-schemas.c
+++ b/gio/glib-compile-schemas.c
@@ -745,6 +745,8 @@ key_state_free (gpointer data)
{
KeyState *state = data;
+ g_free (state->child_schema);
+
if (state->type)
g_variant_type_free (state->type);
@@ -880,6 +882,8 @@ schema_state_free (gpointer data)
g_free (state->path);
g_free (state->gettext_domain);
+ g_free (state->extends_name);
+ g_free (state->list_of);
g_hash_table_unref (state->keys);
g_slice_free (SchemaState, state);
}
diff --git a/gio/gliststore.c b/gio/gliststore.c
index 7cb118d76..c91dcb334 100644
--- a/gio/gliststore.c
+++ b/gio/gliststore.c
@@ -477,7 +477,6 @@ g_list_store_splice (GListStore *store,
{
gint i;
- it = g_sequence_iter_next (it);
for (i = 0; i < n_additions; i++)
{
if G_UNLIKELY (!g_type_is_a (G_OBJECT_TYPE (additions[i]), store->item_type))
@@ -488,6 +487,7 @@ g_list_store_splice (GListStore *store,
}
it = g_sequence_insert_before (it, g_object_ref (additions[i]));
+ it = g_sequence_iter_next (it);
}
}
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index e7481454e..3cd0137d6 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -199,112 +199,13 @@ _g_local_file_get_filename (GLocalFile *file)
return file->filename;
}
-static char *
-canonicalize_filename (const char *filename)
-{
- char *canon, *start, *p, *q;
- char *cwd;
- int i;
-
- if (!g_path_is_absolute (filename))
- {
- cwd = g_get_current_dir ();
- canon = g_build_filename (cwd, filename, NULL);
- g_free (cwd);
- }
- else
- canon = g_strdup (filename);
-
- start = (char *)g_path_skip_root (canon);
-
- if (start == NULL)
- {
- /* This shouldn't really happen, as g_get_current_dir() should
- return an absolute pathname, but bug 573843 shows this is
- not always happening */
- g_free (canon);
- return g_build_filename (G_DIR_SEPARATOR_S, filename, NULL);
- }
-
- /* POSIX allows double slashes at the start to
- * mean something special (as does windows too).
- * So, "//" != "/", but more than two slashes
- * is treated as "/".
- */
- i = 0;
- for (p = start - 1;
- (p >= canon) &&
- G_IS_DIR_SEPARATOR (*p);
- p--)
- i++;
- if (i > 2)
- {
- i -= 1;
- start -= i;
- memmove (start, start+i, strlen (start+i)+1);
- }
-
- /* Make sure we're using the canonical dir separator */
- p++;
- while (p < start && G_IS_DIR_SEPARATOR (*p))
- *p++ = G_DIR_SEPARATOR;
-
- p = start;
- while (*p != 0)
- {
- if (p[0] == '.' && (p[1] == 0 || G_IS_DIR_SEPARATOR (p[1])))
- {
- memmove (p, p+1, strlen (p+1)+1);
- }
- else if (p[0] == '.' && p[1] == '.' && (p[2] == 0 || G_IS_DIR_SEPARATOR (p[2])))
- {
- q = p + 2;
- /* Skip previous separator */
- p = p - 2;
- if (p < start)
- p = start;
- while (p > start && !G_IS_DIR_SEPARATOR (*p))
- p--;
- if (G_IS_DIR_SEPARATOR (*p))
- *p++ = G_DIR_SEPARATOR;
- memmove (p, q, strlen (q)+1);
- }
- else
- {
- /* Skip until next separator */
- while (*p != 0 && !G_IS_DIR_SEPARATOR (*p))
- p++;
-
- if (*p != 0)
- {
- /* Canonicalize one separator */
- *p++ = G_DIR_SEPARATOR;
- }
- }
-
- /* Remove additional separators */
- q = p;
- while (*q && G_IS_DIR_SEPARATOR (*q))
- q++;
-
- if (p != q)
- memmove (p, q, strlen (q)+1);
- }
-
- /* Remove trailing slashes */
- if (p > start && G_IS_DIR_SEPARATOR (*(p-1)))
- *(p-1) = 0;
-
- return canon;
-}
-
GFile *
_g_local_file_new (const char *filename)
{
GLocalFile *local;
local = g_object_new (G_TYPE_LOCAL_FILE, NULL);
- local->filename = canonicalize_filename (filename);
+ local->filename = g_canonicalize_filename (filename, NULL);
return G_FILE (local);
}
@@ -1659,7 +1560,7 @@ expand_symlink (const char *link)
#endif
if (g_path_is_absolute (symlink_value))
- return canonicalize_filename (symlink_value);
+ return g_canonicalize_filename (symlink_value, NULL);
else
{
link2 = strip_trailing_slashes (link);
@@ -1669,7 +1570,7 @@ expand_symlink (const char *link)
resolved = g_build_filename (parent, symlink_value, NULL);
g_free (parent);
- canonical = canonicalize_filename (resolved);
+ canonical = g_canonicalize_filename (resolved, NULL);
g_free (resolved);
@@ -2819,7 +2720,9 @@ g_local_file_measure_size_of_file (gint parent_fd,
if (S_ISDIR (buf.st_mode))
{
int dir_fd = -1;
+#ifdef AT_FDCWD
int errsv;
+#endif
if (g_cancellable_set_error_if_cancelled (state->cancellable, error))
return FALSE;
diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c
index 6d4cbc69c..801695ad0 100644
--- a/gio/glocalfileinfo.c
+++ b/gio/glocalfileinfo.c
@@ -897,19 +897,21 @@ get_access_rights (GFileAttributeMatcher *attribute_matcher,
writable = FALSE;
if (parent_info->writable)
{
+#ifdef G_OS_WIN32
+ writable = TRUE;
+#else
if (parent_info->is_sticky)
{
-#ifndef G_OS_WIN32
uid_t uid = geteuid ();
if (uid == statbuf->st_uid ||
uid == parent_info->owner ||
uid == 0)
-#endif
writable = TRUE;
}
else
writable = TRUE;
+#endif
}
if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_RENAME))
@@ -953,8 +955,7 @@ set_info_from_stat (GFileInfo *info,
else if (S_ISLNK (statbuf->st_mode))
file_type = G_FILE_TYPE_SYMBOLIC_LINK;
#elif defined (G_OS_WIN32)
- if (statbuf->reparse_tag == IO_REPARSE_TAG_SYMLINK ||
- statbuf->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT)
+ if (statbuf->reparse_tag == IO_REPARSE_TAG_SYMLINK)
file_type = G_FILE_TYPE_SYMBOLIC_LINK;
#endif
@@ -998,20 +999,13 @@ set_info_from_stat (GFileInfo *info,
#elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC)
_g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_USEC, statbuf->st_atim.tv_nsec / 1000);
#endif
-
-#ifndef G_OS_WIN32
- /* Microsoft uses st_ctime for file creation time,
- * instead of file change time:
- * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions#generic-text-routine-mappings
- * Thank you, Microsoft!
- */
+
_g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED, statbuf->st_ctime);
#if defined (HAVE_STRUCT_STAT_ST_CTIMENSEC)
_g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED_USEC, statbuf->st_ctimensec / 1000);
#elif defined (HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC)
_g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED_USEC, statbuf->st_ctim.tv_nsec / 1000);
#endif
-#endif
#if defined (HAVE_STRUCT_STAT_ST_BIRTHTIME) && defined (HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
_g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtime);
@@ -1023,8 +1017,6 @@ set_info_from_stat (GFileInfo *info,
_g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtime);
#elif defined (HAVE_STRUCT_STAT_ST_BIRTHTIM)
_g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtim);
-#elif defined (G_OS_WIN32)
- _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_ctime);
#endif
if (_g_file_attribute_matcher_matches_id (attribute_matcher,
@@ -1067,7 +1059,7 @@ make_valid_utf8 (const char *name)
while (remaining_bytes != 0)
{
- if (g_utf8_validate (remainder, remaining_bytes, &invalid))
+ if (g_utf8_validate (remainder, remaining_bytes, &invalid))
break;
valid_bytes = invalid - remainder;
@@ -1802,9 +1794,7 @@ _g_local_file_info_get (const char *basename,
is_symlink = stat_ok && S_ISLNK (statbuf.st_mode);
#elif defined (G_OS_WIN32)
/* glib already checked the FILE_ATTRIBUTE_REPARSE_POINT for us */
- is_symlink = stat_ok &&
- (statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK ||
- statbuf.reparse_tag == IO_REPARSE_TAG_MOUNT_POINT);
+ is_symlink = stat_ok && statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK;
#else
is_symlink = FALSE;
#endif
@@ -2187,9 +2177,7 @@ set_unix_mode (char *filename,
GWin32PrivateStat statbuf;
res = GLIB_PRIVATE_CALL (g_win32_lstat_utf8) (filename, &statbuf);
- is_symlink = (res == 0 &&
- (statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK ||
- statbuf.reparse_tag == IO_REPARSE_TAG_MOUNT_POINT));
+ is_symlink = (res == 0 && statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK);
#endif
if (is_symlink)
{
diff --git a/gio/glocalvfs.c b/gio/glocalvfs.c
index 4f1462de9..c29d071b7 100644
--- a/gio/glocalvfs.c
+++ b/gio/glocalvfs.c
@@ -129,7 +129,7 @@ g_local_vfs_parse_name (GVfs *vfs,
GFile *file;
char *filename;
char *user_prefix;
- const char *user_start, *user_end;
+ const char *user_end;
char *rest;
g_return_val_if_fail (G_IS_VFS (vfs), NULL);
@@ -141,19 +141,22 @@ g_local_vfs_parse_name (GVfs *vfs,
{
if (*parse_name == '~')
{
+#ifdef G_OS_UNIX
+ const char *user_start;
+ user_start = parse_name + 1;
+#endif
parse_name ++;
- user_start = parse_name;
while (*parse_name != 0 && *parse_name != '/')
parse_name++;
user_end = parse_name;
+#ifdef G_OS_UNIX
if (user_end == user_start)
user_prefix = g_strdup (g_get_home_dir ());
else
{
-#ifdef G_OS_UNIX
struct passwd *passwd_file_entry;
char *user_name;
@@ -165,9 +168,11 @@ g_local_vfs_parse_name (GVfs *vfs,
passwd_file_entry->pw_dir != NULL)
user_prefix = g_strdup (passwd_file_entry->pw_dir);
else
-#endif
user_prefix = g_strdup (g_get_home_dir ());
}
+#else
+ user_prefix = g_strdup (g_get_home_dir ());
+#endif
rest = NULL;
if (*user_end != 0)
diff --git a/gio/gmenuexporter.c b/gio/gmenuexporter.c
index e12a0f78e..f319b886b 100644
--- a/gio/gmenuexporter.c
+++ b/gio/gmenuexporter.c
@@ -72,7 +72,7 @@ org_gtk_Menus_get_interface (void)
" </interface>"
"</node>", &error);
if (info == NULL)
- g_error ("%s\n", error->message);
+ g_error ("%s", error->message);
interface_info = g_dbus_node_info_lookup_interface (info, "org.gtk.Menus");
g_assert (interface_info != NULL);
g_dbus_interface_info_ref (interface_info);
diff --git a/gio/gnetworkmonitornetlink.c b/gio/gnetworkmonitornetlink.c
index 3841e69e1..b308b3b65 100644
--- a/gio/gnetworkmonitornetlink.c
+++ b/gio/gnetworkmonitornetlink.c
@@ -113,7 +113,7 @@ g_network_monitor_netlink_initable_init (GInitable *initable,
}
nl->priv->sock = g_socket_new_from_fd (sockfd, error);
- if (!nl->priv->sock)
+ if (error)
{
g_prefix_error (error, "%s", _("Could not create network monitor: "));
(void) g_close (sockfd, NULL);
@@ -435,6 +435,12 @@ g_network_monitor_netlink_finalize (GObject *object)
{
GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (object);
+ if (nl->priv->sock)
+ {
+ g_socket_close (nl->priv->sock, NULL);
+ g_object_unref (nl->priv->sock);
+ }
+
if (nl->priv->source)
{
g_source_destroy (nl->priv->source);
@@ -447,12 +453,6 @@ g_network_monitor_netlink_finalize (GObject *object)
g_source_unref (nl->priv->dump_source);
}
- if (nl->priv->sock)
- {
- g_socket_close (nl->priv->sock, NULL);
- g_object_unref (nl->priv->sock);
- }
-
g_clear_pointer (&nl->priv->context, g_main_context_unref);
g_clear_pointer (&nl->priv->dump_networks, g_ptr_array_unref);
diff --git a/gio/gnetworkmonitorportal.c b/gio/gnetworkmonitorportal.c
index bce8a338a..856f8aa5b 100644
--- a/gio/gnetworkmonitorportal.c
+++ b/gio/gnetworkmonitorportal.c
@@ -21,6 +21,7 @@
#include "gnetworkmonitorportal.h"
#include "ginitable.h"
#include "giomodule-priv.h"
+#include "gnetworkmonitor.h"
#include "xdp-dbus.h"
#include "gportalsupport.h"
@@ -38,13 +39,8 @@ enum
struct _GNetworkMonitorPortalPrivate
{
- GDBusProxy *proxy;
- gboolean has_network;
- int version;
-
- gboolean available;
- gboolean metered;
- GNetworkConnectivity connectivity;
+ GXdpNetworkMonitor *proxy;
+ gboolean network_available;
};
G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorPortal, g_network_monitor_portal, G_TYPE_NETWORK_MONITOR_BASE,
@@ -76,15 +72,22 @@ g_network_monitor_portal_get_property (GObject *object,
switch (prop_id)
{
case PROP_NETWORK_AVAILABLE:
- g_value_set_boolean (value, nm->priv->available);
+ g_value_set_boolean (value,
+ nm->priv->network_available &&
+ gxdp_network_monitor_get_available (nm->priv->proxy));
break;
case PROP_NETWORK_METERED:
- g_value_set_boolean (value, nm->priv->metered);
+ g_value_set_boolean (value,
+ nm->priv->network_available &&
+ gxdp_network_monitor_get_metered (nm->priv->proxy));
break;
case PROP_CONNECTIVITY:
- g_value_set_enum (value, nm->priv->connectivity);
+ g_value_set_enum (value,
+ nm->priv->network_available
+ ? gxdp_network_monitor_get_connectivity (nm->priv->proxy)
+ : G_NETWORK_CONNECTIVITY_LOCAL);
break;
default:
@@ -94,191 +97,22 @@ g_network_monitor_portal_get_property (GObject *object,
}
static void
-got_available (GObject *source,
- GAsyncResult *res,
- gpointer data)
-{
- GDBusProxy *proxy = G_DBUS_PROXY (source);
- GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (data);
- GError *error = NULL;
- GVariant *ret;
- gboolean available;
-
- ret = g_dbus_proxy_call_finish (proxy, res, &error);
- if (ret == NULL)
- {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- return;
- }
-
- g_variant_get (ret, "(b)", &available);
- g_variant_unref (ret);
-
- if (nm->priv->available != available)
- {
- nm->priv->available = available;
- g_object_notify (G_OBJECT (nm), "network-available");
- g_signal_emit_by_name (nm, "network-changed", available);
- }
-}
-
-static void
-got_metered (GObject *source,
- GAsyncResult *res,
- gpointer data)
-{
- GDBusProxy *proxy = G_DBUS_PROXY (source);
- GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (data);
- GError *error = NULL;
- GVariant *ret;
- gboolean metered;
-
- ret = g_dbus_proxy_call_finish (proxy, res, &error);
- if (ret == NULL)
- {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- return;
- }
-
- g_variant_get (ret, "(b)", &metered);
- g_variant_unref (ret);
-
- if (nm->priv->metered != metered)
- {
- nm->priv->metered = metered;
- g_object_notify (G_OBJECT (nm), "network-metered");
- }
-}
-
-static void
-got_connectivity (GObject *source,
- GAsyncResult *res,
- gpointer data)
-{
- GDBusProxy *proxy = G_DBUS_PROXY (source);
- GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (data);
- GError *error = NULL;
- GVariant *ret;
- GNetworkConnectivity connectivity;
-
- ret = g_dbus_proxy_call_finish (proxy, res, &error);
- if (ret == NULL)
- {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- return;
- }
-
- g_variant_get (ret, "(u)", &connectivity);
- g_variant_unref (ret);
-
- if (nm->priv->connectivity != connectivity)
- {
- nm->priv->connectivity = connectivity;
- g_object_notify (G_OBJECT (nm), "connectivity");
- }
-}
-
-static void
-update_properties (GDBusProxy *proxy,
- GNetworkMonitorPortal *nm)
-{
- g_dbus_proxy_call (proxy, "GetConnectivity", NULL, 0, -1, NULL, got_connectivity, nm);
- g_dbus_proxy_call (proxy, "GetMetered", NULL, 0, -1, NULL, got_metered, nm);
- g_dbus_proxy_call (proxy, "GetAvailable", NULL, 0, -1, NULL, got_available, nm);
-}
-
-static void
-proxy_signal (GDBusProxy *proxy,
- const char *sender,
- const char *signal,
- GVariant *parameters,
- GNetworkMonitorPortal *nm)
+proxy_changed (GXdpNetworkMonitor *proxy,
+ gboolean available,
+ GNetworkMonitorPortal *nm)
{
- if (!nm->priv->has_network)
- return;
-
- if (nm->priv->version == 1)
- {
- gboolean available;
-
- g_variant_get (parameters, "(b)", &available);
- g_signal_emit_by_name (nm, "network-changed", available);
- }
- else if (nm->priv->version == 2)
- {
- update_properties (proxy, nm);
- }
+ if (nm->priv->network_available)
+ g_signal_emit_by_name (nm, "network-changed", available);
}
-static void
-proxy_properties_changed (GDBusProxy *proxy,
- GVariant *changed,
- GVariant *invalidated,
- GNetworkMonitorPortal *nm)
-{
- if (!nm->priv->has_network)
- return;
-
- if (nm->priv->version == 1)
- {
- GVariant *ret;
-
- ret = g_dbus_proxy_get_cached_property (proxy, "connectivity");
- if (ret)
- {
- GNetworkConnectivity connectivity = g_variant_get_uint32 (ret);
- if (nm->priv->connectivity != connectivity)
- {
- nm->priv->connectivity = connectivity;
- g_object_notify (G_OBJECT (nm), "connectivity");
- }
- g_variant_unref (ret);
- }
-
- ret = g_dbus_proxy_get_cached_property (proxy, "metered");
- if (ret)
- {
- gboolean metered = g_variant_get_boolean (ret);
- if (nm->priv->metered != metered)
- {
- nm->priv->metered = metered;
- g_object_notify (G_OBJECT (nm), "network-metered");
- }
- g_variant_unref (ret);
- }
-
- ret = g_dbus_proxy_get_cached_property (proxy, "available");
- if (ret)
- {
- gboolean available = g_variant_get_boolean (ret);
- if (nm->priv->available != available)
- {
- nm->priv->available = available;
- g_object_notify (G_OBJECT (nm), "network-available");
- g_signal_emit_by_name (nm, "network-changed", available);
- }
- g_variant_unref (ret);
- }
- }
-}
-
static gboolean
g_network_monitor_portal_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (initable);
- GDBusProxy *proxy;
+ GXdpNetworkMonitor *proxy;
gchar *name_owner = NULL;
- int version;
- GVariant *ret;
-
- nm->priv->available = FALSE;
- nm->priv->metered = FALSE;
- nm->priv->connectivity = G_NETWORK_CONNECTIVITY_LOCAL;
if (!glib_should_use_portal ())
{
@@ -286,19 +120,17 @@ g_network_monitor_portal_initable_init (GInitable *initable,
return FALSE;
}
- proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START
- | G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
- NULL,
- "org.freedesktop.portal.Desktop",
- "/org/freedesktop/portal/desktop",
- "org.freedesktop.portal.NetworkMonitor",
- cancellable,
- error);
+ proxy = gxdp_network_monitor_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START
+ | G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
+ "org.freedesktop.portal.Desktop",
+ "/org/freedesktop/portal/desktop",
+ cancellable,
+ error);
if (!proxy)
return FALSE;
- name_owner = g_dbus_proxy_get_name_owner (proxy);
+ name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy));
if (!name_owner)
{
@@ -312,34 +144,11 @@ g_network_monitor_portal_initable_init (GInitable *initable,
g_free (name_owner);
- ret = g_dbus_proxy_get_cached_property (proxy, "version");
- g_variant_get (ret, "u", &version);
- g_variant_unref (ret);
-
- if (version != 1 && version != 2)
- {
- g_object_unref (proxy);
- g_set_error (error,
- G_DBUS_ERROR,
- G_DBUS_ERROR_NAME_HAS_NO_OWNER,
- "NetworkMonitor portal unsupported version: %d", version);
- return FALSE;
- }
-
- g_signal_connect (proxy, "g-signal", G_CALLBACK (proxy_signal), nm);
- g_signal_connect (proxy, "g-properties-changed", G_CALLBACK (proxy_properties_changed), nm);
-
+ g_signal_connect (proxy, "changed", G_CALLBACK (proxy_changed), nm);
nm->priv->proxy = proxy;
- nm->priv->has_network = glib_network_available_in_sandbox ();
- nm->priv->version = version;
-
- if (!initable_parent_iface->init (initable, cancellable, error))
- return FALSE;
-
- if (nm->priv->has_network && nm->priv->version == 2)
- update_properties (proxy, nm);
+ nm->priv->network_available = glib_network_available_in_sandbox ();
- return TRUE;
+ return initable_parent_iface->init (initable, cancellable, error);
}
static void
diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c
index 247ed8ce7..38d60bf68 100644
--- a/gio/gopenuriportal.c
+++ b/gio/gopenuriportal.c
@@ -203,7 +203,7 @@ open_call_done (GObject *source,
GError *error = NULL;
gboolean open_file;
gboolean res;
- char *path;
+ char *path = NULL;
const char *handle;
guint signal_id;
@@ -224,7 +224,7 @@ open_call_done (GObject *source,
}
handle = (const char *)g_object_get_data (G_OBJECT (task), "handle");
- if (strcmp (handle, path) != 0)
+ if (g_strcmp0 (handle, path) != 0)
{
signal_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "signal-id"));
g_dbus_connection_signal_unsubscribe (connection, signal_id);
diff --git a/gio/gregistrysettingsbackend.c b/gio/gregistrysettingsbackend.c
index 23a96486f..70d391a32 100644
--- a/gio/gregistrysettingsbackend.c
+++ b/gio/gregistrysettingsbackend.c
@@ -1800,7 +1800,7 @@ watch_thread_function (LPVOID parameter)
* likely to block (only when changing notification subscriptions).
*/
event = g_slice_new (RegistryEvent);
- event->self = g_object_ref (self->owner);
+ event->self = G_REGISTRY_BACKEND (g_object_ref (self->owner));
event->prefix = g_strdup (prefix);
event->items = g_ptr_array_new_with_free_func (g_free);
diff --git a/gio/gsettings-mapping.c b/gio/gsettings-mapping.c
index 94d5cc705..bba8a8f7c 100644
--- a/gio/gsettings-mapping.c
+++ b/gio/gsettings-mapping.c
@@ -498,7 +498,7 @@ g_settings_get_mapping (GValue *value,
return TRUE;
}
- g_warning ("Unable to lookup enum nick '%s' via GType\n", nick);
+ g_warning ("Unable to lookup enum nick '%s' via GType", nick);
return FALSE;
}
}
@@ -530,7 +530,7 @@ g_settings_get_mapping (GValue *value,
else
{
- g_warning ("Unable to lookup flags nick '%s' via GType\n",
+ g_warning ("Unable to lookup flags nick '%s' via GType",
nick);
return FALSE;
}
diff --git a/gio/gsettings.c b/gio/gsettings.c
index 10d394d69..e5ed54a46 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -587,7 +587,7 @@ g_settings_set_property (GObject *object,
settings->priv->schema = g_settings_schema_source_lookup (default_source, schema_id, TRUE);
if (settings->priv->schema == NULL)
- g_error ("Settings schema '%s' is not installed\n", schema_id);
+ g_error ("Settings schema '%s' is not installed", schema_id);
}
}
break;
@@ -2475,8 +2475,7 @@ g_settings_list_keys (GSettings *settings)
* to call g_settings_get_child().
*
* For GSettings objects that are lists, this value can change at any
- * time and you should connect to the "children-changed" signal to watch
- * for those changes. Note that there is a race condition here: you may
+ * time. Note that there is a race condition here: you may
* request a child after listing it only for it to have been destroyed
* in the meantime. For this reason, g_settings_get_child() may return
* %NULL even for a child that was listed by this function.
@@ -2683,6 +2682,7 @@ g_settings_binding_property_changed (GObject *object,
GSettingsBinding *binding = user_data;
GValue value = G_VALUE_INIT;
GVariant *variant;
+ gboolean valid = TRUE;
g_assert (object == binding->object);
g_assert (pspec == binding->property);
@@ -2701,24 +2701,33 @@ g_settings_binding_property_changed (GObject *object,
if (!g_settings_schema_key_type_check (&binding->key, variant))
{
+ gchar *type_str;
+ type_str = g_variant_type_dup_string (binding->key.type);
g_critical ("binding mapping function for key '%s' returned "
"GVariant of type '%s' when type '%s' was requested",
binding->key.name, g_variant_get_type_string (variant),
- g_variant_type_dup_string (binding->key.type));
- return;
+ type_str);
+ g_free (type_str);
+ valid = FALSE;
}
- if (!g_settings_schema_key_range_check (&binding->key, variant))
+ if (valid && !g_settings_schema_key_range_check (&binding->key, variant))
{
+ gchar *variant_str;
+ variant_str = g_variant_print (variant, TRUE);
g_critical ("GObject property '%s' on a '%s' object is out of "
"schema-specified range for key '%s' of '%s': %s",
binding->property->name, g_type_name (binding->property->owner_type),
binding->key.name, g_settings_schema_get_id (binding->key.schema),
- g_variant_print (variant, TRUE));
- return;
+ variant_str);
+ g_free (variant_str);
+ valid = FALSE;
}
- g_settings_write_to_backend (binding->settings, &binding->key, variant);
+ if (valid)
+ {
+ g_settings_write_to_backend (binding->settings, &binding->key, variant);
+ }
g_variant_unref (variant);
}
g_value_unset (&value);
diff --git a/gio/gsimpleaction.c b/gio/gsimpleaction.c
index 54c554087..c788252bb 100644
--- a/gio/gsimpleaction.c
+++ b/gio/gsimpleaction.c
@@ -371,12 +371,14 @@ g_simple_action_class_init (GSimpleActionClass *class)
/**
* GSimpleAction::activate:
* @simple: the #GSimpleAction
- * @parameter: (nullable): the parameter to the activation
+ * @parameter: (nullable): the parameter to the activation, or %NULL if it has
+ * no parameter
*
* Indicates that the action was just activated.
*
- * @parameter will always be of the expected type. In the event that
- * an incorrect type was given, no signal will be emitted.
+ * @parameter will always be of the expected type, i.e. the parameter type
+ * specified when the action was created. If an incorrect type is given when
+ * activating the action, this signal is not emitted.
*
* Since GLib 2.40, if no handler is connected to this signal then the
* default behaviour for boolean-stated actions with a %NULL parameter
@@ -405,8 +407,10 @@ g_simple_action_class_init (GSimpleActionClass *class)
* Indicates that the action just received a request to change its
* state.
*
- * @value will always be of the correct state type. In the event that
- * an incorrect type was given, no signal will be emitted.
+ * @value will always be of the correct state type, i.e. the type of the
+ * initial state passed to g_simple_action_new_stateful(). If an incorrect
+ * type is given when requesting to change the state, this signal is not
+ * emitted.
*
* If no handler is connected to this signal then the default
* behaviour is to call g_simple_action_set_state() to set the state
@@ -591,11 +595,13 @@ g_simple_action_set_state_hint (GSimpleAction *simple,
/**
* g_simple_action_new:
* @name: the name of the action
- * @parameter_type: (nullable): the type of parameter to the activate function
+ * @parameter_type: (nullable): the type of parameter that will be passed to
+ * handlers for the #GSimpleAction::activate signal, or %NULL for no parameter
*
* Creates a new action.
*
- * The created action is stateless. See g_simple_action_new_stateful().
+ * The created action is stateless. See g_simple_action_new_stateful() to create
+ * an action that has state.
*
* Returns: a new #GSimpleAction
*
@@ -616,15 +622,16 @@ g_simple_action_new (const gchar *name,
/**
* g_simple_action_new_stateful:
* @name: the name of the action
- * @parameter_type: (nullable): the type of the parameter to the activate function
+ * @parameter_type: (nullable): the type of the parameter that will be passed to
+ * handlers for the #GSimpleAction::activate signal, or %NULL for no parameter
* @state: the initial state of the action
*
* Creates a new stateful action.
*
- * @state is the initial state of the action. All future state values
- * must have the same #GVariantType as the initial state.
+ * All future state values must have the same #GVariantType as the initial
+ * @state.
*
- * If the @state GVariant is floating, it is consumed.
+ * If the @state #GVariant is floating, it is consumed.
*
* Returns: a new #GSimpleAction
*
diff --git a/gio/gsocket.c b/gio/gsocket.c
index b4a941eb1..11be2e738 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -572,7 +572,7 @@ g_socket (gint domain,
if (fd < 0)
{
- int errsv = get_socket_errno ();
+ errsv = get_socket_errno ();
g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
_("Unable to create socket: %s"), socket_strerror (errsv));
@@ -3251,7 +3251,7 @@ g_socket_send_with_timeout (GSocket *socket,
{
win32_unset_event_mask (socket, FD_WRITE);
- if ((ret = send (socket->priv->fd, buffer, size, G_SOCKET_DEFAULT_SEND_FLAGS)) < 0)
+ if ((ret = send (socket->priv->fd, (const char *)buffer, size, G_SOCKET_DEFAULT_SEND_FLAGS)) < 0)
{
int errsv = get_socket_errno ();
diff --git a/gio/gsocketlistener.c b/gio/gsocketlistener.c
index df6b71b0d..ab17678a9 100644
--- a/gio/gsocketlistener.c
+++ b/gio/gsocketlistener.c
@@ -49,9 +49,16 @@
* of server sockets and helps you accept sockets from any of the
* socket, either sync or async.
*
+ * Add addresses and ports to listen on using g_socket_listener_add_address()
+ * and g_socket_listener_add_inet_port(). These will be listened on until
+ * g_socket_listener_close() is called. Dropping your final reference to the
+ * #GSocketListener will not cause g_socket_listener_close() to be called
+ * implicitly, as some references to the #GSocketListener may be held
+ * internally.
+ *
* If you want to implement a network server, also look at #GSocketService
- * and #GThreadedSocketService which are subclass of #GSocketListener
- * that makes this even easier.
+ * and #GThreadedSocketService which are subclasses of #GSocketListener
+ * that make this even easier.
*
* Since: 2.22
*/
@@ -309,6 +316,10 @@ g_socket_listener_add_socket (GSocketListener *listener,
* requesting a binding to port 0 (ie: "any port"). This address, if
* requested, belongs to the caller and must be freed.
*
+ * Call g_socket_listener_close() to stop listening on @address; this will not
+ * be done automatically when you drop your final reference to @listener, as
+ * references may be held internally.
+ *
* Returns: %TRUE on success, %FALSE on error.
*
* Since: 2.22
@@ -404,6 +415,10 @@ g_socket_listener_add_address (GSocketListener *listener,
* useful if you're listening on multiple addresses and do
* different things depending on what address is connected to.
*
+ * Call g_socket_listener_close() to stop listening on @port; this will not
+ * be done automatically when you drop your final reference to @listener, as
+ * references may be held internally.
+ *
* Returns: %TRUE on success, %FALSE on error.
*
* Since: 2.22
diff --git a/gio/gsubprocess.c b/gio/gsubprocess.c
index 2ce2428f0..31822e59c 100644
--- a/gio/gsubprocess.c
+++ b/gio/gsubprocess.c
@@ -1528,8 +1528,7 @@ g_subprocess_communicate_made_progress (GObject *source_object,
}
static gboolean
-g_subprocess_communicate_cancelled (GCancellable *cancellable,
- gpointer user_data)
+g_subprocess_communicate_cancelled (gpointer user_data)
{
CommunicateState *state = user_data;
@@ -1581,9 +1580,7 @@ g_subprocess_communicate_internal (GSubprocess *subprocess,
{
state->cancellable_source = g_cancellable_source_new (cancellable);
/* No ref held here, but we unref the source from state's free function */
- g_source_set_callback (state->cancellable_source,
- (GSourceFunc) g_subprocess_communicate_cancelled,
- state, NULL);
+ g_source_set_callback (state->cancellable_source, g_subprocess_communicate_cancelled, state, NULL);
g_source_attach (state->cancellable_source, g_main_context_get_thread_default ());
}
diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c
index 6eaf060d9..685503c5e 100644
--- a/gio/gtestdbus.c
+++ b/gio/gtestdbus.c
@@ -96,7 +96,7 @@ _g_object_dispose_and_wait_weak_notify (gpointer object)
if (data.timed_out)
{
- g_warning ("Weak notify timeout, object ref_count=%d\n",
+ g_warning ("Weak notify timeout, object ref_count=%d",
G_OBJECT (object)->ref_count);
}
else
@@ -823,6 +823,7 @@ g_test_dbus_down (GTestDBus *self)
_g_object_dispose_and_wait_weak_notify (connection);
g_test_dbus_unset ();
+ _g_bus_forget_singleton (G_BUS_TYPE_SESSION);
self->priv->up = FALSE;
}
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index 4d19217ca..f2db27e66 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -126,6 +126,7 @@ struct _GUnixMountEntry {
char *mount_path;
char *device_path;
char *filesystem_type;
+ char *options;
gboolean is_read_only;
gboolean is_system_internal;
};
@@ -306,6 +307,7 @@ g_unix_is_system_fs_type (const char *fs_type)
"autofs",
"autofs4",
"cgroup",
+ "cifs",
"configfs",
"cxfs",
"debugfs",
@@ -327,6 +329,8 @@ g_unix_is_system_fs_type (const char *fs_type)
"mfs",
"mqueue",
"ncpfs",
+ "nfs",
+ "nfs4",
"nfsd",
"nullfs",
"ocfs2",
@@ -339,6 +343,7 @@ g_unix_is_system_fs_type (const char *fs_type)
"rpc_pipefs",
"securityfs",
"selinuxfs",
+ "smbfs",
"sysfs",
"tmpfs",
"usbfs",
@@ -408,6 +413,7 @@ static GUnixMountEntry *
create_unix_mount_entry (const char *device_path,
const char *mount_path,
const char *filesystem_type,
+ const char *options,
gboolean is_read_only)
{
GUnixMountEntry *mount_entry = NULL;
@@ -416,6 +422,7 @@ create_unix_mount_entry (const char *device_path,
mount_entry->device_path = g_strdup (device_path);
mount_entry->mount_path = g_strdup (mount_path);
mount_entry->filesystem_type = g_strdup (filesystem_type);
+ mount_entry->options = g_strdup (options);
mount_entry->is_read_only = is_read_only;
mount_entry->is_system_internal =
@@ -494,6 +501,7 @@ _g_get_unix_mounts (void)
mount_entry = create_unix_mount_entry (device_path,
mnt_fs_get_target (fs),
mnt_fs_get_fstype (fs),
+ mnt_fs_get_options (fs),
is_read_only);
return_list = g_list_prepend (return_list, mount_entry);
@@ -588,6 +596,7 @@ _g_get_unix_mounts (void)
mount_entry = create_unix_mount_entry (device_path,
mntent->mnt_dir,
mntent->mnt_type,
+ mntent->mnt_opts,
is_read_only);
g_hash_table_insert (mounts_hash,
@@ -701,6 +710,7 @@ _g_get_unix_mounts (void)
mount_entry = create_unix_mount_entry (mntent.mnt_special,
mntent.mnt_mountp,
mntent.mnt_fstype,
+ mntent.mnt_opts,
is_read_only);
return_list = g_list_prepend (return_list, mount_entry);
@@ -734,7 +744,7 @@ _g_get_unix_mounts (void)
if (mntctl (MCTL_QUERY, sizeof (vmount_size), &vmount_size) != 0)
{
- g_warning ("Unable to know the number of mounted volumes\n");
+ g_warning ("Unable to know the number of mounted volumes");
return NULL;
}
@@ -744,11 +754,11 @@ _g_get_unix_mounts (void)
vmount_number = mntctl (MCTL_QUERY, vmount_size, vmount_info);
if (vmount_info->vmt_revision != VMT_REVISION)
- g_warning ("Bad vmount structure revision number, want %d, got %d\n", VMT_REVISION, vmount_info->vmt_revision);
+ g_warning ("Bad vmount structure revision number, want %d, got %d", VMT_REVISION, vmount_info->vmt_revision);
if (vmount_number < 0)
{
- g_warning ("Unable to recover mounted volumes information\n");
+ g_warning ("Unable to recover mounted volumes information");
g_free (vmount_info);
return NULL;
@@ -767,6 +777,7 @@ _g_get_unix_mounts (void)
mount_entry = create_unix_mount_entry (vmt2dataptr (vmount_info, VMT_OBJECT),
vmt2dataptr (vmount_info, VMT_STUB),
fs_info == NULL ? "unknown" : fs_info->vfsent_name,
+ NULL,
is_read_only);
return_list = g_list_prepend (return_list, mount_entry);
@@ -842,6 +853,7 @@ _g_get_unix_mounts (void)
mount_entry = create_unix_mount_entry (mntent[i].f_mntfromname,
mntent[i].f_mntonname,
mntent[i].f_fstypename,
+ NULL,
is_read_only);
return_list = g_list_prepend (return_list, mount_entry);
@@ -1985,6 +1997,7 @@ g_unix_mount_free (GUnixMountEntry *mount_entry)
g_free (mount_entry->mount_path);
g_free (mount_entry->device_path);
g_free (mount_entry->filesystem_type);
+ g_free (mount_entry->options);
g_free (mount_entry);
}
@@ -2009,6 +2022,7 @@ g_unix_mount_copy (GUnixMountEntry *mount_entry)
copy->mount_path = g_strdup (mount_entry->mount_path);
copy->device_path = g_strdup (mount_entry->device_path);
copy->filesystem_type = g_strdup (mount_entry->filesystem_type);
+ copy->options = g_strdup (mount_entry->options);
copy->is_read_only = mount_entry->is_read_only;
copy->is_system_internal = mount_entry->is_system_internal;
@@ -2092,6 +2106,10 @@ g_unix_mount_compare (GUnixMountEntry *mount1,
if (res != 0)
return res;
+ res = g_strcmp0 (mount1->options, mount2->options);
+ if (res != 0)
+ return res;
+
res = mount1->is_read_only - mount2->is_read_only;
if (res != 0)
return res;
@@ -2148,6 +2166,29 @@ g_unix_mount_get_fs_type (GUnixMountEntry *mount_entry)
}
/**
+ * g_unix_mount_get_options:
+ * @mount_entry: a #GUnixMountEntry.
+ *
+ * Gets a comma-separated list of mount options for the unix mount. For example,
+ * `rw,relatime,seclabel,data=ordered`.
+ *
+ * This is similar to g_unix_mount_point_get_options(), but it takes
+ * a #GUnixMountEntry as an argument.
+ *
+ * Returns: (nullable): a string containing the options, or %NULL if not
+ * available.
+ *
+ * Since: 2.58
+ */
+const gchar *
+g_unix_mount_get_options (GUnixMountEntry *mount_entry)
+{
+ g_return_val_if_fail (mount_entry != NULL, NULL);
+
+ return mount_entry->options;
+}
+
+/**
* g_unix_mount_is_readonly:
* @mount_entry: a #GUnixMount.
*
@@ -2684,18 +2725,29 @@ g_unix_mount_guess_should_display (GUnixMountEntry *mount_entry)
mount_path = mount_entry->mount_path;
if (mount_path != NULL)
{
+ const gboolean running_as_root = (getuid () == 0);
gboolean is_in_runtime_dir = FALSE;
+
/* Hide mounts within a dot path, suppose it was a purpose to hide this mount */
if (g_strstr_len (mount_path, -1, "/.") != NULL)
return FALSE;
- /* Check /run/media/$USER/ */
- user_name = g_get_user_name ();
- user_name_len = strlen (user_name);
- if (strncmp (mount_path, "/run/media/", sizeof ("/run/media/") - 1) == 0 &&
- strncmp (mount_path + sizeof ("/run/media/") - 1, user_name, user_name_len) == 0 &&
- mount_path[sizeof ("/run/media/") - 1 + user_name_len] == '/')
- is_in_runtime_dir = TRUE;
+ /* Check /run/media/$USER/. If running as root, display any mounts below
+ * /run/media/. */
+ if (running_as_root)
+ {
+ if (strncmp (mount_path, "/run/media/", strlen ("/run/media/")) == 0)
+ is_in_runtime_dir = TRUE;
+ }
+ else
+ {
+ user_name = g_get_user_name ();
+ user_name_len = strlen (user_name);
+ if (strncmp (mount_path, "/run/media/", strlen ("/run/media/")) == 0 &&
+ strncmp (mount_path + strlen ("/run/media/"), user_name, user_name_len) == 0 &&
+ mount_path[strlen ("/run/media/") + user_name_len] == '/')
+ is_in_runtime_dir = TRUE;
+ }
if (is_in_runtime_dir || g_str_has_prefix (mount_path, "/media/"))
{
diff --git a/gio/gunixmounts.h b/gio/gunixmounts.h
index 04d6b0726..a392d497f 100644
--- a/gio/gunixmounts.h
+++ b/gio/gunixmounts.h
@@ -81,6 +81,8 @@ GLIB_AVAILABLE_IN_ALL
const char * g_unix_mount_get_device_path (GUnixMountEntry *mount_entry);
GLIB_AVAILABLE_IN_ALL
const char * g_unix_mount_get_fs_type (GUnixMountEntry *mount_entry);
+GLIB_AVAILABLE_IN_2_58
+const char * g_unix_mount_get_options (GUnixMountEntry *mount_entry);
GLIB_AVAILABLE_IN_ALL
gboolean g_unix_mount_is_readonly (GUnixMountEntry *mount_entry);
GLIB_AVAILABLE_IN_ALL
diff --git a/gio/gunixvolume.c b/gio/gunixvolume.c
index a3768e11d..b54d1fd6e 100644
--- a/gio/gunixvolume.c
+++ b/gio/gunixvolume.c
@@ -274,7 +274,6 @@ eject_mount_done (GObject *source,
GTask *task = user_data;
GError *error = NULL;
gchar *stderr_str;
- GUnixVolume *unix_volume;
if (!g_subprocess_communicate_utf8_finish (subprocess, result, NULL, &stderr_str, &error))
{
@@ -287,12 +286,8 @@ eject_mount_done (GObject *source,
/* ...but bad exit code */
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", stderr_str);
else
- {
- /* ...and successful exit code */
- unix_volume = G_UNIX_VOLUME (g_task_get_source_object (task));
- _g_unix_volume_monitor_update (G_UNIX_VOLUME_MONITOR (unix_volume->volume_monitor));
- g_task_return_boolean (task, TRUE);
- }
+ /* ...and successful exit code */
+ g_task_return_boolean (task, TRUE);
g_free (stderr_str);
}
diff --git a/gio/gunixvolumemonitor.c b/gio/gunixvolumemonitor.c
index 4b99423d7..b7711ff52 100644
--- a/gio/gunixvolumemonitor.c
+++ b/gio/gunixvolumemonitor.c
@@ -183,21 +183,15 @@ g_unix_volume_monitor_class_init (GUnixVolumeMonitorClass *klass)
native_class->get_mount_for_mount_path = get_mount_for_mount_path;
}
-void
-_g_unix_volume_monitor_update (GUnixVolumeMonitor *unix_monitor)
-{
- /* Update both to make sure volumes are created before mounts */
- update_volumes (unix_monitor);
- update_mounts (unix_monitor);
-}
-
static void
mountpoints_changed (GUnixMountMonitor *mount_monitor,
gpointer user_data)
{
GUnixVolumeMonitor *unix_monitor = user_data;
- _g_unix_volume_monitor_update (unix_monitor);
+ /* Update both to make sure volumes are created before mounts */
+ update_volumes (unix_monitor);
+ update_mounts (unix_monitor);
}
static void
@@ -206,7 +200,9 @@ mounts_changed (GUnixMountMonitor *mount_monitor,
{
GUnixVolumeMonitor *unix_monitor = user_data;
- _g_unix_volume_monitor_update (unix_monitor);
+ /* Update both to make sure volumes are created before mounts */
+ update_volumes (unix_monitor);
+ update_mounts (unix_monitor);
}
static void
@@ -223,7 +219,8 @@ g_unix_volume_monitor_init (GUnixVolumeMonitor *unix_monitor)
"mountpoints-changed", G_CALLBACK (mountpoints_changed),
unix_monitor);
- _g_unix_volume_monitor_update (unix_monitor);
+ update_volumes (unix_monitor);
+ update_mounts (unix_monitor);
}
GVolumeMonitor *
diff --git a/gio/gunixvolumemonitor.h b/gio/gunixvolumemonitor.h
index 14e07fb9f..4f54fc23c 100644
--- a/gio/gunixvolumemonitor.h
+++ b/gio/gunixvolumemonitor.h
@@ -55,7 +55,6 @@ GType _g_unix_volume_monitor_get_type (void) G_GN
GVolumeMonitor * _g_unix_volume_monitor_new (void);
GUnixVolume * _g_unix_volume_monitor_lookup_volume_for_mount_path (GUnixVolumeMonitor *monitor,
const char *mount_path);
-void _g_unix_volume_monitor_update (GUnixVolumeMonitor *monitor);
G_END_DECLS
diff --git a/gio/gwin32notificationbackend.c b/gio/gwin32notificationbackend.c
new file mode 100644
index 000000000..7200fdffb
--- /dev/null
+++ b/gio/gwin32notificationbackend.c
@@ -0,0 +1,90 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2018 Endless Mobile, Inc.
+ *
+ * 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/>.
+ *
+ * Authors:
+ * - Philip Withnall <withnall@endlessm.com>
+ */
+
+#include "config.h"
+
+#include "gnotificationbackend.h"
+
+#include "giomodule-priv.h"
+#include "gnotification-private.h"
+
+#define G_TYPE_WIN32_NOTIFICATION_BACKEND (g_win32_notification_backend_get_type ())
+#define G_WIN32_NOTIFICATION_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_NOTIFICATION_BACKEND, GWin32NotificationBackend))
+
+typedef struct _GWin32NotificationBackend GWin32NotificationBackend;
+typedef GNotificationBackendClass GWin32NotificationBackendClass;
+
+struct _GWin32NotificationBackend
+{
+ GNotificationBackend parent;
+};
+
+GType g_win32_notification_backend_get_type (void);
+
+G_DEFINE_TYPE_WITH_CODE (GWin32NotificationBackend, g_win32_notification_backend, G_TYPE_NOTIFICATION_BACKEND,
+ _g_io_modules_ensure_extension_points_registered ();
+ g_io_extension_point_implement (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME,
+ g_define_type_id, "win32", 0))
+
+static gboolean
+g_win32_notification_backend_is_supported (void)
+{
+ /* This is the only backend supported on Windows, and always needs to be
+ * present to avoid no backend being selected. */
+ return TRUE;
+}
+
+static void
+g_win32_notification_backend_send_notification (GNotificationBackend *backend,
+ const gchar *id,
+ GNotification *notification)
+{
+ /* FIXME: See https://bugzilla.gnome.org/show_bug.cgi?id=776583. This backend
+ * exists purely to stop crashes when applications use g_notification*()
+ * on Windows, by providing a dummy backend implementation. (The alternative
+ * was to modify all of the backend call sites in g_notification*(), which
+ * seemed less scalable.) */
+ g_warning ("Notifications are not yet supported on Windows.");
+}
+
+static void
+g_win32_notification_backend_withdraw_notification (GNotificationBackend *backend,
+ const gchar *id)
+{
+ /* FIXME: Nothing needs doing here until send_notification() is implemented. */
+}
+
+static void
+g_win32_notification_backend_init (GWin32NotificationBackend *backend)
+{
+}
+
+static void
+g_win32_notification_backend_class_init (GWin32NotificationBackendClass *class)
+{
+ GNotificationBackendClass *backend_class = G_NOTIFICATION_BACKEND_CLASS (class);
+
+ backend_class->is_supported = g_win32_notification_backend_is_supported;
+ backend_class->send_notification = g_win32_notification_backend_send_notification;
+ backend_class->withdraw_notification = g_win32_notification_backend_withdraw_notification;
+}
diff --git a/gio/gzlibcompressor.c b/gio/gzlibcompressor.c
index 239d143cc..53f3e4745 100644
--- a/gio/gzlibcompressor.c
+++ b/gio/gzlibcompressor.c
@@ -90,7 +90,7 @@ g_zlib_compressor_set_gzheader (GZlibCompressor *compressor)
G_FILE_ATTRIBUTE_TIME_MODIFIED);
if (deflateSetHeader (&compressor->zstream, &compressor->gzheader) != Z_OK)
- g_warning ("unexpected zlib error: %s\n", compressor->zstream.msg);
+ g_warning ("unexpected zlib error: %s", compressor->zstream.msg);
#endif /* !G_OS_WIN32 || ZLIB >= 1.2.4 */
}
@@ -211,7 +211,7 @@ g_zlib_compressor_constructed (GObject *object)
g_error ("GZlibCompressor: Not enough memory for zlib use");
if (res != Z_OK)
- g_warning ("unexpected zlib error: %s\n", compressor->zstream.msg);
+ g_warning ("unexpected zlib error: %s", compressor->zstream.msg);
g_zlib_compressor_set_gzheader (compressor);
}
@@ -351,7 +351,7 @@ g_zlib_compressor_reset (GConverter *converter)
res = deflateReset (&compressor->zstream);
if (res != Z_OK)
- g_warning ("unexpected zlib error: %s\n", compressor->zstream.msg);
+ g_warning ("unexpected zlib error: %s", compressor->zstream.msg);
/* deflateReset reset the header too, so re-set it */
g_zlib_compressor_set_gzheader (compressor);
diff --git a/gio/gzlibdecompressor.c b/gio/gzlibdecompressor.c
index d16d3f717..cf2542ef8 100644
--- a/gio/gzlibdecompressor.c
+++ b/gio/gzlibdecompressor.c
@@ -95,7 +95,7 @@ g_zlib_decompressor_set_gzheader (GZlibDecompressor *decompressor)
decompressor->header_data->gzheader.name_max = 256;
if (inflateGetHeader (&decompressor->zstream, &decompressor->header_data->gzheader) != Z_OK)
- g_warning ("unexpected zlib error: %s\n", decompressor->zstream.msg);
+ g_warning ("unexpected zlib error: %s", decompressor->zstream.msg);
#endif /* !G_OS_WIN32 || ZLIB >= 1.2.4 */
}
@@ -205,7 +205,7 @@ g_zlib_decompressor_constructed (GObject *object)
g_error ("GZlibDecompressor: Not enough memory for zlib use");
if (res != Z_OK)
- g_warning ("unexpected zlib error: %s\n", decompressor->zstream.msg);
+ g_warning ("unexpected zlib error: %s", decompressor->zstream.msg);
g_zlib_decompressor_set_gzheader (decompressor);
}
@@ -305,7 +305,7 @@ g_zlib_decompressor_reset (GConverter *converter)
res = inflateReset (&decompressor->zstream);
if (res != Z_OK)
- g_warning ("unexpected zlib error: %s\n", decompressor->zstream.msg);
+ g_warning ("unexpected zlib error: %s", decompressor->zstream.msg);
g_zlib_decompressor_set_gzheader (decompressor);
}
diff --git a/gio/inotify/inotify-helper.c b/gio/inotify/inotify-helper.c
index 0a0a84ab9..d94458753 100644
--- a/gio/inotify/inotify-helper.c
+++ b/gio/inotify/inotify-helper.c
@@ -205,6 +205,8 @@ ih_event_callback (ik_event_t *event,
/* unpaired event -- no 'other' field */
interesting = g_file_monitor_source_handle_event (sub->user_data, event_flags,
event->name, NULL, NULL, event->timestamp);
+ else
+ interesting = FALSE;
if (event->mask & IN_CREATE)
{
diff --git a/gio/kqueue/Makefile.am b/gio/kqueue/Makefile.am
index d5657d7e4..24e9724e5 100644
--- a/gio/kqueue/Makefile.am
+++ b/gio/kqueue/Makefile.am
@@ -4,19 +4,9 @@ noinst_LTLIBRARIES += libkqueue.la
libkqueue_la_SOURCES = \
gkqueuefilemonitor.c \
- gkqueuefilemonitor.h \
kqueue-helper.c \
kqueue-helper.h \
- kqueue-thread.c \
- kqueue-thread.h \
- kqueue-sub.c \
- kqueue-sub.h \
kqueue-missing.c \
- kqueue-missing.h \
- kqueue-utils.c \
- kqueue-utils.h \
- kqueue-exclusions.c \
- kqueue-exclusions.h \
dep-list.c \
dep-list.h \
$(NULL)
diff --git a/gio/kqueue/dep-list.c b/gio/kqueue/dep-list.c
index af0010c72..d8c3d8a01 100644
--- a/gio/kqueue/dep-list.c
+++ b/gio/kqueue/dep-list.c
@@ -84,18 +84,22 @@ dep_list* dl_create (char *path, ino_t inode)
dep_list*
dl_shallow_copy (const dep_list *dl)
{
+ dep_list *head;
+ dep_list *cp;
+ const dep_list *it;
+
if (dl == NULL) {
return NULL;
}
- dep_list *head = calloc (1, sizeof (dep_list));
+ head = calloc (1, sizeof (dep_list));
if (head == NULL) {
perror_msg ("Failed to allocate head during shallow copy");
return NULL;
}
- dep_list *cp = head;
- const dep_list *it = dl;
+ cp = head;
+ it = dl;
while (it != NULL) {
cp->path = it->path;
@@ -162,15 +166,19 @@ dl_free (dep_list *dl)
dep_list*
dl_listing (const char *path)
{
- assert (path != NULL);
-
dep_list *head = NULL;
dep_list *prev = NULL;
- DIR *dir = opendir (path);
+ DIR *dir;
+
+ assert (path != NULL);
+
+ dir = opendir (path);
if (dir != NULL) {
struct dirent *ent;
while ((ent = readdir (dir)) != NULL) {
+ dep_list *iter;
+
if (!strcmp (ent->d_name, ".") || !strcmp (ent->d_name, "..")) {
continue;
}
@@ -183,7 +191,7 @@ dl_listing (const char *path)
}
}
- dep_list *iter = (prev == NULL) ? head : calloc (1, sizeof (dep_list));
+ iter = (prev == NULL) ? head : calloc (1, sizeof (dep_list));
if (iter == NULL) {
perror_msg ("Failed to allocate a new element during listing");
goto error;
@@ -229,6 +237,9 @@ error:
void
dl_diff (dep_list **before, dep_list **after)
{
+ dep_list *before_iter;
+ dep_list *before_prev;
+
assert (before != NULL);
assert (after != NULL);
@@ -236,12 +247,13 @@ dl_diff (dep_list **before, dep_list **after)
return;
}
- dep_list *before_iter = *before;
- dep_list *before_prev = NULL;
+ before_iter = *before;
+ before_prev = NULL;
while (before_iter != NULL) {
dep_list *after_iter = *after;
dep_list *after_prev = NULL;
+ dep_list *oldptr;
int matched = 0;
while (after_iter != NULL) {
@@ -266,7 +278,7 @@ dl_diff (dep_list **before, dep_list **after)
after_iter = after_iter->next;
}
- dep_list *oldptr = before_iter;
+ oldptr = before_iter;
before_iter = before_iter->next;
if (matched == 0) {
before_prev = oldptr;
@@ -283,17 +295,21 @@ dl_diff (dep_list **before, dep_list **after)
* from the both lists.
**/
#define EXCLUDE_SIMILAR(removed_list, added_list, match_expr, matched_code) \
+G_STMT_START { \
+ dep_list *removed_list##_iter; \
+ dep_list *removed_list##_prev; \
+ int productive = 0; \
+ \
assert (removed_list != NULL); \
assert (added_list != NULL); \
\
- dep_list *removed_list##_iter = *removed_list; \
- dep_list *removed_list##_prev = NULL; \
- \
- int productive = 0; \
+ removed_list##_iter = *removed_list; \
+ removed_list##_prev = NULL; \
\
while (removed_list##_iter != NULL) { \
dep_list *added_list##_iter = *added_list; \
dep_list *added_list##_prev = NULL; \
+ dep_list *oldptr; \
\
int matched = 0; \
while (added_list##_iter != NULL) { \
@@ -317,7 +333,7 @@ dl_diff (dep_list **before, dep_list **after)
} \
added_list##_iter = added_list##_iter->next; \
} \
- dep_list *oldptr = removed_list##_iter; \
+ oldptr = removed_list##_iter; \
removed_list##_iter = removed_list##_iter->next; \
if (matched == 0) { \
removed_list##_prev = oldptr; \
@@ -325,7 +341,8 @@ dl_diff (dep_list **before, dep_list **after)
free (oldptr); \
} \
} \
- return (productive > 0);
+ return (productive > 0); \
+} G_STMT_END
#define cb_invoke(cbs, name, udata, ...) \
@@ -488,15 +505,14 @@ dl_calculate (dep_list *before,
const traverse_cbs *cbs,
void *udata)
{
- assert (cbs != NULL);
-
int need_update = 0;
-
dep_list *was = dl_shallow_copy (before);
dep_list *pre = dl_shallow_copy (before);
dep_list *now = dl_shallow_copy (after);
dep_list *lst = dl_shallow_copy (after);
+ assert (cbs != NULL);
+
dl_diff (&was, &now);
need_update += dl_detect_moves (&was, &now, cbs, udata);
diff --git a/gio/kqueue/gkqueuefilemonitor.c b/gio/kqueue/gkqueuefilemonitor.c
index 78b749637..d6fea41cf 100644
--- a/gio/kqueue/gkqueuefilemonitor.c
+++ b/gio/kqueue/gkqueuefilemonitor.c
@@ -22,33 +22,73 @@
#include "config.h"
-#include "gkqueuefilemonitor.h"
-#include "kqueue-helper.h"
-#include "kqueue-exclusions.h"
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <glib-object.h>
+#include <gio/gfilemonitor.h>
+#include <gio/glocalfilemonitor.h>
+#include <gio/giomodule.h>
#include <gio/gpollfilemonitor.h>
#include <gio/gfile.h>
-#include <gio/giomodule.h>
+#include <glib-unix.h>
+#include "glib-private.h"
+
+#include "kqueue-helper.h"
+#include "dep-list.h"
+
+G_LOCK_DEFINE_STATIC (kq_lock);
+static GSource *kq_source;
+static int kq_queue = -1;
+
+#define G_TYPE_KQUEUE_FILE_MONITOR (g_kqueue_file_monitor_get_type ())
+#define G_KQUEUE_FILE_MONITOR(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+ G_TYPE_KQUEUE_FILE_MONITOR, GKqueueFileMonitor))
+typedef GLocalFileMonitorClass GKqueueFileMonitorClass;
-struct _GKqueueFileMonitor
+typedef struct
{
GLocalFileMonitor parent_instance;
kqueue_sub *sub;
-
+#ifndef O_EVTONLY
GFileMonitor *fallback;
GFile *fbfile;
-};
+#endif
+} GKqueueFileMonitor;
+
+GType g_kqueue_file_monitor_get_type (void);
+G_DEFINE_TYPE_WITH_CODE (GKqueueFileMonitor, g_kqueue_file_monitor, G_TYPE_LOCAL_FILE_MONITOR,
+ g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
+ g_define_type_id,
+ "kqueue",
+ 20))
+
+#ifndef O_EVTONLY
+#define O_KQFLAG O_RDONLY
+#else
+#define O_KQFLAG O_EVTONLY
+#endif
+
+#define NOTE_ALL (NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_RENAME)
static gboolean g_kqueue_file_monitor_cancel (GFileMonitor* monitor);
+static gboolean g_kqueue_file_monitor_is_supported (void);
-G_DEFINE_TYPE_WITH_CODE (GKqueueFileMonitor, g_kqueue_file_monitor, G_TYPE_LOCAL_FILE_MONITOR,
- g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
- g_define_type_id,
- "kqueue",
- 20))
+static kqueue_sub *_kqsub_new (const gchar *, GLocalFileMonitor *, GFileMonitorSource *);
+static void _kqsub_free (kqueue_sub *);
+static gboolean _kqsub_cancel (kqueue_sub *);
+#ifndef O_EVTONLY
static void
_fallback_callback (GFileMonitor *unused,
GFile *first,
@@ -57,21 +97,41 @@ _fallback_callback (GFileMonitor *unused,
gpointer udata)
{
GKqueueFileMonitor *kq_mon = G_KQUEUE_FILE_MONITOR (udata);
- GFileMonitor *mon = G_FILE_MONITOR (kq_mon);
- g_assert (kq_mon != NULL);
- g_assert (mon != NULL);
- (void) unused;
- if (event == G_FILE_MONITOR_EVENT_CHANGED)
- {
- GLocalFileMonitor *local_monitor = G_LOCAL_FILE_MONITOR (kq_mon);
-
- _kh_dir_diff (kq_mon->sub, local_monitor->source);
- }
- else
- g_file_monitor_emit_event (mon, first, second, event);
+ g_file_monitor_emit_event (G_FILE_MONITOR (kq_mon), first, second, event);
}
+/*
+ * _ke_is_excluded:
+ * @full_path - a path to file to check.
+ *
+ * Returns: TRUE if the file should be excluded from the kqueue-powered
+ * monitoring, FALSE otherwise.
+ **/
+gboolean
+_ke_is_excluded (const char *full_path)
+{
+ GFile *f = NULL;
+ GMount *mount = NULL;
+
+ f = g_file_new_for_path (full_path);
+
+ if (f != NULL) {
+ mount = g_file_find_enclosing_mount (f, NULL, NULL);
+ g_object_unref (f);
+ }
+
+ if ((mount != NULL && (g_mount_can_unmount (mount))) || g_str_has_prefix (full_path, "/mnt/"))
+ {
+ g_warning ("Excluding %s from kernel notification, falling back to poll", full_path);
+ if (mount)
+ g_object_unref (mount);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif /* !O_EVTONLY */
static void
g_kqueue_file_monitor_finalize (GObject *object)
@@ -80,16 +140,18 @@ g_kqueue_file_monitor_finalize (GObject *object)
if (kqueue_monitor->sub)
{
- _kh_cancel_sub (kqueue_monitor->sub);
- _kh_sub_free (kqueue_monitor->sub);
+ _kqsub_cancel (kqueue_monitor->sub);
+ _kqsub_free (kqueue_monitor->sub);
kqueue_monitor->sub = NULL;
}
+#ifndef O_EVTONLY
if (kqueue_monitor->fallback)
g_object_unref (kqueue_monitor->fallback);
if (kqueue_monitor->fbfile)
g_object_unref (kqueue_monitor->fbfile);
+#endif
if (G_OBJECT_CLASS (g_kqueue_file_monitor_parent_class)->finalize)
(*G_OBJECT_CLASS (g_kqueue_file_monitor_parent_class)->finalize) (object);
@@ -103,21 +165,25 @@ g_kqueue_file_monitor_start (GLocalFileMonitor *local_monitor,
GFileMonitorSource *source)
{
GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (local_monitor);
- GObject *obj;
- GKqueueFileMonitorClass *klass;
- GObjectClass *parent_class;
- kqueue_sub *sub = NULL;
- gboolean ret_kh_startup = FALSE;
- const gchar *path = NULL;
-
-
- ret_kh_startup = _kh_startup ();
- g_assert (ret_kh_startup);
+ kqueue_sub *sub;
+ const gchar *path;
path = filename;
- if (!path)
+ if (path == NULL)
path = dirname;
+#ifndef O_EVTONLY
+ if (_ke_is_excluded (path))
+ {
+ GFile *file = g_file_new_for_path (path);
+ kqueue_monitor->fbfile = file;
+ kqueue_monitor->fallback = _g_poll_file_monitor_new (file);
+ g_signal_connect (kqueue_monitor->fallback, "changed",
+ G_CALLBACK (_fallback_callback), kqueue_monitor);
+ return;
+ }
+#endif
+
/* For a directory monitor, create a subscription object anyway.
* It will be used for directory diff calculation routines.
* Wait, directory diff in a GKqueueFileMonitor?
@@ -125,33 +191,13 @@ g_kqueue_file_monitor_start (GLocalFileMonitor *local_monitor,
* file, GIO uses a GKqueueFileMonitor object for that. If a directory
* will be created under that path, GKqueueFileMonitor will have to
* handle the directory notifications. */
+ sub = _kqsub_new (path, local_monitor, source);
+ if (sub == NULL)
+ return;
- sub = _kh_sub_new (path, TRUE, source);
-
- /* FIXME: what to do about errors here? we can't return NULL or another
- * kind of error and an assertion is probably too hard (same issue as in
- * the inotify backend) */
- g_assert (sub != NULL);
kqueue_monitor->sub = sub;
-
- if (!_ke_is_excluded (path))
- _kh_add_sub (sub);
- else
- {
- GFile *file = g_file_new_for_path (path);
- kqueue_monitor->fbfile = file;
- kqueue_monitor->fallback = _g_poll_file_monitor_new (file);
- g_signal_connect (kqueue_monitor->fallback,
- "changed",
- G_CALLBACK (_fallback_callback),
- kqueue_monitor);
- }
-}
-
-static gboolean
-g_kqueue_file_monitor_is_supported (void)
-{
- return _kh_startup ();
+ if (!_kqsub_start_watching (sub))
+ _km_add_missing (sub);
}
static void
@@ -175,24 +221,218 @@ g_kqueue_file_monitor_init (GKqueueFileMonitor *monitor)
}
static gboolean
+g_kqueue_file_monitor_callback (gint fd, GIOCondition condition, gpointer user_data)
+{
+ gint64 now = g_source_get_time (kq_source);
+ kqueue_sub *sub;
+ GFileMonitorSource *source;
+ struct kevent ev;
+ struct timespec ts;
+
+ memset (&ts, 0, sizeof(ts));
+ while (kevent(fd, NULL, 0, &ev, 1, &ts) > 0)
+ {
+ GFileMonitorEvent mask = 0;
+
+ if (ev.filter != EVFILT_VNODE || ev.udata == NULL)
+ continue;
+
+ sub = ev.udata;
+ source = sub->source;
+
+ if (ev.flags & EV_ERROR)
+ ev.fflags = NOTE_REVOKE;
+
+ if (ev.fflags & (NOTE_DELETE | NOTE_REVOKE))
+ {
+ _kqsub_cancel (sub);
+ _km_add_missing (sub);
+ }
+
+ if (sub->is_dir && ev.fflags & (NOTE_WRITE | NOTE_EXTEND))
+ {
+ _kh_dir_diff (sub);
+ ev.fflags &= ~(NOTE_WRITE | NOTE_EXTEND);
+ }
+
+ if (ev.fflags & NOTE_DELETE)
+ {
+ mask = G_FILE_MONITOR_EVENT_DELETED;
+ }
+ else if (ev.fflags & NOTE_ATTRIB)
+ {
+ mask = G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED;
+ }
+ else if (ev.fflags & (NOTE_WRITE | NOTE_EXTEND))
+ {
+ mask = G_FILE_MONITOR_EVENT_CHANGED;
+ }
+ else if (ev.fflags & NOTE_RENAME)
+ {
+ /* Since there’s apparently no way to get the new name of the
+ * file out of kqueue(), all we can do is say that this one has
+ * been deleted. */
+ mask = G_FILE_MONITOR_EVENT_DELETED;
+ }
+ else if (ev.fflags & NOTE_REVOKE)
+ {
+ mask = G_FILE_MONITOR_EVENT_UNMOUNTED;
+ }
+
+ if (mask)
+ g_file_monitor_source_handle_event (source, mask, NULL, NULL, NULL, now);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+g_kqueue_file_monitor_is_supported (void)
+{
+ int errsv;
+
+ G_LOCK (kq_lock);
+
+ if (kq_queue == -1)
+ {
+ kq_queue = kqueue ();
+ errsv = errno;
+
+ if (kq_queue == -1)
+ {
+ g_warning ("Unable to create a kqueue: %s", g_strerror (errsv));
+ G_UNLOCK (kq_lock);
+ return FALSE;
+ }
+
+ kq_source = g_unix_fd_source_new (kq_queue, G_IO_IN);
+ g_source_set_callback (kq_source, (GSourceFunc) g_kqueue_file_monitor_callback, NULL, NULL);
+ g_source_attach (kq_source, GLIB_PRIVATE_CALL (g_get_worker_context) ());
+ }
+
+ G_UNLOCK (kq_lock);
+
+ return TRUE;
+}
+
+static gboolean
g_kqueue_file_monitor_cancel (GFileMonitor *monitor)
{
GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (monitor);
if (kqueue_monitor->sub)
{
- _kh_cancel_sub (kqueue_monitor->sub);
- _kh_sub_free (kqueue_monitor->sub);
+ _kqsub_cancel (kqueue_monitor->sub);
+ _kqsub_free (kqueue_monitor->sub);
kqueue_monitor->sub = NULL;
}
+#ifndef O_EVTONLY
else if (kqueue_monitor->fallback)
{
g_signal_handlers_disconnect_by_func (kqueue_monitor->fallback, _fallback_callback, kqueue_monitor);
g_file_monitor_cancel (kqueue_monitor->fallback);
}
+#endif
if (G_FILE_MONITOR_CLASS (g_kqueue_file_monitor_parent_class)->cancel)
(*G_FILE_MONITOR_CLASS (g_kqueue_file_monitor_parent_class)->cancel) (monitor);
return TRUE;
}
+
+static kqueue_sub *
+_kqsub_new (const gchar *filename, GLocalFileMonitor *mon, GFileMonitorSource *source)
+{
+ kqueue_sub *sub;
+
+ sub = g_slice_new (kqueue_sub);
+ sub->filename = g_strdup (filename);
+ sub->mon = mon;
+ g_source_ref ((GSource *) source);
+ sub->source = source;
+ sub->fd = -1;
+ sub->deps = NULL;
+ sub->is_dir = 0;
+
+ return sub;
+}
+
+static void
+_kqsub_free (kqueue_sub *sub)
+{
+ g_assert (sub->deps == NULL);
+ g_assert (sub->fd == -1);
+
+ g_source_unref ((GSource *) sub->source);
+ g_free (sub->filename);
+ g_slice_free (kqueue_sub, sub);
+}
+
+static gboolean
+_kqsub_cancel (kqueue_sub *sub)
+{
+ struct kevent ev;
+
+ /* Remove the event and close the file descriptor to automatically
+ * delete pending events. */
+ if (sub->fd != -1)
+ {
+ EV_SET (&ev, sub->fd, EVFILT_VNODE, EV_DELETE, NOTE_ALL, 0, sub);
+ if (kevent (kq_queue, &ev, 1, NULL, 0, NULL) == -1)
+ {
+ g_warning ("Unable to remove event for %s: %s", sub->filename, g_strerror (errno));
+ return FALSE;
+ }
+ close (sub->fd);
+ sub->fd = -1;
+ }
+
+ _km_remove (sub);
+
+ if (sub->deps)
+ {
+ dl_free (sub->deps);
+ sub->deps = NULL;
+ }
+
+ return TRUE;
+}
+
+gboolean
+_kqsub_start_watching (kqueue_sub *sub)
+{
+ struct stat st;
+ struct kevent ev;
+
+ sub->fd = open (sub->filename, O_KQFLAG);
+ if (sub->fd == -1)
+ return FALSE;
+
+ if (fstat (sub->fd, &st) == -1)
+ {
+ g_warning ("fstat failed for %s: %s", sub->filename, g_strerror (errno));
+ close (sub->fd);
+ sub->fd = -1;
+ return FALSE;
+ }
+
+ sub->is_dir = (st.st_mode & S_IFDIR) ? 1 : 0;
+ if (sub->is_dir)
+ {
+ if (sub->deps)
+ dl_free (sub->deps);
+
+ sub->deps = dl_listing (sub->filename);
+ }
+
+ EV_SET (&ev, sub->fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_ALL, 0, sub);
+ if (kevent (kq_queue, &ev, 1, NULL, 0, NULL) == -1)
+ {
+ g_warning ("Unable to add event for %s: %s", sub->filename, g_strerror (errno));
+ close (sub->fd);
+ sub->fd = -1;
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/gio/kqueue/gkqueuefilemonitor.h b/gio/kqueue/gkqueuefilemonitor.h
deleted file mode 100644
index 32752f105..000000000
--- a/gio/kqueue/gkqueuefilemonitor.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2011, 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#ifndef __G_KQUEUE_FILE_MONITOR_H__
-#define __G_KQUEUE_FILE_MONITOR_H__
-
-#include <glib-object.h>
-#include <string.h>
-#include <gio/gfilemonitor.h>
-#include <gio/glocalfilemonitor.h>
-#include <gio/giomodule.h>
-
-G_BEGIN_DECLS
-
-#define G_TYPE_KQUEUE_FILE_MONITOR (g_kqueue_file_monitor_get_type ())
-#define G_KQUEUE_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_KQUEUE_FILE_MONITOR, GKqueueFileMonitor))
-#define G_KQUEUE_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_KQUEUE_FILE_MONITOR, GKqueueFileMonitorClass))
-#define G_IS_KQUEUE_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_KQUEUE_FILE_MONITOR))
-#define G_IS_KQUEUE_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_KQUEUE_FILE_MONITOR))
-
-typedef struct _GKqueueFileMonitor GKqueueFileMonitor;
-typedef struct _GKqueueFileMonitorClass GKqueueFileMonitorClass;
-
-struct _GKqueueFileMonitorClass {
- GLocalFileMonitorClass parent_class;
-};
-
-GType g_kqueue_file_monitor_get_type (void);
-
-G_END_DECLS
-
-#endif /* __G_KQUEUE_FILE_MONITOR_H__ */
diff --git a/gio/kqueue/kqueue-exclusions.c b/gio/kqueue/kqueue-exclusions.c
deleted file mode 100644
index 748d7a92a..000000000
--- a/gio/kqueue/kqueue-exclusions.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
- Copyright (c) 2012 Antoine Jacoutot <ajacoutot@openbsd.org>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#include <fcntl.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include "kqueue-exclusions.h"
-
-static gboolean ke_debug_enabled = FALSE;
-#define KE_W if (ke_debug_enabled) g_warning
-
-/*
- * _ke_is_excluded:
- * @full_path - a path to file to check.
- *
- * Returns: TRUE if the file should be excluded from the kqueue-powered
- * monitoring, FALSE otherwise.
- **/
-gboolean
-_ke_is_excluded (const char *full_path)
-{
-#if defined (O_EVTONLY)
- return FALSE;
-#else
- GFile *f = NULL;
- GMount *mount = NULL;
-
- f = g_file_new_for_path (full_path);
-
- if (f != NULL) {
- mount = g_file_find_enclosing_mount (f, NULL, NULL);
- g_object_unref (f);
- }
-
- if ((mount != NULL && (g_mount_can_unmount (mount))) || g_str_has_prefix (full_path, "/mnt/"))
- {
- KE_W ("Excluding %s from kernel notification, falling back to poll", full_path);
- if (mount)
- g_object_unref (mount);
- return TRUE;
- }
- else
- return FALSE;
-#endif
-}
diff --git a/gio/kqueue/kqueue-exclusions.h b/gio/kqueue/kqueue-exclusions.h
deleted file mode 100644
index f1dad0e7e..000000000
--- a/gio/kqueue/kqueue-exclusions.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#ifndef __KQUEUE_EXCLUSIONS_H
-#define __KQUEUE_EXCLUSIONS_H
-
-gboolean _ke_is_excluded (const char *full_path);
-
-#endif /* __KQUEUE_EXCLUDES_H */
diff --git a/gio/kqueue/kqueue-helper.c b/gio/kqueue/kqueue-helper.c
index e7d583c8b..497c30b15 100644
--- a/gio/kqueue/kqueue-helper.c
+++ b/gio/kqueue/kqueue-helper.c
@@ -34,83 +34,6 @@
#include <errno.h>
#include <pthread.h>
#include "kqueue-helper.h"
-#include "kqueue-utils.h"
-#include "kqueue-thread.h"
-#include "kqueue-missing.h"
-#include "kqueue-exclusions.h"
-
-static gboolean kh_debug_enabled = FALSE;
-#define KH_W if (kh_debug_enabled) g_warning
-
-static GHashTable *subs_hash_table = NULL;
-G_LOCK_DEFINE_STATIC (hash_lock);
-
-static int kqueue_descriptor = -1;
-static int kqueue_socket_pair[] = {-1, -1};
-static pthread_t kqueue_thread;
-
-
-void _kh_file_appeared_cb (kqueue_sub *sub);
-
-/**
- * accessor function for kqueue_descriptor
- **/
-int
-get_kqueue_descriptor()
-{
- return kqueue_descriptor;
-}
-
-/**
- * convert_kqueue_events_to_gio:
- * @flags: a set of kqueue filter flags
- * @done: a pointer to #gboolean indicating that the
- * conversion has been done (out)
- *
- * Translates kqueue filter flags into GIO event flags.
- *
- * Returns: a #GFileMonitorEvent
- **/
-static GFileMonitorEvent
-convert_kqueue_events_to_gio (uint32_t flags, gboolean *done)
-{
- g_assert (done != NULL);
- *done = FALSE;
-
- /* TODO: The following notifications should be emulated, if possible:
- * - G_FILE_MONITOR_EVENT_PRE_UNMOUNT
- */
- if (flags & NOTE_DELETE)
- {
- *done = TRUE;
- return G_FILE_MONITOR_EVENT_DELETED;
- }
- if (flags & NOTE_ATTRIB)
- {
- *done = TRUE;
- return G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED;
- }
- if (flags & (NOTE_WRITE | NOTE_EXTEND))
- {
- *done = TRUE;
- return G_FILE_MONITOR_EVENT_CHANGED;
- }
- if (flags & NOTE_RENAME)
- {
- /* Since there’s apparently no way to get the new name of the file out of
- * kqueue(), all we can do is say that this one has been deleted. */
- *done = TRUE;
- return G_FILE_MONITOR_EVENT_DELETED;
- }
- if (flags & NOTE_REVOKE)
- {
- *done = TRUE;
- return G_FILE_MONITOR_EVENT_UNMOUNTED;
- }
-
- /* done is FALSE */
- return 0;
-}
typedef struct {
kqueue_sub *sub;
@@ -238,318 +161,21 @@ static const traverse_cbs cbs = {
void
-_kh_dir_diff (kqueue_sub *sub, GFileMonitorSource *source)
+_kh_dir_diff (kqueue_sub *sub)
{
dep_list *was;
handle_ctx ctx;
- g_assert (sub != NULL);
- g_assert (source != NULL);
-
memset (&ctx, 0, sizeof (handle_ctx));
ctx.sub = sub;
- ctx.source = source;
+ ctx.source = sub->source;
was = sub->deps;
sub->deps = dl_listing (sub->filename);
-
+
dl_calculate (was, sub->deps, &cbs, &ctx);
dl_free (was);
}
-/**
- * process_kqueue_notifications:
- * @gioc: unused.
- * @cond: unused.
- * @data: unused.
- *
- * Processes notifications, coming from the kqueue thread.
- *
- * Reads notifications from the command file descriptor, emits the
- * "changed" event on the appropriate monitor.
- *
- * A typical GIO Channel callback function.
- *
- * Returns: %TRUE
- **/
-static gboolean
-process_kqueue_notifications (GIOChannel *gioc,
- GIOCondition cond,
- gpointer data)
-{
- struct kqueue_notification n;
- kqueue_sub *sub = NULL;
- GFileMonitorSource *source = NULL;
- GFileMonitorEvent mask = 0;
-
- g_assert (kqueue_socket_pair[0] != -1);
- if (!_ku_read (kqueue_socket_pair[0], &n, sizeof (struct kqueue_notification)))
- {
- KH_W ("Failed to read a kqueue notification, error %d", errno);
- return TRUE;
- }
-
- G_LOCK (hash_lock);
- sub = (kqueue_sub *) g_hash_table_lookup (subs_hash_table, GINT_TO_POINTER (n.fd));
- G_UNLOCK (hash_lock);
-
- if (sub == NULL)
- {
- KH_W ("Got a notification for a deleted or non-existing subscription %d",
- n.fd);
- return TRUE;
- }
-
- source = sub->user_data;
- g_assert (source != NULL);
-
- if (n.flags & (NOTE_DELETE | NOTE_REVOKE))
- {
- if (sub->deps)
- {
- dl_free (sub->deps);
- sub->deps = NULL;
- }
- _km_add_missing (sub);
-
- if (!(n.flags & NOTE_REVOKE))
- {
- /* Note that NOTE_REVOKE is issued by the kqueue thread
- * on EV_ERROR kevent. In this case, a file descriptor is
- * already closed from the kqueue thread, no need to close
- * it manually */
- _kh_cancel_sub (sub);
- }
- }
-
- if (sub->is_dir && n.flags & (NOTE_WRITE | NOTE_EXTEND))
- {
- _kh_dir_diff (sub, source);
- n.flags &= ~(NOTE_WRITE | NOTE_EXTEND);
- }
-
- if (n.flags)
- {
- gboolean done = FALSE;
- mask = convert_kqueue_events_to_gio (n.flags, &done);
- if (done == TRUE)
- g_file_monitor_source_handle_event (source, mask, NULL, NULL, NULL, g_get_monotonic_time ());
- }
-
- return TRUE;
-}
-
-
-/*
- * _kh_startup_impl:
- * @unused: unused
- *
- * Kqueue backend startup code. Should be called only once.
- *
- * Returns: %TRUE on success, %FALSE otherwise.
- **/
-static gpointer
-_kh_startup_impl (gpointer unused)
-{
- GIOChannel *channel = NULL;
- gboolean result = FALSE;
-
- kqueue_descriptor = kqueue ();
- result = (kqueue_descriptor != -1);
- if (!result)
- {
- KH_W ("Failed to initialize kqueue\n!");
- return GINT_TO_POINTER (FALSE);
- }
-
- result = socketpair (AF_UNIX, SOCK_STREAM, 0, kqueue_socket_pair);
- if (result != 0)
- {
- KH_W ("Failed to create socket pair\n!");
- return GINT_TO_POINTER (FALSE) ;
- }
-
- result = pthread_create (&kqueue_thread,
- NULL,
- _kqueue_thread_func,
- &kqueue_socket_pair[1]);
- if (result != 0)
- {
- KH_W ("Failed to run kqueue thread\n!");
- return GINT_TO_POINTER (FALSE);
- }
-
- _km_init (_kh_file_appeared_cb);
-
- channel = g_io_channel_unix_new (kqueue_socket_pair[0]);
- g_io_add_watch (channel, G_IO_IN, process_kqueue_notifications, NULL);
-
- subs_hash_table = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- KH_W ("started gio kqueue backend\n");
- return GINT_TO_POINTER (TRUE);
-}
-
-
-/*
- * _kh_startup:
- * Kqueue backend initialization.
- *
- * Returns: %TRUE on success, %FALSE otherwise.
- **/
-gboolean
-_kh_startup (void)
-{
- static GOnce init_once = G_ONCE_INIT;
- g_once (&init_once, _kh_startup_impl, NULL);
- return GPOINTER_TO_INT (init_once.retval);
-}
-
-
-/**
- * _kh_start_watching:
- * @sub: a #kqueue_sub
- *
- * Starts watching on a subscription.
- *
- * Returns: %TRUE on success, %FALSE otherwise.
- **/
-gboolean
-_kh_start_watching (kqueue_sub *sub)
-{
- g_assert (kqueue_socket_pair[0] != -1);
- g_assert (sub != NULL);
- g_assert (sub->filename != NULL);
-
- /* kqueue requires a file descriptor to monitor. Sad but true */
-#if defined (O_EVTONLY)
- sub->fd = open (sub->filename, O_EVTONLY);
-#else
- sub->fd = open (sub->filename, O_RDONLY);
-#endif
-
- if (sub->fd == -1)
- {
- KH_W ("failed to open file %s (error %d)", sub->filename, errno);
- return FALSE;
- }
-
- _ku_file_information (sub->fd, &sub->is_dir, NULL);
- if (sub->is_dir)
- {
- /* I know, it is very bad to make such decisions in this way and here.
- * We already do have an user_data at the #kqueue_sub, and it may point to
- * GKqueueFileMonitor or GKqueueDirectoryMonitor. For a directory case,
- * we need to scan in contents for the further diffs. Ideally this process
- * should be delegated to the GKqueueDirectoryMonitor, but for now I will
- * do it in a dirty way right here. */
- if (sub->deps)
- dl_free (sub->deps);
-
- sub->deps = dl_listing (sub->filename);
- }
-
- G_LOCK (hash_lock);
- g_hash_table_insert (subs_hash_table, GINT_TO_POINTER (sub->fd), sub);
- G_UNLOCK (hash_lock);
-
- _kqueue_thread_push_fd (sub->fd);
-
- /* Bump the kqueue thread. It will pick up a new sub entry to monitor */
- if (!_ku_write (kqueue_socket_pair[0], "A", 1))
- KH_W ("Failed to bump the kqueue thread (add fd, error %d)", errno);
- return TRUE;
-}
-
-
-/**
- * _kh_add_sub:
- * @sub: a #kqueue_sub
- *
- * Adds a subscription for monitoring.
- *
- * This funciton tries to start watching a subscription with
- * _kh_start_watching(). On failure, i.e. when a file does not exist yet,
- * the subscription will be added to a list of missing files to continue
- * watching when the file will appear.
- *
- * Returns: %TRUE
- **/
-gboolean
-_kh_add_sub (kqueue_sub *sub)
-{
- g_assert (sub != NULL);
-
- if (!_kh_start_watching (sub))
- _km_add_missing (sub);
-
- return TRUE;
-}
-
-
-/**
- * _kh_cancel_sub:
- * @sub a #kqueue_sub
- *
- * Stops monitoring on a subscription.
- *
- * Returns: %TRUE
- **/
-gboolean
-_kh_cancel_sub (kqueue_sub *sub)
-{
- gboolean removed = FALSE;
- g_assert (kqueue_socket_pair[0] != -1);
- g_assert (sub != NULL);
-
- _km_remove (sub);
-
- G_LOCK (hash_lock);
- removed = g_hash_table_remove (subs_hash_table, GINT_TO_POINTER (sub->fd));
- G_UNLOCK (hash_lock);
-
- if (removed)
- {
- /* fd will be closed in the kqueue thread */
- _kqueue_thread_remove_fd (sub->fd);
-
- /* Bump the kqueue thread. It will pick up a new sub entry to remove*/
- if (!_ku_write (kqueue_socket_pair[0], "R", 1))
- KH_W ("Failed to bump the kqueue thread (remove fd, error %d)", errno);
- }
-
- return TRUE;
-}
-
-
-/**
- * _kh_file_appeared_cb:
- * @sub: a #kqueue_sub
- *
- * A callback function for kqueue-missing subsystem.
- *
- * Signals that a missing file has finally appeared in the filesystem.
- * Emits %G_FILE_MONITOR_EVENT_CREATED.
- **/
-void
-_kh_file_appeared_cb (kqueue_sub *sub)
-{
- GFile* child;
-
- g_assert (sub != NULL);
- g_assert (sub->filename);
-
- if (!g_file_test (sub->filename, G_FILE_TEST_EXISTS))
- return;
-
- child = g_file_new_for_path (sub->filename);
-
- g_file_monitor_emit_event (G_FILE_MONITOR (sub->user_data),
- child,
- NULL,
- G_FILE_MONITOR_EVENT_CREATED);
-
- g_object_unref (child);
-}
diff --git a/gio/kqueue/kqueue-helper.h b/gio/kqueue/kqueue-helper.h
index b12a28fae..38a32a2f9 100644
--- a/gio/kqueue/kqueue-helper.h
+++ b/gio/kqueue/kqueue-helper.h
@@ -23,16 +23,31 @@
#ifndef __KQUEUE_HELPER_H
#define __KQUEUE_HELPER_H
-#include "kqueue-sub.h"
#include <gio/glocalfilemonitor.h>
#include <gio/gfilemonitor.h>
-gboolean _kh_startup (void);
-gboolean _kh_add_sub (kqueue_sub *sub);
-gboolean _kh_cancel_sub (kqueue_sub *sub);
-
-gboolean _kh_start_watching (kqueue_sub *sub);
-
-void _kh_dir_diff (kqueue_sub *sub, GFileMonitorSource *source);
+#include "dep-list.h"
+
+/**
+ * kqueue_sub:
+ * @filename: a name of the file to monitor
+ * @fd: the associated file descriptor (used by kqueue)
+ *
+ * Represents a subscription on a file or directory.
+ */
+typedef struct
+{
+ GLocalFileMonitor *mon;
+ GFileMonitorSource *source;
+ gchar* filename;
+ int fd;
+ dep_list* deps;
+ int is_dir;
+} kqueue_sub;
+
+gboolean _kqsub_start_watching (kqueue_sub *sub);
+void _kh_dir_diff (kqueue_sub *sub);
+void _km_add_missing (kqueue_sub *sub);
+void _km_remove (kqueue_sub *sub);
#endif /* __KQUEUE_HELPER_H */
diff --git a/gio/kqueue/kqueue-missing.c b/gio/kqueue/kqueue-missing.c
index 9decdc937..93135b962 100644
--- a/gio/kqueue/kqueue-missing.c
+++ b/gio/kqueue/kqueue-missing.c
@@ -23,12 +23,12 @@
#include <glib.h>
#include "kqueue-helper.h"
-#include "kqueue-sub.h"
-#include "kqueue-missing.h"
#define SCAN_MISSING_TIME 4 /* 1/4 Hz */
+void _kh_file_appeared_cb (kqueue_sub *sub);
+
static gboolean km_scan_missing (gpointer user_data);
static gboolean km_debug_enabled = FALSE;
@@ -38,21 +38,6 @@ static GSList *missing_subs_list = NULL;
G_LOCK_DEFINE_STATIC (missing_lock);
static volatile gboolean scan_missing_running = FALSE;
-static on_create_cb file_appeared_callback;
-
-
-/**
- * _km_init:
- * @cb: a callback function. It will be called when a watched file
- * will appear.
- *
- * Initialize the kqueue-missing module (optional).
- **/
-void
-_km_init (on_create_cb cb)
-{
- file_appeared_callback = cb;
-}
/**
@@ -83,6 +68,35 @@ _km_add_missing (kqueue_sub *sub)
}
}
+/**
+ * _kh_file_appeared_cb:
+ * @sub: a #kqueue_sub
+ *
+ * A callback function for kqueue-missing subsystem.
+ *
+ * Signals that a missing file has finally appeared in the filesystem.
+ * Emits %G_FILE_MONITOR_EVENT_CREATED.
+ **/
+void
+_kh_file_appeared_cb (kqueue_sub *sub)
+{
+ GFile *child;
+
+ g_assert (sub != NULL);
+ g_assert (sub->filename);
+
+ if (!g_file_test (sub->filename, G_FILE_TEST_EXISTS))
+ return;
+
+ child = g_file_new_for_path (sub->filename);
+
+ g_file_monitor_emit_event (G_FILE_MONITOR (sub->mon),
+ child,
+ NULL,
+ G_FILE_MONITOR_EVENT_CREATED);
+
+ g_object_unref (child);
+}
/**
* km_scan_missing:
@@ -114,11 +128,10 @@ km_scan_missing (gpointer user_data)
g_assert (sub != NULL);
g_assert (sub->filename != NULL);
- if (_kh_start_watching (sub))
+ if (_kqsub_start_watching (sub))
{
KM_W ("file %s now exists, starting watching", sub->filename);
- if (file_appeared_callback)
- file_appeared_callback (sub);
+ _kh_file_appeared_cb (sub);
not_missing = g_slist_prepend (not_missing, head);
}
}
diff --git a/gio/kqueue/kqueue-missing.h b/gio/kqueue/kqueue-missing.h
deleted file mode 100644
index 704a6f300..000000000
--- a/gio/kqueue/kqueue-missing.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2011, 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#ifndef __G_KQUEUE_MISSING_H
-#define __G_KQUEUE_MISSING_H
-
-typedef void (*on_create_cb) (kqueue_sub *);
-
-void _km_init (on_create_cb cb);
-void _km_add_missing (kqueue_sub *sub);
-void _km_remove (kqueue_sub *sub);
-
-#endif /* __G_KQUEUE_MISSING_H */
diff --git a/gio/kqueue/kqueue-sub.c b/gio/kqueue/kqueue-sub.c
deleted file mode 100644
index 8b864ba90..000000000
--- a/gio/kqueue/kqueue-sub.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2011, 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#include <glib.h>
-
-#include "kqueue-sub.h"
-
-static gboolean ks_debug_enabled = FALSE;
-#define KS_W if (ks_debug_enabled) g_warning
-
-/**
- * _kh_sub_new:
- * @filename: a file path to monitor (will be copied)
- * @pair_moves: pair moves flag. Refer to #GFileMonitorFlags documentation.
- * @user_data: user-supplied poiner.
- *
- * Creates a new subscription object.
- *
- * Returns: a pointer to a created subscription object.
- **/
-kqueue_sub*
-_kh_sub_new (const gchar *filename,
- gboolean pair_moves,
- gpointer user_data)
-{
- kqueue_sub *sub = g_slice_new (kqueue_sub);
- g_assert (sub != NULL);
-
- sub->filename = g_strdup (filename);
- sub->pair_moves = pair_moves;
- sub->user_data = user_data;
- sub->fd = -1;
- sub->deps = NULL;
- /* I think that having such flag in the subscription is not good */
- sub->is_dir = 0;
-
- KS_W ("new subscription for %s being setup\n", sub->filename);
-
- return sub;
-}
-
-
-/**
- * _kh_sub_free:
- * @sub: a #kqueue_sub
- *
- * Frees a subscription object and all its associated memory.
- **/
-void
-_kh_sub_free (kqueue_sub *sub)
-{
- if (sub->deps)
- {
- dl_free (sub->deps);
- sub->deps = NULL;
- }
-
- g_free (sub->filename);
- g_slice_free (kqueue_sub, sub);
-}
diff --git a/gio/kqueue/kqueue-sub.h b/gio/kqueue/kqueue-sub.h
deleted file mode 100644
index 215c49142..000000000
--- a/gio/kqueue/kqueue-sub.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2011, 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#ifndef __KQUEUE_SUB_H
-#define __KQUEUE_SUB_H
-
-#include "dep-list.h"
-
-/**
- * kqueue_sub:
- * @filename: a name of the file to monitor
- * @user_data: the pointer to user data
- * @pair_moves: unused (currently not implemented)
- * @fd: the associated file descriptor (used by kqueue)
- *
- * Represents a subscription on a file or directory.
- */
-typedef struct
-{
- gchar* filename;
- gpointer user_data;
- gboolean pair_moves;
- int fd;
- dep_list* deps;
- int is_dir;
-} kqueue_sub;
-
-kqueue_sub* _kh_sub_new (const gchar* filename, gboolean pair_moves, gpointer user_data);
-void _kh_sub_free (kqueue_sub* sub);
-
-#endif /* __KQUEUE_SUB_H */
diff --git a/gio/kqueue/kqueue-thread.c b/gio/kqueue/kqueue-thread.c
deleted file mode 100644
index 642b997db..000000000
--- a/gio/kqueue/kqueue-thread.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2011, 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#include "config.h"
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <errno.h>
-#include <glib.h>
-
-#include "kqueue-thread.h"
-#include "kqueue-sub.h"
-#include "kqueue-utils.h"
-
-static gboolean kt_debug_enabled = FALSE;
-#define KT_W if (kt_debug_enabled) g_warning
-
-static GQueue pick_up_fds_queue = G_QUEUE_INIT;
-G_LOCK_DEFINE_STATIC (pick_up_lock);
-
-static GSList *remove_fds_list = NULL;
-G_LOCK_DEFINE_STATIC (remove_lock);
-
-/* GIO does not have analogues for NOTE_LINK and(?) NOTE_REVOKE, so
- * we do not ask kqueue() to watch for these events for now. */
-const uint32_t KQUEUE_VNODE_FLAGS =
- NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME;
-
-extern int get_kqueue_descriptor(void);
-
-/**
- * _kqueue_thread_collect_fds:
- * @events: a #kevents - the list of events to monitor. Will be extended
- * with new items.
- *
- * Picks up new file descriptors for monitoring from a global queue.
- *
- * To add new items to the list, use _kqueue_thread_push_fd().
- */
-static void
-_kqueue_thread_collect_fds (kevents *events)
-{
- g_assert (events != NULL);
- gint length = 0;
-
- G_LOCK (pick_up_lock);
- if ((length = g_queue_get_length (&pick_up_fds_queue)) != 0)
- {
- gpointer fdp = NULL;
- kevents_extend_sz (events, length);
-
- while ((fdp = g_queue_pop_head (&pick_up_fds_queue)) != NULL)
- {
- struct kevent *pevent = &events->memory[events->kq_size++];
- EV_SET (pevent,
- GPOINTER_TO_INT (fdp),
- EVFILT_VNODE,
- EV_ADD | EV_ENABLE | EV_ONESHOT,
- KQUEUE_VNODE_FLAGS,
- 0,
- 0);
- }
- }
- G_UNLOCK (pick_up_lock);
-}
-
-
-/**
- * _kqueue_thread_cleanup_fds:
- * @events: a #kevents -- list of events to monitor. Cancelled
- * subscriptions will be removed from it, and its size
- * probably will be reduced.
- *
- * Removes file descriptors from monitoring.
- *
- * This function will pick up file descriptors from a global list
- * to cancel monitoring on them. The list will be freed then.
- *
- * To add new items to the list, use _kqueue_thread_remove_fd().
- */
-static void
-_kqueue_thread_cleanup_fds (kevents *events)
-{
- g_assert (events != NULL);
-
- G_LOCK (remove_lock);
- if (remove_fds_list)
- {
- size_t oldsize = events->kq_size;
- int i, j;
-
- for (i = 1, j = 1; i < oldsize; i++)
- {
- int fd = events->memory[i].ident;
- GSList *elem = g_slist_find (remove_fds_list, GINT_TO_POINTER (fd));
- if (elem == NULL)
- {
- if (i != j)
- events->memory[j] = events->memory[i];
- ++j;
- }
- else if (close (fd) == -1)
- KT_W ("Failed to close fd %d, error %d", fd, errno);
- }
-
- KT_W ("FD Clean up complete, kq_size now %d\n", j);
- events->kq_size = j;
- kevents_reduce (events);
- g_slist_free (remove_fds_list);
- remove_fds_list = NULL;
- }
- G_UNLOCK (remove_lock);
-}
-
-
-/**
- * _kqueue_thread_drop_fd:
- * @events: a #kevents -- list of events to monitor. Cancelled
- * subscriptions will be removed from it, and its size
- * probably will be reduced.
- *
- * Removes a concrete file descriptor from monitoring.
- */
-static void
-_kqueue_thread_drop_fd (kevents *events, int fd)
-{
- g_assert (events != NULL);
-
- int i;
- for (i = 1; i < events->kq_size; i++)
- {
- if (events->memory[i].ident == fd)
- {
- if (close (fd) == -1)
- KT_W ("Failed to close fd %d, error %d", fd, errno);
-
- events->memory[i] = events->memory[--events->kq_size];
- return;
- }
- }
-}
-
-/**
- * _kqueue_thread_func:
- * @arg: a pointer to int -- control file descriptor.
- *
- * The thread communicates with the outside world through a so-called
- * command file descriptor. The thread reads control commands from it
- * and writes the notifications into it.
- *
- * Control commands are single-byte characters:
- * - 'A' - pick up new file descriptors to monitor
- * - 'R' - remove some descriptors from monitoring.
- *
- * For details, see _kqueue_thread_collect_fds() and
- * _kqueue_thread_cleanup_fds().
- *
- * Notifications, that thread writes into the command file descriptor,
- * are represented with #kqueue_notification objects.
- *
- * Returns: %NULL
- */
-void*
-_kqueue_thread_func (void *arg)
-{
- int fd, kqueue_descriptor;
- kevents waiting;
-
- g_assert (arg != NULL);
- kevents_init_sz (&waiting, 1);
-
- fd = *(int *) arg;
-
- kqueue_descriptor = get_kqueue_descriptor();
- if (kqueue_descriptor == -1)
- {
- KT_W ("fatal: kqueue is not initialized!\n");
- return NULL;
- }
-
- EV_SET (&waiting.memory[0],
- fd,
- EVFILT_READ,
- EV_ADD | EV_ENABLE | EV_ONESHOT,
- NOTE_LOWAT,
- 1,
- 0);
- waiting.kq_size = 1;
-
- for (;;)
- {
- /* TODO: Provide more items in the 'eventlist' to kqueue(2).
- * Currently the backend takes notifications from the kernel one
- * by one, i.e. there will be a lot of system calls and context
- * switches when the application will monitor a lot of files with
- * high filesystem activity on each. */
-
- struct kevent received;
- KT_W ("Watching for %zi items", waiting.kq_size);
- int ret = kevent (kqueue_descriptor, waiting.memory, waiting.kq_size, &received, 1, NULL);
- int kevent_errno = errno;
- KT_W ("Awoken.");
-
- if (ret == -1)
- {
- KT_W ("kevent failed: %d", kevent_errno);
- if (kevent_errno == EINTR)
- continue;
- else
- return NULL;
- }
-
- if (received.ident == fd)
- {
- char c;
- if (!_ku_read (fd, &c, 1))
- {
- KT_W ("Failed to read command, error %d", errno);
- continue;
- }
- if (c == 'A')
- _kqueue_thread_collect_fds (&waiting);
- else if (c == 'R')
- _kqueue_thread_cleanup_fds (&waiting);
- }
- else
- {
- struct kqueue_notification kn;
- kn.fd = received.ident;
-
- if (received.flags & EV_ERROR)
- {
- kn.flags = NOTE_REVOKE;
- _kqueue_thread_drop_fd (&waiting, received.ident);
- }
- else
- kn.flags = (received.fflags & ~NOTE_REVOKE);
-
- if (!_ku_write (fd, &kn, sizeof (struct kqueue_notification)))
- KT_W ("Failed to write a kqueue notification, error %d", errno);
- }
- }
- kevents_free (&waiting);
- return NULL;
-}
-
-
-/**
- * _kqueue_thread_push_fd:
- * @fd: a file descriptor
- *
- * Puts a new file descriptor into the pick up list for monitroing.
- *
- * The kqueue thread will not start monitoring on it immediately, it
- * should be bumped via its command file descriptor manually.
- * See kqueue_thread() and _kqueue_thread_collect_fds() for details.
- */
-void
-_kqueue_thread_push_fd (int fd)
-{
- G_LOCK (pick_up_lock);
- g_queue_push_tail (&pick_up_fds_queue, GINT_TO_POINTER (fd));
- G_UNLOCK (pick_up_lock);
-}
-
-
-/**
- * _kqueue_thread_remove_fd:
- * @fd: a file descriptor
- *
- * Puts a new file descriptor into the remove list to cancel monitoring
- * on it.
- *
- * The kqueue thread will not stop monitoring on it immediately, it
- * should be bumped via its command file descriptor manually.
- * See kqueue_thread() and _kqueue_thread_collect_fds() for details.
- */
-void
-_kqueue_thread_remove_fd (int fd)
-{
- G_LOCK (remove_lock);
- remove_fds_list = g_slist_prepend (remove_fds_list, GINT_TO_POINTER (fd));
- G_UNLOCK (remove_lock);
-}
diff --git a/gio/kqueue/kqueue-thread.h b/gio/kqueue/kqueue-thread.h
deleted file mode 100644
index 0e46a0d69..000000000
--- a/gio/kqueue/kqueue-thread.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2011, 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#ifndef __KQUEUE_THREAD_H
-#define __KQUEUE_THREAD_H
-
-/**
- * kqueue_notification:
- * @fd: file descriptor, on which an activity has occured.
- * @flags: kqueue event flags, see man kevent(2).
- *
- * Represents an event occured on a file descriptor. Used for marshalling from
- * kqueue thread to its subscribers.
- */
-struct kqueue_notification {
- /*< public >*/
- int fd;
- uint32_t flags;
-};
-
-
-void* _kqueue_thread_func (void *arg);
-void _kqueue_thread_push_fd (int fd);
-void _kqueue_thread_remove_fd (int fd);
-
-#endif /* __KQUEUE_SUB_H */
diff --git a/gio/kqueue/kqueue-utils.c b/gio/kqueue/kqueue-utils.c
deleted file mode 100644
index bba652278..000000000
--- a/gio/kqueue/kqueue-utils.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2011, 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#include <sys/types.h>
-#include <sys/event.h>
-#include <string.h>
-#include <glib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include "kqueue-utils.h"
-
-static gboolean ku_debug_enabled = FALSE;
-#define KU_W if (ku_debug_enabled) g_warning
-
-
-
-#define KEVENTS_EXTEND_COUNT 10
-
-
-/**
- * kevents_init_sz:
- * @kv: a #kevents
- * @n_initial: the initial preallocated memory size. If it is less than
- * %KEVENTS_EXTEND_COUNT, this value will be used instead.
- *
- * Initializes a #kevents object.
- **/
-void
-kevents_init_sz (kevents *kv, gsize n_initial)
-{
- g_assert (kv != NULL);
-
- memset (kv, 0, sizeof (kevents));
-
- if (n_initial < KEVENTS_EXTEND_COUNT)
- n_initial = KEVENTS_EXTEND_COUNT;
-
- kv->memory = g_new0 (struct kevent, n_initial);
- kv->kq_allocated = n_initial;
-}
-
-
-/**
- * kevents_extend_sz:
- * @kv: a #kevents
- * @n_new: the number of new objects to be added
- *
- * Extends the allocated memory, if needed.
- **/
-void
-kevents_extend_sz (kevents *kv, gsize n_new)
-{
- g_assert (kv != NULL);
-
- if (kv->kq_size + n_new <= kv->kq_allocated)
- return;
-
- kv->kq_allocated += (n_new + KEVENTS_EXTEND_COUNT);
- kv->memory = g_renew (struct kevent, kv->memory, kv->kq_allocated);
-}
-
-
-/**
- * kevents_reduce:
- * @kv: a #kevents
- *
- * Reduces the allocated heap size, if needed.
- *
- * If the allocated heap size is >= 3*used
- * and 2*used >= %KEVENTS_EXTEND_COUNT, reduce it to 2*used.
- **/
-void
-kevents_reduce (kevents *kv)
-{
- g_assert (kv != NULL);
- gsize candidate_sz;
-
- if (kv->kq_size == 0 || kv->kq_allocated == 0 || kv->memory == NULL)
- return;
-
- candidate_sz = 2 * kv->kq_size;
-
- if (((double) kv->kq_allocated / kv->kq_size) >= 3 &&
- candidate_sz >= KEVENTS_EXTEND_COUNT)
- {
- kv->kq_allocated = candidate_sz;
- kv->memory = g_renew (struct kevent, kv->memory, kv->kq_allocated);
- }
-}
-
-
-/**
- * kevents_free:
- * @kv: a #kevents
- *
- * Resets the kevents object and frees all the associated memory.
- **/
-void
-kevents_free (kevents *kv)
-{
- g_assert (kv != NULL);
-
- g_free (kv->memory);
- memset (kv, 0, sizeof (kevents));
-}
-
-
-#define SAFE_GENERIC_OP(fcn, fd, data, size) \
- while (size > 0) \
- { \
- gsize retval = fcn (fd, data, size); \
- if (retval == -1) \
- { \
- if (errno == EINTR) \
- continue; \
- else \
- return FALSE; \
- } \
- size -= retval; \
- data += retval; \
- } \
- return TRUE;
-
-
-/**
- * _ku_read:
- * @fd: a file descriptor
- * @data: the destination buffer
- * @size: how many bytes to read
- *
- * A ready-to-EINTR version of read().
- *
- * This function expects to work with a blocking socket.
- *
- * Returns: %TRUE on success, %FALSE otherwise
- **/
-gboolean
-_ku_read (int fd, gpointer data, gsize size)
-{
- SAFE_GENERIC_OP (read, fd, data, size);
-}
-
-
-/**
- * _ku_write:
- * @fd: a file descriptor
- * @data: the buffer to write
- * @size: how many bytes to write
- *
- * A ready-to-EINTR version of write().
- *
- * This function expects to work with a blocking socket.
- *
- * Returns: %TRUE on success, %FALSE otherwise
- **/
-gboolean
-_ku_write (int fd, gconstpointer data, gsize size)
-{
- SAFE_GENERIC_OP (write, fd, data, size);
-}
-
-
-/**
- * Get some file information by its file descriptor.
- *
- * @param[in] fd A file descriptor.
- * @param[out] is_dir A flag indicating directory.
- * @param[out] inode A file's inode number.
- **/
-void
-_ku_file_information (int fd, int *is_dir, ino_t *inode)
-{
- g_assert (fd != -1);
-
- struct stat st;
- memset (&st, 0, sizeof (struct stat));
-
- if (fstat (fd, &st) == -1)
- {
- KU_W ("fstat failed, assuming it is just a file");
- is_dir = NULL;
- return;
- }
-
- if (is_dir != NULL)
- *is_dir = ((st.st_mode & S_IFDIR) == S_IFDIR) ? 1 : 0;
-
- if (inode != NULL)
- *inode = st.st_ino;
-}
diff --git a/gio/kqueue/kqueue-utils.h b/gio/kqueue/kqueue-utils.h
deleted file mode 100644
index 4e37f4a99..000000000
--- a/gio/kqueue/kqueue-utils.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- Copyright (c) 2011, 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*******************************************************************************/
-
-#ifndef __KQUEUE_UTILS_H
-#define __KQUEUE_UTILS_H
-
-#include <sys/types.h> /* ino_t */
-
-/**
- * kqueue_notification:
- * @memory: a pointer to the allocated memory
- * @kq_size: the number of used items
- * @kq_allocated: the number of allocated items
- *
- * Represents a pool of (struct kevent) objects.
- */
-typedef struct {
- struct kevent *memory;
- gsize kq_size;
- gsize kq_allocated;
-} kevents;
-
-void kevents_init_sz (kevents *kv, gsize n_initial);
-void kevents_extend_sz (kevents *kv, gsize n_new);
-void kevents_reduce (kevents *kv);
-void kevents_free (kevents *kv);
-
-
-gboolean _ku_read (int fd, gpointer data, gsize size);
-gboolean _ku_write (int fd, gconstpointer data, gsize size);
-
-void _ku_file_information (int fd, int *is_dir, ino_t *inode);
-
-#endif /* __KQUEUE_UTILS_H */
diff --git a/gio/kqueue/meson.build b/gio/kqueue/meson.build
index 51c5e788f..e5057c83d 100644
--- a/gio/kqueue/meson.build
+++ b/gio/kqueue/meson.build
@@ -1,18 +1,13 @@
kqueue_sources = [
'gkqueuefilemonitor.c',
'kqueue-helper.c',
- 'kqueue-thread.c',
- 'kqueue-sub.c',
'kqueue-missing.c',
- 'kqueue-utils.c',
- 'kqueue-exclusions.c',
'dep-list.c',
- # gkqueuefilemonitor.h includes gio.h which includes this
- gioenumtypes_h,
]
kqueue_lib = static_library('kqueue',
sources : kqueue_sources,
include_directories : [configinc, glibinc, gmoduleinc],
+ dependencies : [gioenumtypes_dep],
pic : true,
c_args : [ '-DG_DISABLE_DEPRECATED' ] + gio_c_args)
diff --git a/gio/meson.build b/gio/meson.build
index 7393f374d..42f67715d 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -137,10 +137,8 @@ if host_system != 'windows'
glib_conf.set('HAVE_RES_NQUERY', 1)
endif
- if cc.compiles('''#include <netinet/in.h>
- struct ip_mreqn foo;''',
- name : 'struct ip_mreqn')
- glib_conf.set('HAVE_IP_MREQN', '/**/')
+ if cc.has_type('struct ip_mreqn', prefix : '#include <netinet/in.h>')
+ glib_conf.set('HAVE_IP_MREQN', 1)
endif
if cc.compiles('''#include <sys/ioctl.h>
@@ -154,11 +152,6 @@ if host_system != 'windows'
glib_conf.set('HAVE_SIOCGIFADDR', '/**/')
endif
-endif
-
-if host_system.contains('android')
- # struct ip_mreq_source definition is broken on Android NDK <= r16
- # See https://bugzilla.gnome.org/show_bug.cgi?id=740791
if not cc.compiles('''#include <netinet/in.h>
int main(int argc, char ** argv) {
struct ip_mreq_source mc_req_src;
@@ -168,6 +161,7 @@ if host_system.contains('android')
name : 'ip_mreq_source.imr_interface has s_addr member')
glib_conf.set('BROKEN_IP_MREQ_SOURCE_STRUCT', 1)
endif
+
endif
network_args_string = ''
@@ -454,6 +448,7 @@ else
'gwin32outputstream.c',
'gwin32networkmonitor.c',
'gwin32networkmonitor.h',
+ 'gwin32notificationbackend.c',
)
gio_win_rc = configure_file(
@@ -798,16 +793,55 @@ libgio = library('gio-2.0',
install : true,
include_directories : [configinc, gioinc],
link_with : internal_deps,
- #libgio_2_0_la_LDFLAGS = $(GLIB_LINK_FLAGS)',
# '$(gio_win32_res_ldflag)',
- dependencies : [libintl, libz_dep, libdl_dep, libmount_dep, libglib_dep,
+ dependencies : [libz_dep, libdl_dep, libmount_dep, libglib_dep,
libgobject_dep, libgmodule_dep, selinux_dep, xattr_dep,
platform_deps, network_libs],
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
- link_args : noseh_link_args,
+ link_args : [noseh_link_args, glib_link_flags],
+)
+
+giomodulesdir = get_option('gio_module_dir')
+if giomodulesdir == ''
+ giomodulesdir = join_paths('${libdir}', 'gio', 'modules')
+endif
+
+pkg.generate(libraries : libgio,
+ libraries_private : [osx_ldflags],
+ requires : ['glib-2.0', 'gobject-2.0'],
+ variables : ['bindir=' + join_paths('${prefix}', get_option('bindir')),
+ 'giomoduledir=' + giomodulesdir,
+ 'glib_compile_schemas=' + join_paths('${bindir}', 'glib-compile-schemas'),
+ 'glib_compile_resources=' + join_paths('${bindir}', 'glib-compile-resources'),
+ 'gdbus_codegen=' + join_paths('${bindir}', 'gdbus-codegen')],
+ version : glib_version,
+ install_dir : glib_pkgconfigreldir,
+ filebase : 'gio-2.0',
+ name : 'GIO',
+ description : 'glib I/O library',
)
+if host_system == 'windows'
+ pkg.generate(requires : ['gobject-2.0', 'gmodule-no-export-2.0', 'gio-2.0'],
+ subdirs : ['gio-win32-2.0'],
+ version : glib_version,
+ install_dir : glib_pkgconfigreldir,
+ filebase : 'gio-windows-2.0',
+ name : 'GIO Windows specific APIs',
+ description : 'Windows specific headers for glib I/O library',
+ )
+else
+ pkg.generate(requires : ['gobject-2.0', 'gio-2.0'],
+ subdirs : ['gio-unix-2.0'],
+ version : glib_version,
+ install_dir : glib_pkgconfigreldir,
+ filebase : 'gio-unix-2.0',
+ name : 'GIO unix specific APIs',
+ description : 'unix specific headers for glib I/O library',
+ )
+endif
+
libgio_dep = declare_dependency(link_with : libgio,
dependencies : [gioenumtypes_dep],
# We sadly need to export configinc here because everyone includes <gio/*.h>
@@ -860,13 +894,13 @@ executable('gio', gio_tool_sources,
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
executable('gresource', 'gresource-tool.c',
install : true,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libelf, libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libelf, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
executable('gio-querymodules', 'gio-querymodules.c', 'giomodule-priv.c',
install : true,
@@ -880,7 +914,7 @@ glib_compile_schemas = executable('glib-compile-schemas',
install : true,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
glib_compile_resources = executable('glib-compile-resources',
[gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-resources.c'],
@@ -888,14 +922,14 @@ glib_compile_resources = executable('glib-compile-resources',
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
executable('gsettings', 'gsettings-tool.c',
install : true,
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
install_data('gschema.dtd',
install_dir : join_paths(get_option('datadir'), 'glib-2.0/schemas'))
@@ -907,7 +941,7 @@ executable('gdbus', 'gdbus-tool.c',
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
if host_system != 'windows'
executable('gapplication', 'gapplication-tool.c',
@@ -915,7 +949,7 @@ if host_system != 'windows'
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
endif
if enable_systemtap
diff --git a/gio/org.freedesktop.portal.NetworkMonitor.xml b/gio/org.freedesktop.portal.NetworkMonitor.xml
index fb551d6ed..8d3a471d5 100644
--- a/gio/org.freedesktop.portal.NetworkMonitor.xml
+++ b/gio/org.freedesktop.portal.NetworkMonitor.xml
@@ -5,86 +5,25 @@
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 of the License, or (at your option) any later version.
+ 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/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, see <http://www.gnu.org/licenses/>.
Author: Matthias Clasen <mclasen@redhat.com>
-->
-<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
- <!--
- org.freedesktop.portal.NetworkMonitor:
- @short_description: Network monitoring portal
-
- The NetworkMonitor interface provides network status information
- to sandboxed applications. It is not a portal in the strict sense,
- since it does not involve user interaction. Applications are
- expected to use this interface indirectly, via a library API
- such as the GLib GNetworkMonitor interface.
-
- This documentation describes version 2 of this interface.
- -->
+<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd" name="/">
<interface name="org.freedesktop.portal.NetworkMonitor">
- <!--
- changed:
-
- Emitted when the network configuration changes.
- -->
- <signal name="changed"/>
- <!--
- GetAvailable:
- @available: whether the network is available
-
- Returns whether the network is considered available.
- That is, whether the system as a default route for
- at least one of IPv4 or IPv6.
-
- This method was added in version 2 to replace
- the available property.
- -->
- <method name="GetAvailable">
- <arg type='b' name='available' direction='out'/>
- </method>
- <!--
- GetMetered:
- @metered: whether the network is metered
-
- Returns whether the network is considered metered.
- That is, whether the system as traffic flowing through
- the default connection that is subject ot limitations
- by service providers.
-
- This method was added in version 2 to replace
- the metered property.
- -->
- <method name="GetMetered">
- <arg type='b' name='metered' direction='out'/>
- </method>
- <!--
- GetConnectivity:
- @connectivity: the level of connectivity
-
- Returs more detailed information about the host's network
- connectivity. The meaning of the value is:
- <simplelist>
- <member>1: Local only. The host is not configured with a route to the internet.</member>
- <member>2: Limited connectivity. The host is connected to a network, but can't reach the full internet.</member>
- <member>3: Captive portal. The host is behind a captive portal and cannot reach the full internet.</member>
- <member>4: Full network. The host connected to a network, and can reach the full internet.</member>
- </simplelist>
-
- This method was added in version 2 to replace
- the connectivity property.
- -->
- <method name="GetConnectivity">
- <arg type='u' name='connectivity' direction='out'/>
- </method>
- <property name="version" type="u" access="read"/>
+ <signal name="changed">
+ <arg type="b" name="available"/>
+ </signal>
+ <property name="available" type="b" access="read"/>
+ <property name="metered" type="b" access="read"/>
+ <property name="connectivity" type="u" access="read"/>
</interface>
</node>
diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am
index 49a19bf4a..410f11d95 100644
--- a/gio/tests/Makefile.am
+++ b/gio/tests/Makefile.am
@@ -300,11 +300,11 @@ usr_desktop_files = \
evince-previewer.desktop \
evince.desktop \
file-roller.desktop \
+ frobnicator.desktop \
gcr-prompter.desktop \
gcr-viewer.desktop \
gedit.desktop \
glade.desktop \
- gnome-clocks.desktop \
gnome-contacts.desktop \
gnome-font-viewer.desktop \
gnome-music.desktop \
@@ -319,6 +319,7 @@ usr_desktop_files = \
nautilus-classic.desktop \
nautilus-connect-server.desktop \
nautilus.desktop \
+ org.gnome.clocks.desktop \
totem.desktop \
yelp.desktop
diff --git a/gio/tests/desktop-app-info.c b/gio/tests/desktop-app-info.c
index d1b68c441..669db5769 100644
--- a/gio/tests/desktop-app-info.c
+++ b/gio/tests/desktop-app-info.c
@@ -626,7 +626,7 @@ assert_implementations (const gchar *interface,
}
#define ALL_USR_APPS "evince-previewer.desktop nautilus-classic.desktop gnome-font-viewer.desktop " \
- "baobab.desktop yelp.desktop eog.desktop cheese.desktop gnome-clocks.desktop " \
+ "baobab.desktop yelp.desktop eog.desktop cheese.desktop org.gnome.clocks.desktop " \
"gnome-contacts.desktop kde4-kate.desktop gcr-prompter.desktop totem.desktop " \
"gnome-terminal.desktop nautilus-autorun-software.desktop gcr-viewer.desktop " \
"nautilus-connect-server.desktop kde4-dolphin.desktop gnome-music.desktop " \
@@ -667,6 +667,17 @@ test_search (void)
assert_search ("image viewer", "", FALSE, TRUE, NULL, NULL);
assert_search ("image viewer", "", TRUE, TRUE, NULL, NULL);
+ /* There're "flatpak" apps (clocks) installed as well - they should *not*
+ * match the prefix command ("/bin/sh") in the Exec= line though.
+ */
+ assert_search ("sh", "gnome-terminal.desktop\n", TRUE, FALSE, NULL, NULL);
+
+ /* "frobnicator.desktop" is ignored by get_all() because the binary is
+ * missing, but search should still find it (to avoid either stale results
+ * from the cache or expensive stat() calls for each potential result)
+ */
+ assert_search ("frobni", "frobnicator.desktop\n", TRUE, FALSE, NULL, NULL);
+
/* Obvious multi-word search */
assert_search ("gno hel", "yelp.desktop\n", TRUE, TRUE, NULL, NULL);
@@ -685,7 +696,7 @@ test_search (void)
* yelp and gnome-contacts, though.
*/
assert_search ("gnome", "eog.desktop\n"
- "gnome-clocks.desktop\n"
+ "org.gnome.clocks.desktop\n"
"yelp.desktop gnome-contacts.desktop\n", TRUE, TRUE, NULL, NULL);
/* eog has exec name 'false' in usr only */
diff --git a/gio/tests/desktop-files/usr/applications/frobnicator.desktop b/gio/tests/desktop-files/usr/applications/frobnicator.desktop
new file mode 100644
index 000000000..0a8dbfa39
--- /dev/null
+++ b/gio/tests/desktop-files/usr/applications/frobnicator.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=Frobnicator
+Comment=Frobnicate your life!
+Exec=/does-not-exist
+Icon=frobnicator
+StartupNotify=true
+Terminal=false
+Type=Application
+Categories=GNOME;GTK;Utilities
diff --git a/gio/tests/desktop-files/usr/applications/gnome-clocks.desktop b/gio/tests/desktop-files/usr/applications/gnome-clocks.desktop
deleted file mode 100644
index 3f533e963..000000000
--- a/gio/tests/desktop-files/usr/applications/gnome-clocks.desktop
+++ /dev/null
@@ -1,41 +0,0 @@
-[Desktop Entry]
-Name=Clocks
-Name[ca]=Rellotges
-Name[ca@valencia]=Rellotges
-Name[en_GB]=Clocks
-Name[eo]=Horloĝoj
-Name[pt]=Relógios
-Name[pt_BR]=Relógios
-GenericName=Clocks
-GenericName[ca]=Rellotges
-GenericName[ca@valencia]=Rellotges
-GenericName[en_GB]=Clocks
-GenericName[eo]=Horloĝoj
-GenericName[pt]=Relógios
-GenericName[pt_BR]=Relógios
-X-GNOME-FullName=GNOME Clocks
-X-GNOME-FullName[ca]=Rellotges del GNOME
-X-GNOME-FullName[ca@valencia]=Rellotges del GNOME
-X-GNOME-FullName[en_GB]=GNOME Clocks
-X-GNOME-FullName[eo]=GNOME-horloĝoj
-X-GNOME-FullName[pt]=Relógios GNOME
-X-GNOME-FullName[pt_BR]=Relógios do GNOME
-Comment=Clocks for world times, plus alarms, stopwatch and a timer
-Comment[ca]=Rellotges de tot el món, a més d'alarmes, de cronòmetres i de temporitzadors
-Comment[ca@valencia]=Rellotges de tot el món, a més d'alarmes, de cronòmetres i de temporitzadors
-Comment[en_GB]=Clocks for world times, plus alarms, stopwatch and a timer
-Comment[pt]=Relógios com as horas do mundo, alarmes, cronómetros e um temporizador
-Comment[pt_BR]=Relógios para horários mundiais além de alarmes, cronômetro e um temporizador
-Keywords=time;timer;alarm;world clock;stopwatch;time zone;
-Keywords[ca]=temps;temporitzador;alarma;rellotge global;cronòmetre;zona horària;
-Keywords[ca@valencia]=temps;temporitzador;alarma;rellotge global;cronòmetre;zona horària;
-Keywords[en_GB]=time;timer;alarm;world clock;stopwatch;time zone;
-Keywords[pt]=horas;temporizador;alarme;relógio mundial;cronómetro;fuso horário;
-Keywords[pt_BR]=hora;temporizador;alarme;relógio mundial;cronômetro;fuso horário;
-Exec=true
-Icon=gnome-clocks
-Terminal=false
-Type=Application
-Categories=GNOME;GTK;Utility;Clock;
-StartupNotify=true
-X-GNOME-UsesNotifications=true
diff --git a/gio/tests/desktop-files/usr/applications/org.gnome.clocks.desktop b/gio/tests/desktop-files/usr/applications/org.gnome.clocks.desktop
new file mode 100755
index 000000000..92a6b35bc
--- /dev/null
+++ b/gio/tests/desktop-files/usr/applications/org.gnome.clocks.desktop
@@ -0,0 +1,404 @@
+[Desktop Entry]
+Name[af]=Horlosies
+Name[an]=Reloches
+Name[ar]=الساعات
+Name[as]=ঘড়ী
+Name[be]=Гадзіннікі
+Name[bg]=Часовници
+Name[bn_IN]=ঘড়ি
+Name[bs]=Satovi
+Name[ca]=Rellotges
+Name[ca@valencia]=Rellotges
+Name[cs]=Hodiny
+Name[da]=Ure
+Name[de]=Uhren
+Name[el]=Ρολόγια
+Name[en_GB]=Clocks
+Name[eo]=Horloĝoj
+Name[es]=Relojes
+Name[et]=Kell
+Name[eu]=Ordulariak
+Name[fa]=ساعت‌ها
+Name[fi]=Kellot
+Name[fr]=Horloges
+Name[fur]=Orlois
+Name[ga]=Cloig
+Name[gd]=Uaireadairean
+Name[gl]=Reloxos
+Name[gu]=ઘડિયાળ
+Name[he]=שעונים
+Name[hi]=घड़ी
+Name[hr]=Satovi
+Name[hu]=Órák
+Name[id]=Jam
+Name[is]=Klukkur
+Name[it]=Orologi
+Name[ja]=時計
+Name[kk]=Сағаттар
+Name[ko]=시계
+Name[kn]=ಗಡಿಯಾರಗಳು
+Name[lt]=Laikrodžiai
+Name[lv]=Pulksteņi
+Name[ml]=ക്ലോക്കുകൾ
+Name[mr]=घड्याळी
+Name[nb]=Klokker
+Name[ne]=घडिहरू
+Name[nl]=Klok
+Name[oc]=Relòtges
+Name[or]=ଘଣ୍ଟାଗୁଡ଼ିକ
+Name[pa]=ਘੜੀ
+Name[pl]=Zegar
+Name[pt]=Relógios
+Name[pt_BR]=Relógios
+Name[ro]=Ceasuri
+Name[ru]=Часы
+Name[sk]=Hodiny
+Name[sl]=Ure
+Name[sr]=Сатови
+Name[sr@latin]=Satovi
+Name[sv]=Klockor
+Name[ta]=கடிகாரங்கள்
+Name[te]=గడియారాలు
+Name[tg]=Соатҳо
+Name[th]=นาฬิกา
+Name[tr]=Saatler
+Name[uk]=Годинники
+Name[vi]=Đồng hồ
+Name[zh_CN]=时钟
+Name[zh_HK]=時鐘
+Name[zh_TW]=時鐘
+Name[ug]=سائەتلەر
+Name=Clocks
+GenericName[af]=Horlosies
+GenericName[an]=Reloches
+GenericName[ar]=الساعات
+GenericName[as]=ঘড়ী
+GenericName[be]=Гадзіннікі
+GenericName[bg]=Часовници
+GenericName[bn_IN]=ঘড়ি
+GenericName[bs]=Satovi
+GenericName[ca]=Rellotges
+GenericName[ca@valencia]=Rellotges
+GenericName[cs]=Hodiny
+GenericName[da]=Ure
+GenericName[de]=Uhren
+GenericName[el]=Ρολόγια
+GenericName[en_GB]=Clocks
+GenericName[eo]=Horloĝoj
+GenericName[es]=Relojes
+GenericName[et]=Kell
+GenericName[eu]=Ordulariak
+GenericName[fa]=ساعت‌ها
+GenericName[fi]=Kellot
+GenericName[fr]=Horloges
+GenericName[fur]=Orlois
+GenericName[ga]=Cloig
+GenericName[gd]=Uaireadairean
+GenericName[gl]=Reloxos
+GenericName[gu]=ઘડિયાળ
+GenericName[he]=שעונים
+GenericName[hi]=घड़ी
+GenericName[hr]=Satovi
+GenericName[hu]=Órák
+GenericName[id]=Jam
+GenericName[is]=Klukkur
+GenericName[it]=Orologi
+GenericName[ja]=時計
+GenericName[kk]=Сағаттар
+GenericName[ko]=시계
+GenericName[kn]=ಗಡಿಯಾರಗಳು
+GenericName[lt]=Laikrodžiai
+GenericName[lv]=Pulksteņi
+GenericName[ml]=ക്ലോക്കുകൾ
+GenericName[mr]=घड्याळी
+GenericName[nb]=Klokker
+GenericName[ne]=घडिहरू
+GenericName[nl]=Klok
+GenericName[oc]=Relòtges
+GenericName[or]=ଘଣ୍ଟାଗୁଡ଼ିକ
+GenericName[pa]=ਘੜੀ
+GenericName[pl]=Zegar
+GenericName[pt]=Relógios
+GenericName[pt_BR]=Relógios
+GenericName[ro]=Ceasuri
+GenericName[ru]=Часы
+GenericName[sk]=Hodiny
+GenericName[sl]=Ure
+GenericName[sr]=Сатови
+GenericName[sr@latin]=Satovi
+GenericName[sv]=Klockor
+GenericName[ta]=கடிகாரங்கள்
+GenericName[te]=గడియారాలు
+GenericName[tg]=Соатҳо
+GenericName[th]=นาฬิกา
+GenericName[tr]=Saatler
+GenericName[uk]=Годинники
+GenericName[vi]=Đồng hồ
+GenericName[zh_CN]=时钟
+GenericName[zh_HK]=時鐘
+GenericName[zh_TW]=時鐘
+GenericName[ug]=سائەتلەر
+GenericName=Clocks
+X-GNOME-FullName[af]=GNOME Horlosies
+X-GNOME-FullName[an]=Reloches d'o GNOME
+X-GNOME-FullName[ar]=ساعات جنوم
+X-GNOME-FullName[as]=GNOME ঘড়ী
+X-GNOME-FullName[be]=Гадзіннікі GNOME
+X-GNOME-FullName[bg]=Часовници
+X-GNOME-FullName[bn_IN]=GNOME ঘড়ি
+X-GNOME-FullName[bs]=GNOME satovi
+X-GNOME-FullName[ca]=Rellotges del GNOME
+X-GNOME-FullName[ca@valencia]=Rellotges del GNOME
+X-GNOME-FullName[cs]=Hodiny GNOME
+X-GNOME-FullName[da]=GNOME Ure
+X-GNOME-FullName[de]=GNOME-Uhren
+X-GNOME-FullName[el]=Ρολόγια GNOME
+X-GNOME-FullName[en_GB]=GNOME Clocks
+X-GNOME-FullName[eo]=GNOME-horloĝoj
+X-GNOME-FullName[es]=Relojes de GNOME
+X-GNOME-FullName[et]=GNOME kell
+X-GNOME-FullName[eu]=GNOMEren ordulariak
+X-GNOME-FullName[fa]=ساعت‌های گنوم
+X-GNOME-FullName[fi]=Gnomen kellot
+X-GNOME-FullName[fr]=Horloges de GNOME
+X-GNOME-FullName[fur]=Orlois par GNOME
+X-GNOME-FullName[ga]=Cloig GNOME
+X-GNOME-FullName[gd]=Uaireadairean GNOME
+X-GNOME-FullName[gl]=Reloxos de GNOME
+X-GNOME-FullName[gu]=GNOME ઘડિયાળ
+X-GNOME-FullName[he]=שעונים מבית GNOME
+X-GNOME-FullName[hi]=गनोम घड़ी
+X-GNOME-FullName[hr]=GNOME satovi
+X-GNOME-FullName[hu]=GNOME órák
+X-GNOME-FullName[id]=Jam GNOME
+X-GNOME-FullName[is]=GNOME Klukkur
+X-GNOME-FullName[it]=Orologi per GNOME
+X-GNOME-FullName[ja]=GNOME Clocks
+X-GNOME-FullName[kk]=GNOME сағаттары
+X-GNOME-FullName[ko]=그놈 시계
+X-GNOME-FullName[kn]=GNOME ಕ್ಲಾಕ್ಸ್
+X-GNOME-FullName[lt]=GNOME laikrodžiai
+X-GNOME-FullName[lv]=GNOME pulksteņi
+X-GNOME-FullName[ml]=ഗ്നോം ക്ലോക്കുകൾ
+X-GNOME-FullName[mr]=GNOME घड्याळी
+X-GNOME-FullName[nb]=GNOME klokker
+X-GNOME-FullName[ne]=जिनोम घडी
+X-GNOME-FullName[nl]=Gnome Klok
+X-GNOME-FullName[oc]=Relòtges GNOME
+X-GNOME-FullName[or]=GNOME ଘଣ୍ଟାଗୁଡ଼ିକ
+X-GNOME-FullName[pa]=ਗਨੋਮ ਘੜੀ
+X-GNOME-FullName[pl]=Zegar GNOME
+X-GNOME-FullName[pt]=Relógios GNOME
+X-GNOME-FullName[pt_BR]=Relógios do GNOME
+X-GNOME-FullName[ro]=Ceasuri GNOME
+X-GNOME-FullName[ru]=Часы GNOME
+X-GNOME-FullName[sk]=Hodiny prostredia GNOME
+X-GNOME-FullName[sl]=Gnomeove ure
+X-GNOME-FullName[sr]=Гномови сатови
+X-GNOME-FullName[sr@latin]=Gnomovi satovi
+X-GNOME-FullName[sv]=GNOME Klockor
+X-GNOME-FullName[ta]=க்னோம் கடிகாரங்கள்
+X-GNOME-FullName[te]=గ్నోమ్ గడియారాలు
+X-GNOME-FullName[tg]=Соатҳои GNOME
+X-GNOME-FullName[th]=นาฬิกา GNOME
+X-GNOME-FullName[tr]=GNOME Saatleri
+X-GNOME-FullName[vi]=Đồng hồ GNOME
+X-GNOME-FullName[zh_CN]=GNOME 时钟
+X-GNOME-FullName[zh_HK]=GNOME Clocks
+X-GNOME-FullName[zh_TW]=GNOME 時鐘
+X-GNOME-FullName[ug]=گىنوم سائەتلىرى
+X-GNOME-FullName=GNOME Clocks
+Comment[af]=Horlosies vir wêreldtyd, plus wekkers, stophorlosie en 'n tydteller
+Comment[an]=Reloches d'horas mundials, amás d'alarmas, cronometro y un temporizador
+Comment[ar]=ساعات لتوقيتات العالم، مع منبه ومُؤقّت وساعة إيقاف.
+Comment[as]=বিশ্বৰ সময়সমূহৰ বাবে ঘড়ী, লগতে এলাৰ্ম, স্টপৱাচ আৰু এটা টাইমাৰ
+Comment[be]=Гадзіннікі для адсочвання часу ў розных кутках свету, з будзільнікам, таймерам і секундамерам
+Comment[bg]=Часовници за различни градове, аларми, хронометър и отброяване
+Comment[bn_IN]=বিশ্বঘড়ি, প্লাস অ্যালার্ম, স্টপওয়াচ এবং টাইমারের জন্য ঘড়ি
+Comment[bs]=Satovi za svjetsko vrijeme, plus alarmi, štoperica i tajmer
+Comment[ca]=Rellotges de tot el món, a més d'alarmes, de cronòmetres i de temporitzadors
+Comment[ca@valencia]=Rellotges de tot el món, a més d'alarmes, de cronòmetres i de temporitzadors
+Comment[cs]=Hodiny s časy ve světě, budíkem, stopkami a odpočtem
+Comment[da]=Verdensur plus alarmer, stopur og et minutur
+Comment[de]=Uhren für die Weltzeit mit Alarm, Stoppuhr und einem Timer
+Comment[el]=Ρολόγια για παγκόσμιες ώρες, για ειδοποιήσεις, με χρονόμετρο και αντίστροφη μέτρηση
+Comment[en_GB]=Clocks for world times, plus alarms, stopwatch and a timer
+Comment[eo]=Horloĝoj por mondaj horoj, plus alarmoj, kronometro kaj minutatoro
+Comment[es]=Relojes de horas mundiales, además de alarmas, cronómetro y un temporizador
+Comment[et]=Kell maailmaajaga, alarmide, stopperi ja taimeriga
+Comment[eu]=Ordulariak munduko orduetarako, gehi alarmak, kronometroa eta tenporizadorea
+Comment[fa]=ساعت‌هایی برای زمان‌ها در دنیا، با اضافه‌ی زنگ هشدار، کرنومتر و زمان‌سنج
+Comment[fi]=Kellot eri puolille maailmaa, hälytykset, sekuntikello ja ajastin
+Comment[fr]=Des horloges pour connaître l’heure dans le monde, régler des alarmes, chronométrer ou lancer un décompte
+Comment[fur]=Orlois par i fûs oraris tal mont, sveis, cronometri e un timer
+Comment[gd]=Uaireadairean airson àm an t-saoghail le caismeachdan, stad-uaireadair ’s tìmear
+Comment[gl]=Reloxos para todo o mundo, ademais de alarmas, cronómetro e un temporizador
+Comment[gu]=વિશ્ર્વનો સમય, વત્તા એલાર્મ, સ્ટોપવૉચ અને ટાઇમર માટે ઘડિયાળો
+Comment[he]=שעונים לזמנים שונים ברחבי העולם לרבות התרעות, שעון עצר וקוצב זמן
+Comment[hi]=विश्व समय, के साथ साथ अलार्म, स्टॉपवॉच और एक टाइमर के लिए घड़ियां
+Comment[hr]=Satovi sa svjetskim vremenima, uključujući alarme, štopericu i odbrojavanje vremena
+Comment[hu]=Világidő, figyelmeztetés, stopper és időzítő
+Comment[id]=Jam untuk waktu dunia, alarm, stopwatch dan penghitung waktu
+Comment[is]=Klukkur á ýmsum stöðum, vekjaraklukkur, skeiðklukka og niðurteljari.
+Comment[it]=Orologi per i fusi orari nel mondo, sveglie, cronometro e un timer
+Comment[ja]=世界時計、アラーム、ストップウォッチ、およびタイマー機能をもつ時計アプリケーション
+Comment[kk]=Дүниежүзілік уақыттары үшін сағаттар, құрамында тағы оятқыш, секундтар өлшегіші және таймері бар
+Comment[ko]=세계 시계, 알림, 초시계, 타이머 기능이 있는 시계
+Comment[kn]=ಪ್ರಪಂಚದ ಸಮಯಕ್ಕಾಗಿನ, ಜೊತೆಗೆ ಅಲಾರಂಗಳಿಗಾಗಿನ, ಸ್ಟಾಪ್‌ವಾಚ್‌ಗಾಗಿನ ಮತ್ತು ಟೈಮರಿಗಾಗಿನ ಗಡಿಯಾರಗಳು
+Comment[lt]=Pasaulio laikų laikrodžiai, taip pat žadintuvai, chronometras ir laikmatis
+Comment[lv]=Pulksteņi pasaules laikiem, kā arī modinātājs, hronometrs un taimeris
+Comment[ml]=ലോകത്തെവിടെയുമുള്ള സമയം കാണിയ്ക്കുന്ന ക്ലോക്കുകൾ, അലാറങ്ങൾ, സ്റ്റോപ്പ്‌വാച്ച്, ടൈമര്‍ എന്നിവയും
+Comment[mr]=जागतिक वेळ, तसेच गजर, स्टॉपवॉच व टाइमरकरीता घड्याळी
+Comment[nb]=Klokker med verdenstid, alarm, stoppeklokke og nedtelling
+Comment[nl]=Wereldklok, wekker, stopwatch en timer
+Comment[oc]=De relòtges per conéisser l'ora dins lo mond, reglar d'alarmas, cronometrar o aviar un descompte
+Comment[or]=ବିଶ୍ୱ ସମୟ ପାଇଁ ଘଣ୍ଟାଗୁଡ଼ିକ, ଏହା ସହିତ ଆଲାର୍ମ, ଷ୍ଟପୱାଚ ଏବଂ ସମୟ ମାପକ
+Comment[pa]=ਸੰਸਾਰ ਸਮਾਂ, ਅਲਾਰਮ, ਸਟਾਪਵਾਚ ਅਤੇ ਟਾਈਮਰ ਦੇ ਨਾਲ ਘੜੀਆਂ
+Comment[pl]=Zegar światowy, budzik, stoper i minutnik
+Comment[pt]=Relógios com as horas do mundo, alarmes, cronómetros e um temporizador
+Comment[pt_BR]=Relógios para horários mundiais além de alarmes, cronômetro e um temporizador
+Comment[ro]=Ora în lume, alarme, cronometru și temporizator
+Comment[ru]=Часы мирового времени, а также будильник, секундомер и таймер
+Comment[sk]=Hodiny svetového času, budík, stopky a časovač
+Comment[sl]=Ure za prikazovanje svetovnega časa, alarmi, štoparica in časomer
+Comment[sr]=Сатови за светска времена, будилници, штоперица и одбројавач
+Comment[sr@latin]=Satovi za svetska vremena, budilnici, štoperica i odbrojavač
+Comment[sv]=Klockor för världstider, alarm, stoppur och en timer
+Comment[ta]=உலக நேரம், எச்சரிக்கை மணிகள், நிறுத்த கடிகாரம், நேர அளவி கொண்ட கடிகாரங்கள்
+Comment[te]=ప్రపంచ సమయాలకు,అలారాలకు, స్టాప్‍వాచ్ ఇంకా సమయకానికి ఉపయోగపడే గడియారాలు
+Comment[tg]=Соат барои вақти ҷаҳон, аз ҷумла истифодаи ҳушдорҳо, сонияшумор ва вақтсанҷ
+Comment[th]=นาฬิกาสำหรับเวลาทั่วโลก, พร้อมด้วยนาฬิกาปลุก, นาฬิกาจับเวลา และนาฬิกานับถอยหลัง
+Comment[tr]=Dünya saatleri, alarmlar, kronometre ve zaman ölçer
+Comment[vi]=Đồng hồ thế giới, kèm báo thức và đo giờ
+Comment[zh_CN]=时钟可用来查看世界时间,外加闹钟、秒表和定时器功能
+Comment[zh_HK]=包含世界時刻的時鐘,加上鬧鐘、碼表和計時器
+Comment[zh_TW]=包含世界時刻的時鐘,加上鬧鐘、碼表和計時器
+Comment[ug]=دۇنيا ۋاقىتلىرى، قوڭغۇراقلىق سائەت، ۋاقىت ئۆلچىگۈچ
+Comment=Clocks for world times, plus alarms, stopwatch and a timer
+Keywords[af]=time;timer;alarm;world clock;stopwatch;time zone;tyd;tydteller;wekker;wêreldtyd;stophorlosie;tydsone;tydhou;
+Keywords[an]=Hora;Temporizador;Alarma;Hora mundial;Cronometro;Zona horaria;
+Keywords[ar]=وقت;موقت;منبه;ساعة عالمية;ساعة إيقاف;منطقة زمنية;
+Keywords[as]=time;timer;alarm;world clock;stopwatch;time zone;
+Keywords[be]=час;таймер;гадзіннік;будзільнік;сусветны гадзіннік;секундамер;часавы пояс;
+Keywords[bg]=време;обратно;отброяване;напомняне;аларма;часовник;секундомер;пояс;хронометър;time;timer;alarm;world clock;stopwatch;time zone;
+Keywords[bn_IN]=সময়;টাইমার;অ্যালার্ম;বিশ্বঘড়ি;স্টপওয়াচ;সময় জোন;
+Keywords[bs]=vrijeme;tajmer;alarm;svjetski sat;štoperica;vremenska zona;
+Keywords[ca]=temps;temporitzador;alarma;rellotge global;cronòmetre;zona horària;
+Keywords[ca@valencia]=temps;temporitzador;alarma;rellotge global;cronòmetre;zona horària;
+Keywords[cs]=čas;časovač;minutka;odpočet;budík;buzení;světový čas;stopky;časové pásmo;
+Keywords[da]=tid;timer;minutur;alarm;vækkeur;verdensur;stopur;ur;tidszone;klokken;
+Keywords[de]=Zeit;Uhrzeit;Alarm;Weltuhr;Stoppuhr;Zeitzone;
+Keywords[el]=χρόνος;χρονόμετρο;ξυπνητήρι;παγκόσμιο ρολόι;χρονόμετρο;ώρα ζώνης;time;timer;alarm;world clock;stopwatch;time zone;
+Keywords[en_GB]=time;timer;alarm;world clock;stopwatch;time zone;
+Keywords[eo]=horo;minutatoro;alarmo;monda horloĝo;kronometro;horzono;
+Keywords[es]=Hora;Temporizador;Alarma;Hora mundial;Cronómetro;Zona horaria;
+Keywords[et]=aeg;kell;kuupäev;taimer;alarm;äratus;maailmakell;stopper;ajavöönd;ajatsoon;
+Keywords[eu]=ordua;tenporizadorea;alarma;munduko ordulariak;kronometroa;ordu-zona;
+Keywords[fa]=time;timer;alarm;world clock;stopwatch;time zone;زمان;زمانسنج;زنگ;ساعت جهانی;منطقه زمانی;
+Keywords[fi]=time;timer;alarm;world clock;stopwatch;time zone;aika;ajastin;hälytys;maailmankello;aikavyöhyke;
+Keywords[fr]=heure;minuterie;décompte;alarme;horloge mondiale;chronomètre;fuseau horaire;
+Keywords[fur]=ore;orari;timp;orloi;cronometri;fûs orari;svee;alarme;
+Keywords[gd]=time;timer;alarm;world clock;stopwatch;time zone;àm;ùine;tìmear;uaireadair an t-saoghail;uaireadair;saoghal;cleoc;gleoc;stad-uaireadair;roinn-tìde;
+Keywords[gl]=tempo;temporizador;alarma;reloxo mundial;reloxo de parada;fuso horario;
+Keywords[gu]=સમય;ટાઇમર;એલાર્મ;વિશ્ર્વ ઘડિયાળો;સ્ટોપવૉચ;ટાઇમઝોન;
+Keywords[he]=זמן;שעה;טיימר;קוצב זמן;שעון עולמי;שעון עצר;סטופר;אזור זמן;שעון;
+Keywords[hi]=समय; टाइमर;अलार्म;दुनिया घड़ी; स्टॉपवॉच; समय क्षेत्र;
+Keywords[hr]=vrijeme;odbrojavanje;alarm;svjetski sat;štoperica;vremenska zona;
+Keywords[hu]=idő;időzítő;riasztás;világóra;stopper;időzóna;
+Keywords[id]=time;timer;alarm;world clock;stopwatch;time zone;jam;waktu;
+Keywords[is]=tími;heimsklukka;vekjari;skeiðklukka;niðurteljari;tímabelti;
+Keywords[it]=ora;orario;tempo;orologio;cronometro;fuso orario;sveglia;allarme;
+Keywords[ja]=time;timer;alarm;world clock;stopwatch;time zone;時間;時刻;タイム;タイマー;アラーム;世界時計;時計;ストップウォッチ;ストップウオッチ;タイムゾーン;
+Keywords[kk]=time;timer;alarm;world clock;stopwatch;time zone;уақыт;таймер;оятқыш;дүниежүзі сағаты;секундтар өлшегіші;уақыт белдеуі;
+Keywords[ko]=time;시간;timer;타이머;alarm;알림;world clock;세계 시계;stopwatch;스톱워치;time zone;시간대;
+Keywords[kn]=ಸಮಯ;ಟೈಮರ್;ಅಲಾರಂ;ಪ್ರಪಂಚದ ಗಡಿಯಾರ;ಸ್ಟಾಪ್‌ವಾಚ್;ಕಾಲ ವಲಯ;
+Keywords[lt]=laikas;laikmatis;žadintuvas;pasaulio laikrodis;chronometras;laiko juosta;
+Keywords[lv]=laiks;taimeris;modinātājs;pasaules pulkstenis;hronometrs;laika zona;signāls;
+Keywords[ml]=time;timer;alarm;world clock;stopwatch;time zone;
+Keywords[mr]=वेळ;टाइमर;गजर;जागतिक घड्याळ;स्टॉपवॉच;वेळ क्षेत्र;
+Keywords[nb]=tid;nedtelling;alarm;verdensklokke;stoppeklokke;tidssone;
+Keywords[nl]=time;timer;alarm;world clock;stopwatch;time zone;klok;tijd;wekker;wereldtijd;wereldklok;tijdzone;
+Keywords[oc]=ora;minutariá;descompte;alarma;relòtge mondiala;cronomètre;fus orari;
+Keywords[or]=ସମୟ;ସମୟ ମାପକ;ଆଲାର୍ମ;ବିଶ୍ୱ ସମୟ;ଷ୍ଟପ ୱାଚ;ସମୟ ମଣ୍ଡଳ;
+Keywords[pa]=ਸਮਾਂ;ਟਾਈਮ;ਟਾਈਮਰ;ਅਲਾਰਮ;ਸੰਸਾਰ ਘੜੀ;ਸਟਾਪਵਾਚ;ਸਮਾਂ ਖੇਤਰ;ਟਾਈਮ ਜ਼ੋਨ;ਖੇਤਰ;ਵੇਲਾ;ਦੁਨਿਆਂ;ਕਲਾਕ;ਵਕਤ;
+Keywords[pl]=czas;minutnik;timer;budzik;alarm;zegar światowy;stoper;strefa czasowa;
+Keywords[pt]=horas;temporizador;alarme;relógio mundial;cronómetro;fuso horário;
+Keywords[pt_BR]=hora;temporizador;alarme;relógio mundial;cronômetro;fuso horário;
+Keywords[ro]=timp;temporizator;fus orar;cronometru;alarmă;time;timer;alarm;world clock;stopwatch;time zone;
+Keywords[ru]=время;таймер;будильник;мировое время;часовой пояс;
+Keywords[sk]=čas;časovač;budík;svetový čas;stopky;časová zóna;
+Keywords[sl]=čas;časomer;alarm;svetovne ure;štoparica;časovni pas;
+Keywords[sr]=време;одбројавач;аларм;будилник;светски сат;штоперица;временска зона;
+Keywords[sr@latin]=vreme;odbrojavač;alarm;budilnik;svetski sat;štoperica;vremenska zona;
+Keywords[sv]=tid;timer;alarm:världsklocka;världsur;stoppur;tidszon;
+Keywords[ta]=நேரம்;நேர அளவி;எச்சரிப்பான்;உலக கடிகாரம்;நிறுத்தக் கடிகாரம்;காலப்பகுதி;
+Keywords[te]=సమయం;సమయకం;అలారం;ప్రపంచ గడియారం;స్టాప్‌వాచ్;సమయక్షేత్రం;
+Keywords[tg]=вақт;вақтсанҷ;ҳушдор;соати ҷаҳон;сонияшумор;минтақаи вақт;
+Keywords[th]=เวลา;นาฬิกานับถอยหลัง;นาฬิกาปลุก;นาฬิกาทั่วโลก;นาฬิกาจับเวลา;เขตเวลา;
+Keywords[tr]=saat;zaman;geri sayım;alarm;dünya saatleri;kronometre;saat dilimi;
+Keywords[vi]=time;thời;gian;thoi;timer;hẹn;giờ;hen;gio;alarm;world clock;đồng;hồ;dong;ho;stopwatch;time zone;múi;mui;bấm;
+Keywords[zh_CN]=time;timer;alarm;world clock;stopwatch;time zone;钟;表;定时;计时;时间;时区;
+Keywords[zh_HK]=time;timer;alarm;world clock;stopwatch;time zone;時間;計時器;鬧鐘;鬧鈴;世界時鐘;碼表;時區;
+Keywords[zh_TW]=time;timer;alarm;world clock;stopwatch;time zone;時間;倒數;計時器;鬧鐘;鬧鈴;世界時鐘;碼表;時區;
+Keywords[ug]=time;timer;alarm;world clock;stopwatch;time zone;ۋاقىت;ئۆلچىگۈچ;قوڭغۇراق;دۇنيا سائىتى;ۋاقىت رايونى;
+Keywords=time;timer;alarm;world clock;stopwatch;time zone;
+# GDesktopAppInfo requires that the command exists, so use /bin/sh
+# rather than /usr/bin/flatpak, since that's guaranteed to exist on
+# all test systems (in particular CI machines).
+Exec=/bin/sh run --branch=stable --arch=x86_64 --command=gnome-clocks org.gnome.clocks
+Icon=org.gnome.clocks
+Terminal=false
+Type=Application
+Categories=GNOME;GTK;Utility;Clock;
+StartupNotify=true
+DBusActivatable=true
+X-GNOME-UsesNotifications=true
+X-Geoclue-Reason[af]=Laat wêreldhorlosies toe om vir jou tydsone vertoon te word.
+X-Geoclue-Reason[ar]=يتيح عرض الساعات العالمية في منطقة الزمنية الحالية.
+X-Geoclue-Reason[be]=Дазваляе паказваць сусветныя гадзіннікі для вашага часавога пояса.
+X-Geoclue-Reason[ca]=Permet que els rellotges del món es mostrin a la vostra zona horària.
+X-Geoclue-Reason[ca@valencia]=Permet que els rellotges del món es mostren a la vostra zona horària.
+X-Geoclue-Reason[cs]=Umožňuje zobrazit světové časy pro vaše časová pásma.
+X-Geoclue-Reason[da]=Lader verdensure blive vist for din tidszone.
+X-Geoclue-Reason[de]=Ermöglicht die Anzeige von Weltuhren für Ihre Zeitzone.
+X-Geoclue-Reason[el]=Επιτρέπει την εμφάνιση των παγκόσμιων ρολογιών για την ζώνη ώρας σας.
+X-Geoclue-Reason[en_GB]=Allows world clocks to be displayed for your time zone.
+X-Geoclue-Reason[es]=Permite a los relojes del mundo mostrarse para su zona horaria.
+X-Geoclue-Reason[eu]=Munduko ordulariak zure ordu-zonan bistaratzea baimentzen du.
+X-Geoclue-Reason[fa]=اجازه می‌دهد تا ساعت‌های جهانی برای منطقه زمانی شما نمایش داده شود.
+X-Geoclue-Reason[fi]=Mahdollistaa maailmankellojen esityksen aikavyöhykkeellesi.
+X-Geoclue-Reason[fr]=Permet d’afficher des horloges mondiales selon votre fuseau horaire.
+X-Geoclue-Reason[fur]=Al permet di mostrâ orlois di dut il mont pal tô fûs orari.
+X-Geoclue-Reason[gd]=Leigidh seo leat uaireadairean an t-saoghail a shealltainn airson na roinn-tìde agad.
+X-Geoclue-Reason[gl]=Permítelle mostrar reloxos do mundio para o seu fuso horario.
+X-Geoclue-Reason[he]=מאפשר הצגת שעונים מסביב לעולם עבור אזור הזמן שלך.
+X-Geoclue-Reason[hr]=Dopušta svjetskim satovima prikaz u vašoj vremenskoj zoni.
+X-Geoclue-Reason[hu]=Világórák megjelenítése az időzónájához.
+X-Geoclue-Reason[id]=Mengijinkan jam dunia ditampilkan untuk zona waktu Anda.
+X-Geoclue-Reason[is]=Gerir kleift að birta klukku fyrir staðinn þar sem þú ert.
+X-Geoclue-Reason[it]=Consente di visualizzare orologi per il proprio fuso orario.
+X-Geoclue-Reason[ja]=タイムゾーンに対応した世界時計を表示します。
+X-Geoclue-Reason[kk]=Сіздің уақыт белдеуіңіз үшін дүниежүзілік сағаттарды көрсетуді мүмкін етеді.
+X-Geoclue-Reason[ko]=현재 시간대에 해당하는 세계 시계 표시 허용.
+X-Geoclue-Reason[lt]=Leidžia rodyti pasaulio laikrodžius jūsų laiko zonai.
+X-Geoclue-Reason[lv]=Ļauj parādīt pasaules pulksteņus jūsu laika joslai.
+X-Geoclue-Reason[ml]=താങ്കളുടെ സമയമേഖലയ്ക്കനുസരിച്ച് ലോകത്തെ മറ്റു സ്ഥലങ്ങളിലെ ക്ലോക്കുകൾ പ്രദർശിപ്പിക്കാൻ അനുവദിക്കുന്നു.
+X-Geoclue-Reason[nb]=Tillat visning av verdensklokker for din tidssone.
+X-Geoclue-Reason[nl]=Uw tijdzone kan worden weergegeven in de wereldklok.
+X-Geoclue-Reason[pa]=ਤੁਹਾਡੇ ਸਮਾਂ ਖੇਤਰ ਲਈ ਸੰਸਾਰ ਘੜੀਆਂ ਵਿਖਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿਉ।
+X-Geoclue-Reason[pl]=Umożliwia wyświetlanie zegara dla strefy czasowej użytkownika.
+X-Geoclue-Reason[pt]=Permite que o relógio mundial apresente o seu fuso horário.
+X-Geoclue-Reason[pt_BR]=Permite que relógios mundiais sejam exibidos para o seu fuso horário.
+X-Geoclue-Reason[ru]=Позволяет отображать мировые часы для вашего часового пояса.
+X-Geoclue-Reason[sk]=Umožňuje zobrazenie svetových hodín pre vašu časovú zónu.
+X-Geoclue-Reason[sl]=Dovoli prikaz svetovnih časov za trenutno časovno območje.
+X-Geoclue-Reason[sr]=Допустите да светски сатови буду приказани за вашу временску зону.
+X-Geoclue-Reason[sr@latin]=Dopustite da svetski satovi budu prikazani za vašu vremensku zonu.
+X-Geoclue-Reason[sv]=Låter världsklockor visas för din tidszon.
+X-Geoclue-Reason[th]=เพื่อให้สามารถแสดงนาฬิกาทั่วโลกสำหรับเขตเวลาของคุณ
+X-Geoclue-Reason[tr]=Saat diliminiz için dünya saatlerinin gösterilmesine olanak tanır.
+X-Geoclue-Reason[vi]=Cho phép các đồng hồ thế giới hiển thị cho múi giờ của bạn.
+X-Geoclue-Reason[zh_CN]=允许为您的时区显示世界时钟
+X-Geoclue-Reason[zh_TW]=允許為您的時區顯示世界時鐘。
+X-Geoclue-Reason=Allows world clocks to be displayed for your time zone.
+X-Flatpak=org.gnome.clocks
diff --git a/gio/tests/file.c b/gio/tests/file.c
index 98eeb85d4..04625fd68 100644
--- a/gio/tests/file.c
+++ b/gio/tests/file.c
@@ -155,7 +155,7 @@ typedef struct
gint monitor_changed;
gchar *monitor_path;
gint pos;
- gchar *data;
+ const gchar *data;
gchar *buffer;
guint timeout;
} CreateDeleteData;
@@ -510,7 +510,7 @@ test_create_delete (gconstpointer d)
skip:
g_object_unref (data->monitor);
g_object_unref (data->file);
- free (data->monitor_path);
+ g_free (data->monitor_path);
g_free (data->buffer);
g_free (data);
}
@@ -962,7 +962,7 @@ test_measure (void)
if (size > 0)
g_assert_cmpuint (num_bytes, ==, size);
g_assert_cmpuint (num_dirs, ==, 6);
- g_assert_cmpuint (num_files, ==, 30);
+ g_assert_cmpuint (num_files, ==, 31);
g_object_unref (file);
g_free (path);
@@ -1056,7 +1056,7 @@ test_measure_async (void)
g_free (path);
data->expected_dirs = 6;
- data->expected_files = 30;
+ data->expected_files = 31;
g_file_measure_disk_usage_async (file,
G_FILE_MEASURE_APPARENT_SIZE,
diff --git a/gio/tests/fileattributematcher.c b/gio/tests/fileattributematcher.c
index 6956e6a36..553d57b19 100644
--- a/gio/tests/fileattributematcher.c
+++ b/gio/tests/fileattributematcher.c
@@ -3,7 +3,7 @@
static void
test_exact (void)
{
- char *exact_matches[] = {
+ const char *exact_matches[] = {
"*",
"a::*",
"a::*,b::*",
@@ -29,8 +29,8 @@ static void
test_equality (void)
{
struct {
- char *expected;
- char *actual;
+ const char *expected;
+ const char *actual;
} equals[] = {
/* star makes everything else go away */
{ "*", "*,*" },
@@ -70,9 +70,9 @@ static void
test_subtract (void)
{
struct {
- char *attributes;
- char *subtract;
- char *result;
+ const char *attributes;
+ const char *subtract;
+ const char *result;
} subtractions[] = {
/* * subtracts everything */
{ "*", "*", NULL },
diff --git a/gio/tests/g-file-info-filesystem-readonly.c b/gio/tests/g-file-info-filesystem-readonly.c
index 9a185b081..c2b0aa518 100644
--- a/gio/tests/g-file-info-filesystem-readonly.c
+++ b/gio/tests/g-file-info-filesystem-readonly.c
@@ -29,7 +29,7 @@ test_filesystem_readonly (gconstpointer with_mount_monitor)
{
GFileInfo *file_info;
GFile *mounted_file;
- GUnixMountMonitor *mount_monitor;
+ GUnixMountMonitor *mount_monitor = NULL;
gchar *bindfs, *fusermount;
gchar *command_mount, *command_mount_ro, *command_umount;
gchar *curdir, *dir_to_mount, *dir_mountpoint;
@@ -62,9 +62,7 @@ test_filesystem_readonly (gconstpointer with_mount_monitor)
}
if (with_mount_monitor)
- {
- mount_monitor = g_unix_mount_monitor_get ();
- }
+ mount_monitor = g_unix_mount_monitor_get ();
/* Use bindfs, which does not need root privileges, to mount the contents of one dir
* into another dir (and do the mount as readonly as per passed '-o ro' option) */
@@ -125,9 +123,7 @@ test_filesystem_readonly (gconstpointer with_mount_monitor)
}
/* Clean up */
- if (with_mount_monitor)
- g_clear_object (&mount_monitor);
-
+ g_clear_object (&mount_monitor);
g_clear_object (&file_info);
g_clear_object (&mounted_file);
g_spawn_command_line_sync (command_umount, NULL, NULL, NULL, NULL); /* unmount */
diff --git a/gio/tests/gdbus-addresses.c b/gio/tests/gdbus-addresses.c
index 0ab05661a..2e662d000 100644
--- a/gio/tests/gdbus-addresses.c
+++ b/gio/tests/gdbus-addresses.c
@@ -39,86 +39,65 @@ test_empty_address (void)
g_error_free (error);
}
-static void
-assert_is_supported_address (const gchar *address)
-{
- GError *error = NULL;
-
- g_assert_true (g_dbus_is_supported_address (address, NULL));
- g_assert_true (g_dbus_is_supported_address (address, &error));
- g_assert_no_error (error);
-}
-
-static void
-assert_not_supported_address (const gchar *address)
-{
- GError *error = NULL;
-
- g_assert_false (g_dbus_is_supported_address (address, NULL));
- g_assert_false (g_dbus_is_supported_address (address, &error));
- g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
- g_clear_error (&error);
-}
-
#ifdef G_OS_UNIX
static void
test_unix_address (void)
{
- assert_not_supported_address ("some-imaginary-transport:foo=bar");
- assert_is_supported_address ("unix:path=/tmp/dbus-test");
- assert_is_supported_address ("unix:abstract=/tmp/dbus-another-test");
+ g_assert (!g_dbus_is_supported_address ("some-imaginary-transport:foo=bar", NULL));
+ g_assert (g_dbus_is_supported_address ("unix:path=/tmp/dbus-test", NULL));
+ g_assert (g_dbus_is_supported_address ("unix:abstract=/tmp/dbus-another-test", NULL));
g_assert (g_dbus_is_address ("unix:foo=bar"));
- assert_not_supported_address ("unix:foo=bar");
+ g_assert (!g_dbus_is_supported_address ("unix:foo=bar", NULL));
g_assert (!g_dbus_is_address ("unix:path=/foo;abstract=/bar"));
- assert_not_supported_address ("unix:path=/foo;abstract=/bar");
- assert_is_supported_address ("unix:path=/tmp/concrete;unix:abstract=/tmp/abstract");
+ g_assert (!g_dbus_is_supported_address ("unix:path=/foo;abstract=/bar", NULL));
+ g_assert (g_dbus_is_supported_address ("unix:path=/tmp/concrete;unix:abstract=/tmp/abstract", NULL));
g_assert (g_dbus_is_address ("some-imaginary-transport:foo=bar"));
g_assert (g_dbus_is_address ("some-imaginary-transport:foo=bar;unix:path=/this/is/valid"));
- assert_not_supported_address ("some-imaginary-transport:foo=bar;unix:path=/this/is/valid");
+ g_assert (!g_dbus_is_supported_address ("some-imaginary-transport:foo=bar;unix:path=/this/is/valid", NULL));
}
#endif
static void
test_nonce_tcp_address (void)
{
- assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar");
- assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=ipv6");
- assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=ipv4");
-
- assert_not_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=blah");
- assert_not_supported_address ("nonce-tcp:host=localhost,port=420000,noncefile=/foo/bar,family=ipv4");
- assert_not_supported_address ("nonce-tcp:host=,port=x42,noncefile=/foo/bar,family=ipv4");
- assert_not_supported_address ("nonce-tcp:host=,port=42x,noncefile=/foo/bar,family=ipv4");
- assert_not_supported_address ("nonce-tcp:host=,port=420000,noncefile=/foo/bar,family=ipv4");
+ g_assert (g_dbus_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar", NULL));
+ g_assert (g_dbus_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=ipv6", NULL));
+ g_assert (g_dbus_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=ipv4", NULL));
+
+ g_assert (!g_dbus_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=blah", NULL));
+ g_assert (!g_dbus_is_supported_address ("nonce-tcp:host=localhost,port=420000,noncefile=/foo/bar,family=ipv4", NULL));
+ g_assert (!g_dbus_is_supported_address ("nonce-tcp:host=,port=x42,noncefile=/foo/bar,family=ipv4", NULL));
+ g_assert (!g_dbus_is_supported_address ("nonce-tcp:host=,port=42x,noncefile=/foo/bar,family=ipv4", NULL));
+ g_assert (!g_dbus_is_supported_address ("nonce-tcp:host=,port=420000,noncefile=/foo/bar,family=ipv4", NULL));
}
static void
test_tcp_address (void)
{
- assert_is_supported_address ("tcp:host=localhost");
- assert_not_supported_address ("tcp:host=localhost,noncefile=/tmp/foo");
- assert_is_supported_address ("tcp:host=localhost,port=42");
- assert_not_supported_address ("tcp:host=localhost,port=-1");
- assert_not_supported_address ("tcp:host=localhost,port=420000");
- assert_not_supported_address ("tcp:host=localhost,port=42x");
- assert_is_supported_address ("tcp:host=localhost,port=42,family=ipv4");
- assert_is_supported_address ("tcp:host=localhost,port=42,family=ipv6");
- assert_not_supported_address ("tcp:host=localhost,port=42,family=sopranos");
+ g_assert (g_dbus_is_supported_address ("tcp:host=localhost", NULL));
+ g_assert (!g_dbus_is_supported_address ("tcp:host=localhost,noncefile=/tmp/foo", NULL));
+ g_assert (g_dbus_is_supported_address ("tcp:host=localhost,port=42", NULL));
+ g_assert (!g_dbus_is_supported_address ("tcp:host=localhost,port=-1", NULL));
+ g_assert (!g_dbus_is_supported_address ("tcp:host=localhost,port=420000", NULL));
+ g_assert (!g_dbus_is_supported_address ("tcp:host=localhost,port=42x", NULL));
+ g_assert (g_dbus_is_supported_address ("tcp:host=localhost,port=42,family=ipv4", NULL));
+ g_assert (g_dbus_is_supported_address ("tcp:host=localhost,port=42,family=ipv6", NULL));
+ g_assert (!g_dbus_is_supported_address ("tcp:host=localhost,port=42,family=sopranos", NULL));
}
static void
test_autolaunch_address (void)
{
- assert_is_supported_address ("autolaunch:");
+ g_assert (g_dbus_is_supported_address ("autolaunch:", NULL));
}
static void
test_mixed_address (void)
{
- assert_is_supported_address ("unix:path=/tmp/dbus1;unix:path=/tmp/dbus2");
- assert_is_supported_address ("tcp:host=localhost,port=42;autolaunch:");
- assert_not_supported_address ("tcp:host=localhost,port=42;tcp:family=bla");
+ g_assert (g_dbus_is_supported_address ("unix:path=/tmp/dbus1;unix:path=/tmp/dbus2", NULL));
+ g_assert (g_dbus_is_supported_address ("tcp:host=localhost,port=42;autolaunch:", NULL));
+ g_assert (!g_dbus_is_supported_address ("tcp:host=localhost,port=42;tcp:family=bla", NULL));
}
static const struct { const char *before; const char *after; } escaping[] = {
diff --git a/gio/tests/gdbus-connection-slow.c b/gio/tests/gdbus-connection-slow.c
index 82e02587c..dd1ababd4 100644
--- a/gio/tests/gdbus-connection-slow.c
+++ b/gio/tests/gdbus-connection-slow.c
@@ -123,7 +123,7 @@ large_message_timeout_cb (gpointer data)
{
(void)data;
- g_error ("Error: timeout waiting for dbus name to appear\n");
+ g_error ("Error: timeout waiting for dbus name to appear");
return FALSE;
}
diff --git a/gio/tests/gdbus-serialization.c b/gio/tests/gdbus-serialization.c
index a6c242a13..da28f1bc1 100644
--- a/gio/tests/gdbus-serialization.c
+++ b/gio/tests/gdbus-serialization.c
@@ -855,7 +855,7 @@ message_serialize_header_checks (void)
{
GDBusMessage *message;
GDBusMessage *reply;
- GError *error = NULL;
+ GError *error;
guchar *blob;
gsize blob_size;
@@ -863,73 +863,65 @@ message_serialize_header_checks (void)
* check we can't serialize messages with INVALID type
*/
message = g_dbus_message_new ();
+ error = NULL;
blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: type is INVALID");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
g_object_unref (message);
/*
- * check that we can't serialize messages with SIGNATURE set to a non-signature-typed value
- */
- message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember");
- g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, g_variant_new_boolean (FALSE));
- blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
-
- g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
- g_assert_cmpstr (error->message, ==, "Signature header found but is not of type signature");
- g_assert_null (blob);
-
- g_clear_error (&error);
- g_clear_object (&message);
-
- /*
* check we can't serialize signal messages with INTERFACE, PATH or MEMBER unset / set to reserved value
*/
message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember");
/* ----- */
/* interface NULL => error */
g_dbus_message_set_interface (message, NULL);
+ error = NULL;
blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
/* interface reserved value => error */
g_dbus_message_set_interface (message, "org.freedesktop.DBus.Local");
+ error = NULL;
blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
/* reset interface */
g_dbus_message_set_interface (message, "The.Interface");
/* ----- */
/* path NULL => error */
g_dbus_message_set_path (message, NULL);
+ error = NULL;
blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
/* path reserved value => error */
g_dbus_message_set_path (message, "/org/freedesktop/DBus/Local");
+ error = NULL;
blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
/* reset path */
g_dbus_message_set_path (message, "/the/path");
/* ----- */
/* member NULL => error */
g_dbus_message_set_member (message, NULL);
+ error = NULL;
blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
/* reset member */
g_dbus_message_set_member (message, "TheMember");
/* ----- */
@@ -943,21 +935,23 @@ message_serialize_header_checks (void)
/* ----- */
/* path NULL => error */
g_dbus_message_set_path (message, NULL);
+ error = NULL;
blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_CALL message: PATH or MEMBER header field is missing");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
/* reset path */
g_dbus_message_set_path (message, "/the/path");
/* ----- */
/* member NULL => error */
g_dbus_message_set_member (message, NULL);
+ error = NULL;
blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_CALL message: PATH or MEMBER header field is missing");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
/* reset member */
g_dbus_message_set_member (message, "TheMember");
/* ----- */
@@ -973,31 +967,34 @@ message_serialize_header_checks (void)
reply = g_dbus_message_new_method_reply (message);
g_assert_cmpint (g_dbus_message_get_reply_serial (reply), ==, 42);
g_dbus_message_set_header (reply, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, NULL);
+ error = NULL;
blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_RETURN message: REPLY_SERIAL header field is missing");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
g_object_unref (reply);
/* method error - first nuke ERROR_NAME, then REPLY_SERIAL */
reply = g_dbus_message_new_method_error (message, "Some.Error.Name", "the message");
g_assert_cmpint (g_dbus_message_get_reply_serial (reply), ==, 42);
/* nuke ERROR_NAME */
g_dbus_message_set_error_name (reply, NULL);
+ error = NULL;
blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
/* reset ERROR_NAME */
g_dbus_message_set_error_name (reply, "Some.Error.Name");
/* nuke REPLY_SERIAL */
g_dbus_message_set_header (reply, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, NULL);
+ error = NULL;
blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (error->message, ==, "Cannot serialize message: ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing");
- g_clear_error (&error);
- g_assert_null (blob);
+ g_error_free (error);
+ g_assert (blob == NULL);
g_object_unref (reply);
g_object_unref (message);
}
@@ -1084,125 +1081,6 @@ test_double_array (void)
/* ---------------------------------------------------------------------------------------------------- */
-/* Test that an invalid header in a D-Bus message (specifically, with a type
- * which doesn’t match what’s expected for the given header) is gracefully
- * handled with an error rather than a crash.
- * The set of bytes here come directly from fuzzer output. */
-static void
-test_message_parse_non_signature_header (void)
-{
- const guint8 data[] = {
- 'l', /* little-endian byte order */
- 0x04, /* message type */
- 0x0f, /* message flags */
- 0x01, /* major protocol version */
- 0x00, 0x00, 0x00, 0x00, /* body length */
- 0x00, 0x00, 0x00, 0xbc, /* message serial */
- /* a{yv} of header fields:
- * (things start to be invalid below here) */
- 0x02, 0x00, 0x00, 0x00, /* array length (in bytes) */
- G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, /* array key */
- /* Variant array value: */
- 0x04, /* signature length */
- 'd', 0x00, 0x00, 'F', /* signature (invalid) */
- 0x00, /* nul terminator */
- /* (Variant array value payload missing) */
- /* (message body length missing) */
- };
- gsize size = sizeof (data);
- GDBusMessage *message = NULL;
- GError *local_error = NULL;
-
- message = g_dbus_message_new_from_blob ((guchar *) data, size,
- G_DBUS_CAPABILITY_FLAGS_NONE,
- &local_error);
- g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
- g_assert_null (message);
-
- g_clear_error (&local_error);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-/* Test that an invalid header in a D-Bus message (specifically, containing a
- * variant with an empty type signature) is gracefully handled with an error
- * rather than a crash. The set of bytes here come directly from fuzzer
- * output. */
-static void
-test_message_parse_empty_signature_header (void)
-{
- const guint8 data[] = {
- 'l', /* little-endian byte order */
- 0x20, /* message type */
- 0x20, /* message flags */
- 0x01, /* major protocol version */
- 0x20, 0x20, 0x20, 0x00, /* body length (invalid) */
- 0x20, 0x20, 0x20, 0x20, /* message serial */
- /* a{yv} of header fields:
- * (things start to be even more invalid below here) */
- 0x20, 0x20, 0x20, 0x00, /* array length (in bytes) */
- 0x20, /* array key */
- /* Variant array value: */
- 0x00, /* signature length */
- 0x00, /* nul terminator */
- /* (Variant array value payload missing) */
- /* (message body length missing) */
- };
- gsize size = sizeof (data);
- GDBusMessage *message = NULL;
- GError *local_error = NULL;
-
- message = g_dbus_message_new_from_blob ((guchar *) data, size,
- G_DBUS_CAPABILITY_FLAGS_NONE,
- &local_error);
- g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
- g_assert_null (message);
-
- g_clear_error (&local_error);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-/* Test that an invalid header in a D-Bus message (specifically, containing a
- * variant with a type signature containing multiple complete types) is
- * gracefully handled with an error rather than a crash. The set of bytes here
- * come directly from fuzzer output. */
-static void
-test_message_parse_multiple_signature_header (void)
-{
- const guint8 data[] = {
- 'l', /* little-endian byte order */
- 0x20, /* message type */
- 0x20, /* message flags */
- 0x01, /* major protocol version */
- 0x20, 0x20, 0x20, 0x00, /* body length (invalid) */
- 0x20, 0x20, 0x20, 0x20, /* message serial */
- /* a{yv} of header fields:
- * (things start to be even more invalid below here) */
- 0x20, 0x20, 0x20, 0x00, /* array length (in bytes) */
- 0x20, /* array key */
- /* Variant array value: */
- 0x02, /* signature length */
- 'b', 'b', /* two complete types */
- 0x00, /* nul terminator */
- /* (Variant array value payload missing) */
- /* (message body length missing) */
- };
- gsize size = sizeof (data);
- GDBusMessage *message = NULL;
- GError *local_error = NULL;
-
- message = g_dbus_message_new_from_blob ((guchar *) data, size,
- G_DBUS_CAPABILITY_FLAGS_NONE,
- &local_error);
- g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
- g_assert_null (message);
-
- g_clear_error (&local_error);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
int
main (int argc,
char *argv[])
@@ -1221,12 +1099,6 @@ main (int argc,
message_parse_empty_arrays_of_arrays);
g_test_add_func ("/gdbus/message-serialize/double-array", test_double_array);
- g_test_add_func ("/gdbus/message-parse/non-signature-header",
- test_message_parse_non_signature_header);
- g_test_add_func ("/gdbus/message-parse/empty-signature-header",
- test_message_parse_empty_signature_header);
- g_test_add_func ("/gdbus/message-parse/multiple-signature-header",
- test_message_parse_multiple_signature_header);
return g_test_run();
}
diff --git a/gio/tests/gengiotypefuncs.py b/gio/tests/gengiotypefuncs.py
index 9732d7892..47219f357 100644
--- a/gio/tests/gengiotypefuncs.py
+++ b/gio/tests/gengiotypefuncs.py
@@ -19,11 +19,11 @@ if debug: print (len(in_files), 'input files')
for filename in in_files:
if debug: print ('Input file: ', filename)
- with open(filename, "r") as f:
+ with open(filename, 'rb') as f:
for line in f:
- line = line.rstrip('\n').rstrip('\r')
+ line = line.rstrip(b'\n').rstrip(b'\r')
# print line
- match = re.search(r'\bg_[a-zA-Z0-9_]*_get_type\b', line)
+ match = re.search(b'\bg_[a-zA-Z0-9_]*_get_type\b', line)
if match:
func = match.group(0)
if not func in funcs:
diff --git a/gio/tests/glistmodel.c b/gio/tests/glistmodel.c
index 898b62886..dcf571f29 100644
--- a/gio/tests/glistmodel.c
+++ b/gio/tests/glistmodel.c
@@ -216,13 +216,550 @@ test_store_sorted (void)
g_object_unref (store);
}
+/* Test that using splice() to replace the middle element in a list store works. */
+static void
+test_store_splice_replace_middle (void)
+{
+ GListStore *store;
+ GListModel *model;
+ GAction *item;
+ GPtrArray *array;
+
+ g_test_bug ("795307");
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ model = G_LIST_MODEL (store);
+
+ array = g_ptr_array_new_full (0, g_object_unref);
+ g_ptr_array_add (array, g_simple_action_new ("1", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("2", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("3", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("4", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("5", NULL));
+
+ /* Add three items through splice */
+ g_list_store_splice (store, 0, 0, array->pdata, 3);
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 3);
+
+ item = g_list_model_get_item (model, 0);
+ g_assert_cmpstr (g_action_get_name (item), ==, "1");
+ g_object_unref (item);
+ item = g_list_model_get_item (model, 1);
+ g_assert_cmpstr (g_action_get_name (item), ==, "2");
+ g_object_unref (item);
+ item = g_list_model_get_item (model, 2);
+ g_assert_cmpstr (g_action_get_name (item), ==, "3");
+ g_object_unref (item);
+
+ /* Replace the middle one with two new items */
+ g_list_store_splice (store, 1, 1, array->pdata + 3, 2);
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 4);
+
+ item = g_list_model_get_item (model, 0);
+ g_assert_cmpstr (g_action_get_name (item), ==, "1");
+ g_object_unref (item);
+ item = g_list_model_get_item (model, 1);
+ g_assert_cmpstr (g_action_get_name (item), ==, "4");
+ g_object_unref (item);
+ item = g_list_model_get_item (model, 2);
+ g_assert_cmpstr (g_action_get_name (item), ==, "5");
+ g_object_unref (item);
+ item = g_list_model_get_item (model, 3);
+ g_assert_cmpstr (g_action_get_name (item), ==, "3");
+ g_object_unref (item);
+
+ g_ptr_array_unref (array);
+ g_object_unref (store);
+}
+
+/* Test that using splice() to replace the whole list store works. */
+static void
+test_store_splice_replace_all (void)
+{
+ GListStore *store;
+ GListModel *model;
+ GPtrArray *array;
+ GAction *item;
+
+ g_test_bug ("795307");
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ model = G_LIST_MODEL (store);
+
+ array = g_ptr_array_new_full (0, g_object_unref);
+ g_ptr_array_add (array, g_simple_action_new ("1", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("2", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("3", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("4", NULL));
+
+ /* Add the first two */
+ g_list_store_splice (store, 0, 0, array->pdata, 2);
+
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 2);
+ item = g_list_model_get_item (model, 0);
+ g_assert_cmpstr (g_action_get_name (item), ==, "1");
+ g_object_unref (item);
+ item = g_list_model_get_item (model, 1);
+ g_assert_cmpstr (g_action_get_name (item), ==, "2");
+ g_object_unref (item);
+
+ /* Replace all with the last two */
+ g_list_store_splice (store, 0, 2, array->pdata + 2, 2);
+
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 2);
+ item = g_list_model_get_item (model, 0);
+ g_assert_cmpstr (g_action_get_name (item), ==, "3");
+ g_object_unref (item);
+ item = g_list_model_get_item (model, 1);
+ g_assert_cmpstr (g_action_get_name (item), ==, "4");
+ g_object_unref (item);
+
+ g_ptr_array_unref (array);
+ g_object_unref (store);
+}
+
+/* Test that using splice() without removing or adding anything works */
+static void
+test_store_splice_noop (void)
+{
+ GListStore *store;
+ GListModel *model;
+ GAction *item;
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ model = G_LIST_MODEL (store);
+
+ /* splice noop with an empty list */
+ g_list_store_splice (store, 0, 0, NULL, 0);
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 0);
+
+ /* splice noop with a non-empty list */
+ item = G_ACTION (g_simple_action_new ("1", NULL));
+ g_list_store_append (store, item);
+ g_object_unref (item);
+
+ g_list_store_splice (store, 0, 0, NULL, 0);
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 1);
+
+ g_list_store_splice (store, 1, 0, NULL, 0);
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 1);
+
+ item = g_list_model_get_item (model, 0);
+ g_assert_cmpstr (g_action_get_name (item), ==, "1");
+ g_object_unref (item);
+
+ g_object_unref (store);
+}
+
+static gboolean
+model_array_equal (GListModel *model, GPtrArray *array)
+{
+ guint i;
+
+ if (g_list_model_get_n_items (model) != array->len)
+ return FALSE;
+
+ for (i = 0; i < array->len; i++)
+ {
+ GObject *ptr;
+ gboolean ptrs_equal;
+
+ ptr = g_list_model_get_item (model, i);
+ ptrs_equal = (g_ptr_array_index (array, i) == ptr);
+ g_object_unref (ptr);
+ if (!ptrs_equal)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Test that using splice() to remove multiple items at different
+ * positions works */
+static void
+test_store_splice_remove_multiple (void)
+{
+ GListStore *store;
+ GListModel *model;
+ GPtrArray *array;
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ model = G_LIST_MODEL (store);
+
+ array = g_ptr_array_new_full (0, g_object_unref);
+ g_ptr_array_add (array, g_simple_action_new ("1", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("2", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("3", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("4", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("5", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("6", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("7", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("8", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("9", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("10", NULL));
+
+ /* Add all */
+ g_list_store_splice (store, 0, 0, array->pdata, array->len);
+ g_assert_true (model_array_equal (model, array));
+
+ /* Remove the first two */
+ g_list_store_splice (store, 0, 2, NULL, 0);
+ g_assert_false (model_array_equal (model, array));
+ g_ptr_array_remove_range (array, 0, 2);
+ g_assert_true (model_array_equal (model, array));
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 8);
+
+ /* Remove two in the middle */
+ g_list_store_splice (store, 2, 2, NULL, 0);
+ g_assert_false (model_array_equal (model, array));
+ g_ptr_array_remove_range (array, 2, 2);
+ g_assert_true (model_array_equal (model, array));
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 6);
+
+ /* Remove two at the end */
+ g_list_store_splice (store, 4, 2, NULL, 0);
+ g_assert_false (model_array_equal (model, array));
+ g_ptr_array_remove_range (array, 4, 2);
+ g_assert_true (model_array_equal (model, array));
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 4);
+
+ g_ptr_array_unref (array);
+ g_object_unref (store);
+}
+
+/* Test that using splice() to add multiple items at different
+ * positions works */
+static void
+test_store_splice_add_multiple (void)
+{
+ GListStore *store;
+ GListModel *model;
+ GPtrArray *array;
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ model = G_LIST_MODEL (store);
+
+ array = g_ptr_array_new_full (0, g_object_unref);
+ g_ptr_array_add (array, g_simple_action_new ("1", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("2", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("3", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("4", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("5", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("6", NULL));
+
+ /* Add two at the beginning */
+ g_list_store_splice (store, 0, 0, array->pdata, 2);
+
+ /* Add two at the end */
+ g_list_store_splice (store, 2, 0, array->pdata + 4, 2);
+
+ /* Add two in the middle */
+ g_list_store_splice (store, 2, 0, array->pdata + 2, 2);
+
+ g_assert_true (model_array_equal (model, array));
+
+ g_ptr_array_unref (array);
+ g_object_unref (store);
+}
+
+/* Test that get_item_type() returns the right type */
+static void
+test_store_item_type (void)
+{
+ GListStore *store;
+ GType gtype;
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ gtype = g_list_model_get_item_type (G_LIST_MODEL (store));
+ g_assert (gtype == G_TYPE_SIMPLE_ACTION);
+
+ g_object_unref (store);
+}
+
+/* Test that remove_all() removes all items */
+static void
+test_store_remove_all (void)
+{
+ GListStore *store;
+ GListModel *model;
+ GSimpleAction *item;
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ model = G_LIST_MODEL (store);
+
+ /* Test with an empty list */
+ g_list_store_remove_all (store);
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 0);
+
+ /* Test with a non-empty list */
+ item = g_simple_action_new ("42", NULL);
+ g_list_store_append (store, item);
+ g_list_store_append (store, item);
+ g_object_unref (item);
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 2);
+ g_list_store_remove_all (store);
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 0);
+
+ g_object_unref (store);
+}
+
+/* Test that splice() logs an error when passed the wrong item type */
+static void
+test_store_splice_wrong_type (void)
+{
+ GListStore *store;
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+
+ g_test_expect_message (G_LOG_DOMAIN,
+ G_LOG_LEVEL_CRITICAL,
+ "*GListStore instead of a GSimpleAction*");
+ g_list_store_splice (store, 0, 0, (gpointer)&store, 1);
+
+ g_object_unref (store);
+}
+
+static gint
+ptr_array_cmp_action_by_name (GAction **a, GAction **b)
+{
+ return g_strcmp0 (g_action_get_name (*a), g_action_get_name (*b));
+}
+
+static gint
+list_model_cmp_action_by_name (GAction *a, GAction *b, gpointer user_data)
+{
+ return g_strcmp0 (g_action_get_name (a), g_action_get_name (b));
+}
+
+/* Test if sort() works */
+static void
+test_store_sort (void)
+{
+ GListStore *store;
+ GListModel *model;
+ GPtrArray *array;
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ model = G_LIST_MODEL (store);
+
+ array = g_ptr_array_new_full (0, g_object_unref);
+ g_ptr_array_add (array, g_simple_action_new ("2", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("3", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("9", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("4", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("5", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("8", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("6", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("7", NULL));
+ g_ptr_array_add (array, g_simple_action_new ("1", NULL));
+
+ /* Sort an empty list */
+ g_list_store_sort (store, (GCompareDataFunc)list_model_cmp_action_by_name, NULL);
+
+ /* Add all */
+ g_list_store_splice (store, 0, 0, array->pdata, array->len);
+ g_assert_true (model_array_equal (model, array));
+
+ /* Sort both and check if the result is the same */
+ g_ptr_array_sort (array, (GCompareFunc)ptr_array_cmp_action_by_name);
+ g_assert_false (model_array_equal (model, array));
+ g_list_store_sort (store, (GCompareDataFunc)list_model_cmp_action_by_name, NULL);
+ g_assert_true (model_array_equal (model, array));
+
+ g_ptr_array_unref (array);
+ g_object_unref (store);
+}
+
+/* Test the cases where the item store tries to speed up item access by caching
+ * the last iter/position */
+static void
+test_store_get_item_cache (void)
+{
+ GListStore *store;
+ GListModel *model;
+ GSimpleAction *item1, *item2, *temp;
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ model = G_LIST_MODEL (store);
+
+ /* Add two */
+ item1 = g_simple_action_new ("1", NULL);
+ g_list_store_append (store, item1);
+ item2 = g_simple_action_new ("2", NULL);
+ g_list_store_append (store, item2);
+
+ /* Clear the cache */
+ g_assert_null (g_list_model_get_item (model, 42));
+
+ /* Access the same position twice */
+ temp = g_list_model_get_item (model, 1);
+ g_assert (temp == item2);
+ g_object_unref (temp);
+ temp = g_list_model_get_item (model, 1);
+ g_assert (temp == item2);
+ g_object_unref (temp);
+
+ g_assert_null (g_list_model_get_item (model, 42));
+
+ /* Access forwards */
+ temp = g_list_model_get_item (model, 0);
+ g_assert (temp == item1);
+ g_object_unref (temp);
+ temp = g_list_model_get_item (model, 1);
+ g_assert (temp == item2);
+ g_object_unref (temp);
+
+ g_assert_null (g_list_model_get_item (model, 42));
+
+ /* Access backwards */
+ temp = g_list_model_get_item (model, 1);
+ g_assert (temp == item2);
+ g_object_unref (temp);
+ temp = g_list_model_get_item (model, 0);
+ g_assert (temp == item1);
+ g_object_unref (temp);
+
+ g_object_unref (item1);
+ g_object_unref (item2);
+ g_object_unref (store);
+}
+
+struct ItemsChangedData
+{
+ guint position;
+ guint removed;
+ guint added;
+ gboolean called;
+};
+
+static void
+expect_items_changed (struct ItemsChangedData *expected,
+ guint position,
+ guint removed,
+ guint added)
+{
+ expected->position = position;
+ expected->removed = removed;
+ expected->added = added;
+ expected->called = FALSE;
+}
+
+static void
+on_items_changed (GListModel *model,
+ guint position,
+ guint removed,
+ guint added,
+ struct ItemsChangedData *expected)
+{
+ g_assert_false (expected->called);
+ g_assert_cmpuint (expected->position, ==, position);
+ g_assert_cmpuint (expected->removed, ==, removed);
+ g_assert_cmpuint (expected->added, ==, added);
+ expected->called = TRUE;
+}
+
+/* Test that all operations on the list emit the items-changed signal */
+static void
+test_store_signal_items_changed (void)
+{
+ GListStore *store;
+ GListModel *model;
+ GSimpleAction *item;
+ struct ItemsChangedData expected = {0};
+
+ store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
+ model = G_LIST_MODEL (store);
+
+ g_object_connect (model, "signal::items-changed",
+ on_items_changed, &expected, NULL);
+
+ /* Emit the signal manually */
+ expect_items_changed (&expected, 0, 0, 0);
+ g_list_model_items_changed (model, 0, 0, 0);
+ g_assert_true (expected.called);
+
+ /* Append an item */
+ expect_items_changed (&expected, 0, 0, 1);
+ item = g_simple_action_new ("2", NULL);
+ g_list_store_append (store, item);
+ g_object_unref (item);
+ g_assert_true (expected.called);
+
+ /* Insert an item */
+ expect_items_changed (&expected, 1, 0, 1);
+ item = g_simple_action_new ("1", NULL);
+ g_list_store_insert (store, 1, item);
+ g_object_unref (item);
+ g_assert_true (expected.called);
+
+ /* Sort the list */
+ expect_items_changed (&expected, 0, 2, 2);
+ g_list_store_sort (store,
+ (GCompareDataFunc)list_model_cmp_action_by_name,
+ NULL);
+ g_assert_true (expected.called);
+
+ /* Insert sorted */
+ expect_items_changed (&expected, 2, 0, 1);
+ item = g_simple_action_new ("3", NULL);
+ g_list_store_insert_sorted (store,
+ item,
+ (GCompareDataFunc)list_model_cmp_action_by_name,
+ NULL);
+ g_object_unref (item);
+ g_assert_true (expected.called);
+
+ /* Remove an item */
+ expect_items_changed (&expected, 1, 1, 0);
+ g_list_store_remove (store, 1);
+ g_assert_true (expected.called);
+
+ /* Splice */
+ expect_items_changed (&expected, 0, 2, 1);
+ item = g_simple_action_new ("4", NULL);
+ g_assert_cmpuint (g_list_model_get_n_items (model), >=, 2);
+ g_list_store_splice (store, 0, 2, (gpointer)&item, 1);
+ g_object_unref (item);
+ g_assert_true (expected.called);
+
+ /* Remove all */
+ expect_items_changed (&expected, 0, 1, 0);
+ g_assert_cmpuint (g_list_model_get_n_items (model), ==, 1);
+ g_list_store_remove_all (store);
+ g_assert_true (expected.called);
+
+ g_object_unref (store);
+}
+
int main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("https://bugzilla.gnome.org/");
g_test_add_func ("/glistmodel/store/boundaries", test_store_boundaries);
g_test_add_func ("/glistmodel/store/refcounts", test_store_refcounts);
g_test_add_func ("/glistmodel/store/sorted", test_store_sorted);
+ g_test_add_func ("/glistmodel/store/splice-replace-middle",
+ test_store_splice_replace_middle);
+ g_test_add_func ("/glistmodel/store/splice-replace-all",
+ test_store_splice_replace_all);
+ g_test_add_func ("/glistmodel/store/splice-noop", test_store_splice_noop);
+ g_test_add_func ("/glistmodel/store/splice-remove-multiple",
+ test_store_splice_remove_multiple);
+ g_test_add_func ("/glistmodel/store/splice-add-multiple",
+ test_store_splice_add_multiple);
+ g_test_add_func ("/glistmodel/store/splice-wrong-type",
+ test_store_splice_wrong_type);
+ g_test_add_func ("/glistmodel/store/item-type",
+ test_store_item_type);
+ g_test_add_func ("/glistmodel/store/remove-all",
+ test_store_remove_all);
+ g_test_add_func ("/glistmodel/store/sort",
+ test_store_sort);
+ g_test_add_func ("/glistmodel/store/get-item-cache",
+ test_store_get_item_cache);
+ g_test_add_func ("/glistmodel/store/items-changed",
+ test_store_signal_items_changed);
return g_test_run ();
}
diff --git a/gio/tests/gschema-compile.c b/gio/tests/gschema-compile.c
index 65f656c52..81ded83fa 100644
--- a/gio/tests/gschema-compile.c
+++ b/gio/tests/gschema-compile.c
@@ -22,17 +22,17 @@ test_schema_do_compile (gpointer data)
SchemaTest *test = (SchemaTest *) data;
gchar *filename = g_strconcat (test->name, ".gschema.xml", NULL);
gchar *path = g_test_build_filename (G_TEST_DIST, "schema-tests", filename, NULL);
- gchar *argv[] = {
+ const gchar *argv[] = {
GLIB_COMPILE_SCHEMAS,
"--strict",
"--dry-run",
"--schema-file", path,
- (gchar *)test->opt,
+ test->opt,
NULL
};
gchar *envp[] = { NULL };
- execve (argv[0], argv, envp);
+ execve (argv[0], (char **) argv, envp);
g_assert_not_reached ();
}
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
index 2be4122fe..2f056ee95 100644
--- a/gio/tests/gsettings.c
+++ b/gio/tests/gsettings.c
@@ -1324,6 +1324,33 @@ test_simple_binding (void)
g_object_get (obj, "flags", &i, NULL);
g_assert_cmpint (i, ==, TEST_FLAGS_MOURNING | TEST_FLAGS_WALKING);
+ g_settings_bind (settings, "uint", obj, "uint", G_SETTINGS_BIND_DEFAULT);
+
+ g_object_set (obj, "uint", 12345, NULL);
+ g_assert_cmpuint (g_settings_get_uint (settings, "uint"), ==, 12345);
+
+ g_settings_set_uint (settings, "uint", 54321);
+ u = 1111;
+ g_object_get (obj, "uint", &u, NULL);
+ g_assert_cmpuint (u, ==, 54321);
+
+ g_settings_bind (settings, "range", obj, "uint", G_SETTINGS_BIND_DEFAULT);
+ g_object_set (obj, "uint", 22, NULL);
+ u = 1111;
+ g_assert_cmpuint (g_settings_get_uint (settings, "range"), ==, 22);
+ g_object_get (obj, "uint", &u, NULL);
+ g_assert_cmpuint (u, ==, 22);
+
+ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+ "* is out of schema-specified range for*");
+ g_object_set (obj, "uint", 45, NULL);
+ g_test_assert_expected_messages ();
+ u = 1111;
+ g_object_get (obj, "uint", &u, NULL);
+ g_assert_cmpuint (g_settings_get_uint (settings, "range"), ==, 22);
+ /* The value of the object is currently not reset back to its initial value
+ g_assert_cmpuint (u, ==, 22); */
+
g_object_unref (obj);
g_object_unref (settings);
}
@@ -1472,6 +1499,14 @@ bool_to_string (const GValue *value,
return g_variant_new_string ("false");
}
+static GVariant *
+bool_to_bool (const GValue *value,
+ const GVariantType *expected_type,
+ gpointer user_data)
+{
+ return g_variant_new_boolean (g_value_get_boolean (value));
+}
+
/* Test custom bindings.
* Translate strings to booleans and back
*/
@@ -1508,6 +1543,17 @@ test_custom_binding (void)
g_assert_cmpstr (s, ==, "true");
g_free (s);
+ g_settings_bind_with_mapping (settings, "string",
+ obj, "bool",
+ G_SETTINGS_BIND_DEFAULT,
+ string_to_bool, bool_to_bool,
+ NULL, NULL);
+ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+ "*binding mapping function for key 'string' returned"
+ " GVariant of type 'b' when type 's' was requested*");
+ g_object_set (obj, "bool", FALSE, NULL);
+ g_test_assert_expected_messages ();
+
g_object_unref (obj);
g_object_unref (settings);
}
diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c
index f617bc599..ac7051d6d 100644
--- a/gio/tests/gsubprocess.c
+++ b/gio/tests/gsubprocess.c
@@ -849,167 +849,6 @@ test_communicate (gconstpointer test_data)
g_object_unref (proc);
}
-typedef struct {
- GSubprocess *proc;
- GCancellable *cancellable;
- gboolean is_utf8;
- gboolean running;
- GError *error;
-} TestCancelledCommunicateData;
-
-static gboolean
-on_test_communicate_cancelled_idle (gpointer user_data)
-{
- TestCancelledCommunicateData *data = user_data;
- GBytes *input;
- const gchar *hellostring;
- GBytes *stdout_bytes = NULL, *stderr_bytes = NULL;
- gchar *stdout_buf = NULL, *stderr_buf = NULL;
-
- /* Include a leading hash and trailing newline so that if this gets onto the
- * test’s stdout, it doesn’t mess up TAP output. */
- hellostring = "# hello world\n";
- input = g_bytes_new_static (hellostring, strlen (hellostring));
-
- if (data->is_utf8)
- g_subprocess_communicate_utf8 (data->proc, hellostring, data->cancellable,
- &stdout_buf, &stderr_buf, &data->error);
- else
- g_subprocess_communicate (data->proc, input, data->cancellable, &stdout_bytes,
- &stderr_bytes, &data->error);
-
- data->running = FALSE;
-
- if (data->is_utf8)
- {
- g_assert_null (stdout_buf);
- g_assert_null (stderr_buf);
- }
- else
- {
- g_assert_null (stdout_bytes);
- g_assert_null (stderr_bytes);
- }
-
- g_bytes_unref (input);
-
- return G_SOURCE_REMOVE;
-}
-
-/* Test g_subprocess_communicate() can be cancelled correctly */
-static void
-test_communicate_cancelled (gconstpointer test_data)
-{
- GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
- GPtrArray *args;
- GSubprocess *proc;
- GCancellable *cancellable = NULL;
- GError *error = NULL;
- TestCancelledCommunicateData data = { 0 };
-
- args = get_test_subprocess_args ("cat", NULL);
- proc = g_subprocess_newv ((const gchar* const*)args->pdata,
- G_SUBPROCESS_FLAGS_STDIN_PIPE | flags,
- &error);
- g_assert_no_error (error);
- g_ptr_array_free (args, TRUE);
-
- cancellable = g_cancellable_new ();
-
- data.proc = proc;
- data.cancellable = cancellable;
- data.error = error;
-
- g_cancellable_cancel (cancellable);
- g_idle_add (on_test_communicate_cancelled_idle, &data);
-
- data.running = TRUE;
- while (data.running)
- g_main_context_iteration (NULL, TRUE);
-
- g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
- g_clear_error (&data.error);
-
- g_object_unref (cancellable);
- g_object_unref (proc);
-}
-
-static void
-on_communicate_cancelled_complete (GObject *proc,
- GAsyncResult *result,
- gpointer user_data)
-{
- TestAsyncCommunicateData *data = user_data;
- GBytes *stdout_bytes = NULL, *stderr_bytes = NULL;
- char *stdout_str = NULL, *stderr_str = NULL;
-
- data->running = FALSE;
- if (data->is_utf8)
- (void) g_subprocess_communicate_utf8_finish ((GSubprocess*)proc, result,
- &stdout_str, &stderr_str, &data->error);
- else
- (void) g_subprocess_communicate_finish ((GSubprocess*)proc, result,
- &stdout_bytes, &stderr_bytes, &data->error);
-
- if (data->is_utf8)
- {
- g_assert_null (stdout_str);
- g_assert_null (stderr_str);
- }
- else
- {
- g_assert_null (stdout_bytes);
- g_assert_null (stderr_bytes);
- }
-}
-
-/* Test g_subprocess_communicate_async() can be cancelled correctly,
- * as passed in via @test_data. */
-static void
-test_communicate_cancelled_async (gconstpointer test_data)
-{
- GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
- GError *error = NULL;
- GPtrArray *args;
- TestAsyncCommunicateData data = { 0 };
- GSubprocess *proc;
- GCancellable *cancellable = NULL;
- GBytes *input;
- const char *hellostring;
-
- args = get_test_subprocess_args ("cat", NULL);
- proc = g_subprocess_newv ((const gchar* const*)args->pdata,
- G_SUBPROCESS_FLAGS_STDIN_PIPE | flags,
- &error);
- g_assert_no_error (error);
- g_ptr_array_free (args, TRUE);
-
- /* Include a leading hash and trailing newline so that if this gets onto the
- * test’s stdout, it doesn’t mess up TAP output. */
- hellostring = "# hello world\n";
- input = g_bytes_new_static (hellostring, strlen (hellostring));
-
- cancellable = g_cancellable_new ();
-
- g_subprocess_communicate_async (proc, input,
- cancellable,
- on_communicate_cancelled_complete,
- &data);
-
- g_cancellable_cancel (cancellable);
-
- data.running = TRUE;
- while (data.running)
- g_main_context_iteration (NULL, TRUE);
-
- g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
- g_clear_error (&data.error);
-
- g_bytes_unref (input);
- g_object_unref (cancellable);
- g_object_unref (proc);
-}
-
/* Test g_subprocess_communicate_utf8_async() works correctly with a variety of
* flags, as passed in via @test_data. */
static void
@@ -1044,44 +883,6 @@ test_communicate_utf8_async (gconstpointer test_data)
g_object_unref (proc);
}
-/* Test g_subprocess_communicate_utf8_async() can be cancelled correclty. */
-static void
-test_communicate_utf8_cancelled_async (gconstpointer test_data)
-{
- GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
- GError *error = NULL;
- GPtrArray *args;
- TestAsyncCommunicateData data = { flags, 0, };
- GSubprocess *proc;
- GCancellable *cancellable = NULL;
-
- args = get_test_subprocess_args ("cat", NULL);
- proc = g_subprocess_newv ((const gchar* const*)args->pdata,
- G_SUBPROCESS_FLAGS_STDIN_PIPE | flags,
- &error);
- g_assert_no_error (error);
- g_ptr_array_free (args, TRUE);
-
- cancellable = g_cancellable_new ();
- data.is_utf8 = TRUE;
- g_subprocess_communicate_utf8_async (proc, "# hello world\n",
- cancellable,
- on_communicate_cancelled_complete,
- &data);
-
- g_cancellable_cancel (cancellable);
-
- data.running = TRUE;
- while (data.running)
- g_main_context_iteration (NULL, TRUE);
-
- g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
- g_clear_error (&data.error);
-
- g_object_unref (cancellable);
- g_object_unref (proc);
-}
-
/* Test g_subprocess_communicate_utf8() works correctly with a variety of flags,
* as passed in via @test_data. */
static void
@@ -1122,45 +923,6 @@ test_communicate_utf8 (gconstpointer test_data)
g_object_unref (proc);
}
-/* Test g_subprocess_communicate_utf8() can be cancelled correctly */
-static void
-test_communicate_utf8_cancelled (gconstpointer test_data)
-{
- GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
- GPtrArray *args;
- GSubprocess *proc;
- GCancellable *cancellable = NULL;
- GError *error = NULL;
- TestCancelledCommunicateData data = { 0 };
-
- args = get_test_subprocess_args ("cat", NULL);
- proc = g_subprocess_newv ((const gchar* const*)args->pdata,
- G_SUBPROCESS_FLAGS_STDIN_PIPE | flags,
- &error);
- g_assert_no_error (error);
- g_ptr_array_free (args, TRUE);
-
- cancellable = g_cancellable_new ();
-
- data.proc = proc;
- data.cancellable = cancellable;
- data.error = error;
-
- g_cancellable_cancel (cancellable);
- g_idle_add (on_test_communicate_cancelled_idle, &data);
-
- data.is_utf8 = TRUE;
- data.running = TRUE;
- while (data.running)
- g_main_context_iteration (NULL, TRUE);
-
- g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
- g_clear_error (&data.error);
-
- g_object_unref (cancellable);
- g_object_unref (proc);
-}
-
static void
test_communicate_nothing (void)
{
@@ -1747,40 +1509,20 @@ main (int argc, char **argv)
test_communicate);
g_free (test_path);
- test_path = g_strdup_printf ("/gsubprocess/communicate/cancelled%s", flags_vectors[i].subtest);
- g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
- test_communicate_cancelled);
- g_free (test_path);
-
test_path = g_strdup_printf ("/gsubprocess/communicate/async%s", flags_vectors[i].subtest);
g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
test_communicate_async);
g_free (test_path);
- test_path = g_strdup_printf ("/gsubprocess/communicate/async/cancelled%s", flags_vectors[i].subtest);
- g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
- test_communicate_cancelled_async);
- g_free (test_path);
-
test_path = g_strdup_printf ("/gsubprocess/communicate/utf8%s", flags_vectors[i].subtest);
g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
test_communicate_utf8);
g_free (test_path);
- test_path = g_strdup_printf ("/gsubprocess/communicate/utf8/cancelled%s", flags_vectors[i].subtest);
- g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
- test_communicate_utf8_cancelled);
- g_free (test_path);
-
test_path = g_strdup_printf ("/gsubprocess/communicate/utf8/async%s", flags_vectors[i].subtest);
g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
test_communicate_utf8_async);
g_free (test_path);
-
- test_path = g_strdup_printf ("/gsubprocess/communicate/utf8/async/cancelled%s", flags_vectors[i].subtest);
- g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
- test_communicate_utf8_cancelled_async);
- g_free (test_path);
}
g_test_add_func ("/gsubprocess/communicate/utf8/invalid", test_communicate_utf8_invalid);
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index fb4ffcf7d..96229bd8b 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -3,7 +3,6 @@ common_gio_tests_deps = [
libgmodule_dep,
libgobject_dep,
libgio_dep,
- libintl
]
subdir('gdbus-object-manager-example')
@@ -296,7 +295,7 @@ foreach test_name : gio_tests
install : false,
c_args : test_c_args,
dependencies : common_gio_tests_deps + extra_deps)
- if test_name == 'testfilemonitor' or test_name == 'network-monitor-race'
+ if test_name == 'testfilemonitor'
test(test_name, exe, env : test_env, timeout : 45)
else
test(test_name, exe, env : test_env)
diff --git a/gio/tests/network-address.c b/gio/tests/network-address.c
index da1b92413..1a7f8e797 100644
--- a/gio/tests/network-address.c
+++ b/gio/tests/network-address.c
@@ -149,6 +149,8 @@ test_resolve_address (gconstpointer d)
GSocketAddress *addr;
GError *error = NULL;
+ g_test_message ("Input: %s", test->input);
+
g_assert_cmpint (test->valid_ip, ==, g_hostname_is_ip_address (test->input));
connectable = g_network_address_parse (test->input, 1234, &error);
@@ -187,6 +189,8 @@ test_resolve_address_gresolver (gconstpointer d)
GInetAddress *iaddr;
GError *error = NULL;
+ g_test_message ("Input: %s", test->input);
+
resolver = g_resolver_get_default ();
addrs = g_resolver_lookup_by_name (resolver, test->input, NULL, &error);
g_object_unref (resolver);
@@ -204,6 +208,8 @@ test_resolve_address_gresolver (gconstpointer d)
}
else
{
+ g_assert_nonnull (error);
+ g_test_message ("Error: %s", error->message);
g_assert_false (test->valid_resolve);
if (!test->valid_parse)
diff --git a/gio/tests/network-monitor-race.c b/gio/tests/network-monitor-race.c
index 4b92c87a5..cadd62cee 100644
--- a/gio/tests/network-monitor-race.c
+++ b/gio/tests/network-monitor-race.c
@@ -18,7 +18,7 @@
#include <glib/glib.h>
#include <gio/gio.h>
-#define MAX_RUNS 333
+#define MAX_RUNS 20
static gboolean
quit_loop (gpointer user_data)
diff --git a/gio/tests/org.gtk.test.gschema.xml.orig b/gio/tests/org.gtk.test.gschema.xml.orig
index c07558335..3c9d7b779 100644
--- a/gio/tests/org.gtk.test.gschema.xml.orig
+++ b/gio/tests/org.gtk.test.gschema.xml.orig
@@ -131,6 +131,10 @@
<key name="flags" flags="org.gtk.test.TestFlags">
<default>['mourning', 'laughing']</default>
</key>
+ <key name="range" type='u'>
+ <default>33</default>
+ <range min="2" max="44"/>
+ </key>
</schema>
<schema id='org.gtk.test.enums' path='/tests/enums/'>
diff --git a/gio/tests/pollable.c b/gio/tests/pollable.c
index c61525d09..826eaecad 100644
--- a/gio/tests/pollable.c
+++ b/gio/tests/pollable.c
@@ -61,7 +61,7 @@ check_source_readability_callback (gpointer user_data)
static gboolean
write_callback (gpointer user_data)
{
- char *buf = "x";
+ const char *buf = "x";
gssize nwrote;
GError *error = NULL;
diff --git a/gio/tests/send-data.c b/gio/tests/send-data.c
index a30bdca56..514442976 100644
--- a/gio/tests/send-data.c
+++ b/gio/tests/send-data.c
@@ -170,7 +170,7 @@ main (int argc, char *argv[])
if (!g_output_stream_write_all (out, buffer, strlen (buffer),
NULL, cancellable, &error))
{
- g_warning ("send error: %s\n", error->message);
+ g_warning ("send error: %s", error->message);
g_error_free (error);
error = NULL;
}
@@ -187,7 +187,7 @@ main (int argc, char *argv[])
res, &error))
{
g_object_unref (res);
- g_warning ("close error: %s\n", error->message);
+ g_warning ("close error: %s", error->message);
return 1;
}
g_object_unref (res);
@@ -196,7 +196,7 @@ main (int argc, char *argv[])
{
if (!g_io_stream_close (G_IO_STREAM (connection), cancellable, &error))
{
- g_warning ("close error: %s\n", error->message);
+ g_warning ("close error: %s", error->message);
return 1;
}
}
diff --git a/gio/tests/simple-proxy.c b/gio/tests/simple-proxy.c
index 00bdb2ea4..f1eb6af9b 100644
--- a/gio/tests/simple-proxy.c
+++ b/gio/tests/simple-proxy.c
@@ -32,7 +32,7 @@ static void
test_uris (void)
{
GProxyResolver *resolver;
- gchar *ignore_hosts[2] = { "127.0.0.1", NULL };
+ const gchar *ignore_hosts[2] = { "127.0.0.1", NULL };
gchar **proxies;
GError *error = NULL;
const gchar *uri;
@@ -41,7 +41,7 @@ test_uris (void)
/* Valid URI. */
uri = "http://%E0%B4%A8%E0%B4%B2:80/";
- resolver = g_simple_proxy_resolver_new (NULL, ignore_hosts);
+ resolver = g_simple_proxy_resolver_new (NULL, (char **) ignore_hosts);
proxies = g_proxy_resolver_lookup (resolver, uri, NULL, &error);
g_assert_no_error (error);
@@ -60,7 +60,7 @@ test_uris (void)
/* Invalid URI. */
uri = "%E0%B4%A8%E0%B4%B2";
str = g_strdup_printf ("Invalid URI ‘%s’", uri);
- resolver = g_simple_proxy_resolver_new (NULL, ignore_hosts);
+ resolver = g_simple_proxy_resolver_new (NULL, (char **) ignore_hosts);
proxies = g_proxy_resolver_lookup (resolver, uri, NULL, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
@@ -81,7 +81,7 @@ test_uris (void)
g_object_unref (resolver);
g_free (str);
- resolver = g_simple_proxy_resolver_new ("default://", ignore_hosts);
+ resolver = g_simple_proxy_resolver_new ("default://", (char **) ignore_hosts);
g_simple_proxy_resolver_set_uri_proxy (G_SIMPLE_PROXY_RESOLVER (resolver),
"http", "http://proxy.example.com");
g_simple_proxy_resolver_set_uri_proxy (G_SIMPLE_PROXY_RESOLVER (resolver),
@@ -136,11 +136,11 @@ static void
test_socks (void)
{
GProxyResolver *resolver;
- gchar *ignore_hosts[2] = { "127.0.0.1", NULL };
+ const gchar *ignore_hosts[2] = { "127.0.0.1", NULL };
gchar **proxies;
GError *error = NULL;
- resolver = g_simple_proxy_resolver_new ("socks://proxy.example.com", ignore_hosts);
+ resolver = g_simple_proxy_resolver_new ("socks://proxy.example.com", (char **) ignore_hosts);
proxies = g_proxy_resolver_lookup (resolver, "http://one.example.com/",
NULL, &error);
@@ -160,7 +160,7 @@ test_socks (void)
g_object_unref (resolver);
- resolver = g_simple_proxy_resolver_new ("default-proxy://", ignore_hosts);
+ resolver = g_simple_proxy_resolver_new ("default-proxy://", (char **) ignore_hosts);
g_simple_proxy_resolver_set_uri_proxy (G_SIMPLE_PROXY_RESOLVER (resolver),
"http", "socks://proxy.example.com");
diff --git a/gio/tests/socket-client.c b/gio/tests/socket-client.c
index 62dda8991..803f4d6e9 100644
--- a/gio/tests/socket-client.c
+++ b/gio/tests/socket-client.c
@@ -173,7 +173,7 @@ make_connection (const char *argument,
if (g_socket_connect (*socket, *address, cancellable, &err))
break;
- g_message ("Connection to %s failed: %s, trying next\n", socket_address_to_string (*address), err->message);
+ g_message ("Connection to %s failed: %s, trying next", socket_address_to_string (*address), err->message);
g_clear_error (&err);
g_object_unref (*address);
diff --git a/gio/tests/unix-mounts.c b/gio/tests/unix-mounts.c
index 67b8c8d98..3d54047dc 100644
--- a/gio/tests/unix-mounts.c
+++ b/gio/tests/unix-mounts.c
@@ -33,12 +33,6 @@ test_is_system_fs_type (void)
{
g_assert_true (g_unix_is_system_fs_type ("tmpfs"));
g_assert_false (g_unix_is_system_fs_type ("ext4"));
-
- /* Check that some common network file systems aren’t considered ‘system’. */
- g_assert_false (g_unix_is_system_fs_type ("cifs"));
- g_assert_false (g_unix_is_system_fs_type ("nfs"));
- g_assert_false (g_unix_is_system_fs_type ("nfs4"));
- g_assert_false (g_unix_is_system_fs_type ("smbfs"));
}
static void
diff --git a/gio/xdgmime/xdgmime.c b/gio/xdgmime/xdgmime.c
index 95adf7ee0..12028927d 100644
--- a/gio/xdgmime/xdgmime.c
+++ b/gio/xdgmime/xdgmime.c
@@ -60,6 +60,8 @@ XdgMimeCache **_caches = NULL;
static int n_caches = 0;
const char xdg_mime_type_unknown[] = "application/octet-stream";
+const char xdg_mime_type_empty[] = "application/x-zerosize";
+const char xdg_mime_type_textplain[] = "text/plain";
enum
@@ -463,17 +465,23 @@ xdg_mime_get_mime_type_for_data (const void *data,
{
const char *mime_type;
+ if (len == 0)
+ {
+ *result_prio = 100;
+ return XDG_MIME_TYPE_EMPTY;
+ }
+
xdg_mime_init ();
if (_caches)
- return _xdg_mime_cache_get_mime_type_for_data (data, len, result_prio);
-
- mime_type = _xdg_mime_magic_lookup_data (global_magic, data, len, result_prio, NULL, 0);
+ mime_type = _xdg_mime_cache_get_mime_type_for_data (data, len, result_prio);
+ else
+ mime_type = _xdg_mime_magic_lookup_data (global_magic, data, len, result_prio, NULL, 0);
if (mime_type)
return mime_type;
- return XDG_MIME_TYPE_UNKNOWN;
+ return _xdg_binary_or_text_fallback(data, len);
}
#ifdef NOT_USED_IN_GIO
@@ -554,7 +562,7 @@ xdg_mime_get_mime_type_for_file (const char *file_name,
if (mime_type)
return mime_type;
- return XDG_MIME_TYPE_UNKNOWN;
+ return _xdg_binary_or_text_fallback(data, bytes_read);
}
const char *
diff --git a/gio/xdgmime/xdgmime.h b/gio/xdgmime/xdgmime.h
index d30106245..cd20c77a9 100644
--- a/gio/xdgmime/xdgmime.h
+++ b/gio/xdgmime/xdgmime.h
@@ -66,6 +66,8 @@ typedef void (*XdgMimeDestroy) (void *user_data);
#define xdg_mime_register_reload_callback XDG_ENTRY(register_reload_callback)
#define xdg_mime_remove_callback XDG_ENTRY(remove_callback)
#define xdg_mime_type_unknown XDG_ENTRY(type_unknown)
+#define xdg_mime_type_empty XDG_ENTRY(type_empty)
+#define xdg_mime_type_textplain XDG_ENTRY(type_textplain)
#define xdg_mime_get_icon XDG_ENTRY(get_icon)
#define xdg_mime_get_generic_icon XDG_ENTRY(get_generic_icon)
@@ -75,7 +77,11 @@ typedef void (*XdgMimeDestroy) (void *user_data);
#endif
extern const char xdg_mime_type_unknown[];
+extern const char xdg_mime_type_empty[];
+extern const char xdg_mime_type_textplain[];
#define XDG_MIME_TYPE_UNKNOWN xdg_mime_type_unknown
+#define XDG_MIME_TYPE_EMPTY xdg_mime_type_empty
+#define XDG_MIME_TYPE_TEXTPLAIN xdg_mime_type_textplain
const char *xdg_mime_get_mime_type_for_data (const void *data,
size_t len,
diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c
index eab6119b6..8010f9e5b 100644
--- a/gio/xdgmime/xdgmimecache.c
+++ b/gio/xdgmime/xdgmimecache.c
@@ -760,12 +760,11 @@ cache_get_mime_type_for_data (const void *data,
for (n = 0; n < n_mime_types; n++)
{
-
if (mime_types[n])
return mime_types[n];
}
- return XDG_MIME_TYPE_UNKNOWN;
+ return NULL;
}
const char *
@@ -812,6 +811,9 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name,
statbuf = &buf;
}
+ if (statbuf->st_size == 0)
+ return XDG_MIME_TYPE_EMPTY;
+
if (!S_ISREG (statbuf->st_mode))
return XDG_MIME_TYPE_UNKNOWN;
@@ -841,6 +843,9 @@ _xdg_mime_cache_get_mime_type_for_file (const char *file_name,
mime_type = cache_get_mime_type_for_data (data, bytes_read, NULL,
mime_types, n);
+ if (!mime_type)
+ mime_type = _xdg_binary_or_text_fallback(data, bytes_read);
+
free (data);
fclose (file);
diff --git a/gio/xdgmime/xdgmimeint.c b/gio/xdgmime/xdgmimeint.c
index d56bb8340..35c3635e2 100644
--- a/gio/xdgmime/xdgmimeint.c
+++ b/gio/xdgmime/xdgmimeint.c
@@ -185,3 +185,18 @@ _xdg_reverse_ucs4 (xdg_unichar_t *source, int len)
}
}
+const char *
+_xdg_binary_or_text_fallback(const void *data, size_t len)
+{
+ unsigned char *chardata;
+ int i;
+
+ chardata = (unsigned char *) data;
+ for (i = 0; i < 128 && i < len; ++i)
+ {
+ if (chardata[i] < 32 && chardata[i] != 9 && chardata[i] != 10 && chardata[i] != 13)
+ return XDG_MIME_TYPE_UNKNOWN; /* binary data */
+ }
+
+ return XDG_MIME_TYPE_TEXTPLAIN;
+}
diff --git a/gio/xdgmime/xdgmimeint.h b/gio/xdgmime/xdgmimeint.h
index 8acd8d5cd..c9270139e 100644
--- a/gio/xdgmime/xdgmimeint.h
+++ b/gio/xdgmime/xdgmimeint.h
@@ -71,5 +71,6 @@ int _xdg_utf8_validate (const char *source);
xdg_unichar_t *_xdg_convert_to_ucs4 (const char *source, int *len);
void _xdg_reverse_ucs4 (xdg_unichar_t *source, int len);
const char *_xdg_get_base_name (const char *file_name);
+const char *_xdg_binary_or_text_fallback(const void *data, size_t len);
#endif /* __XDG_MIME_INT_H__ */