Merge branch 'master' into gdbus-codegen

This commit is contained in:
David Zeuthen
2011-04-29 12:01:35 -04:00
94 changed files with 5256 additions and 1774 deletions

View File

@@ -141,7 +141,9 @@ g_action_group_default_init (GActionGroupInterface *class)
g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED] =
g_signal_new (I_("action-state-changed"),
G_TYPE_ACTION_GROUP,
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
G_SIGNAL_RUN_LAST |
G_SIGNAL_DETAILED |
G_SIGNAL_MUST_COLLECT,
G_STRUCT_OFFSET (GActionGroupInterface,
action_state_changed),
NULL, NULL,

View File

@@ -27,6 +27,7 @@
#include "gapplicationcommandline.h"
#include "gapplicationimpl.h"
#include "gactiongroup.h"
#include "gsettings.h"
#include "gioenumtypes.h"
#include "gio-marshal.h"
@@ -557,7 +558,7 @@ g_application_class_init (GApplicationClass *class)
g_object_class_install_property (object_class, PROP_INACTIVITY_TIMEOUT,
g_param_spec_uint ("inactivity-timeout",
P_("Inactivity timeout"),
P_("Iime (ms) to stay alive after becoming idle"),
P_("Time (ms) to stay alive after becoming idle"),
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
@@ -1006,14 +1007,17 @@ g_application_register (GApplication *application,
if (!application->priv->is_registered)
{
application->priv->impl =
g_application_impl_register (application, application->priv->id,
application->priv->flags,
&application->priv->remote_actions,
cancellable, error);
if (~application->priv->flags & G_APPLICATION_NON_UNIQUE)
{
application->priv->impl =
g_application_impl_register (application, application->priv->id,
application->priv->flags,
&application->priv->remote_actions,
cancellable, error);
if (application->priv->impl == NULL)
return FALSE;
if (application->priv->impl == NULL)
return FALSE;
}
application->priv->is_remote = application->priv->remote_actions != NULL;
application->priv->is_registered = TRUE;
@@ -1326,6 +1330,8 @@ g_application_run (GApplication *application,
if (application->priv->impl)
g_application_impl_flush (application->priv->impl);
g_settings_sync ();
return status;
}

View File

@@ -659,6 +659,9 @@ g_application_impl_register (GApplication *application,
g_dbus_connection_unregister_object (impl->session_bus,
impl->object_id);
impl->object_id = 0;
g_dbus_connection_unregister_object (impl->session_bus,
impl->action_id);
impl->action_id = 0;
if (flags & G_APPLICATION_IS_SERVICE)
{

View File

@@ -258,25 +258,13 @@ is_valid_nonce_tcp (const gchar *address_entry,
goto out;
}
if (nonce_file == NULL)
if (host != NULL)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
_("Error in address `%s' - missing noncefile attribute"),
address_entry);
goto out;
}
if (host == NULL)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
_("Error in address `%s' - missing host attribute"),
address_entry);
goto out;
/* TODO: validate host */
}
nonce_file = nonce_file; /* To avoid -Wunused-but-set-variable */
ret= TRUE;
out:
@@ -351,14 +339,9 @@ is_valid_tcp (const gchar *address_entry,
goto out;
}
if (host == NULL)
if (host != NULL)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
_("Error in address `%s' - missing host attribute"),
address_entry);
goto out;
/* TODO: validate host */
}
ret= TRUE;

View File

@@ -663,7 +663,8 @@ _g_dbus_auth_run_client (GDBusAuth *auth,
if (line == NULL)
goto out;
debug_print ("CLIENT: WaitingForReject, read '%s'", line);
foobar:
choose_mechanism:
if (!g_str_has_prefix (line, "REJECTED "))
{
g_set_error (error,
@@ -739,7 +740,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth,
}
else if (g_str_has_prefix (line, "REJECTED "))
{
goto foobar;
goto choose_mechanism;
}
else
{
@@ -841,6 +842,13 @@ _g_dbus_auth_run_client (GDBusAuth *auth,
}
state = CLIENT_STATE_WAITING_FOR_OK;
}
else if (g_str_has_prefix (line, "REJECTED "))
{
/* could be the chosen authentication method just doesn't work. Try
* another one...
*/
goto choose_mechanism;
}
else
{
g_set_error (error,

View File

@@ -187,8 +187,7 @@ mechanism_server_initiate (GDBusAuthMechanism *mechanism,
g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism));
g_return_if_fail (!m->priv->is_server && !m->priv->is_client);
if (initial_response != NULL)
g_debug ("ANONYMOUS: initial_response was `%s'", initial_response);
//g_debug ("ANONYMOUS: initial_response was `%s'", initial_response);
m->priv->is_server = TRUE;
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;

View File

@@ -652,6 +652,7 @@ keyring_generate_entry (const gchar *cookie_context,
lines = NULL;
new_contents = NULL;
have_id = FALSE;
use_id = 0;
use_cookie = NULL;
lock_fd = -1;

View File

@@ -1992,7 +1992,7 @@ g_dbus_connection_send_message_with_reply_sync (GDBusConnection *connection,
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
g_return_val_if_fail ((flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL) || !g_dbus_message_get_locked (message), FALSE);
g_return_val_if_fail ((flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL) || !g_dbus_message_get_locked (message), NULL);
g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
@@ -2264,15 +2264,20 @@ initable_init (GInitable *initable,
ret = FALSE;
/* First, handle the case where the connection already has an
* initialization error set.
*/
if (connection->initialization_error != NULL)
goto out;
/* Also make this a no-op if we're already initialized fine */
if (connection->is_initialized)
{
if (connection->stream != NULL)
ret = TRUE;
else
g_assert (connection->initialization_error != NULL);
ret = TRUE;
goto out;
}
g_assert (connection->initialization_error == NULL);
g_assert (connection->initialization_error == NULL && !connection->is_initialized);
/* The user can pass multiple (but mutally exclusive) construct
* properties:

View File

@@ -3197,8 +3197,8 @@ g_dbus_message_lock (GDBusMessage *message)
* This operation can fail if e.g. @message contains file descriptors
* and the per-process or system-wide open files limit is reached.
*
* Returns: (transfer full): A new #GDBusMessage or %NULL if @error is set. Free with
* g_object_unref().
* Returns: (transfer full): A new #GDBusMessage or %NULL if @error is set.
* Free with g_object_unref().
*
* Since: 2.26
*/
@@ -3212,7 +3212,7 @@ g_dbus_message_copy (GDBusMessage *message,
GVariant *header_value;
g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
ret = g_dbus_message_new ();
ret->type = message->type;
@@ -3255,4 +3255,3 @@ g_dbus_message_copy (GDBusMessage *message,
out:
return ret;
}

View File

@@ -399,10 +399,10 @@ struct GDBusWorker
* only user) - we might want it to affect messages sent to the other peer too?
*/
gboolean frozen;
GDBusCapabilityFlags capabilities;
GQueue *received_messages_while_frozen;
GIOStream *stream;
GDBusCapabilityFlags capabilities;
GCancellable *cancellable;
GDBusWorkerMessageReceivedCallback message_received_callback;
GDBusWorkerMessageAboutToBeSentCallback message_about_to_be_sent_callback;
@@ -425,9 +425,9 @@ struct GDBusWorker
gint read_num_ancillary_messages;
/* used for writing */
gint num_writes_pending;
GMutex *write_lock;
GQueue *write_queue;
gint num_writes_pending;
guint64 write_num_messages_written;
GList *write_pending_flushes;
gboolean flush_pending;

View File

@@ -83,9 +83,9 @@
struct _GDBusProxyPrivate
{
GBusType bus_type;
GDBusProxyFlags flags;
GDBusConnection *connection;
GDBusProxyFlags flags;
gchar *name;
gchar *name_owner;
gchar *object_path;
@@ -505,7 +505,7 @@ g_dbus_proxy_class_init (GDBusProxyClass *klass)
*/
signals[PROPERTIES_CHANGED_SIGNAL] = g_signal_new ("g-properties-changed",
G_TYPE_DBUS_PROXY,
G_SIGNAL_RUN_LAST,
G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
G_STRUCT_OFFSET (GDBusProxyClass, g_properties_changed),
NULL,
NULL,
@@ -528,7 +528,7 @@ g_dbus_proxy_class_init (GDBusProxyClass *klass)
*/
signals[SIGNAL_SIGNAL] = g_signal_new ("g-signal",
G_TYPE_DBUS_PROXY,
G_SIGNAL_RUN_LAST,
G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
G_STRUCT_OFFSET (GDBusProxyClass, g_signal),
NULL,
NULL,
@@ -1037,14 +1037,13 @@ on_name_owner_changed (GDBusConnection *connection,
g_hash_table_size (proxy->priv->properties) > 0)
{
GVariantBuilder builder;
GVariant *changed_properties;
GPtrArray *invalidated_properties;
GHashTableIter iter;
const gchar *key;
/* Build changed_properties (always empty) and invalidated_properties ... */
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
changed_properties = g_variant_builder_end (&builder);
invalidated_properties = g_ptr_array_new_with_free_func (g_free);
g_hash_table_iter_init (&iter, proxy->priv->properties);
while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL))
@@ -1057,9 +1056,8 @@ on_name_owner_changed (GDBusConnection *connection,
/* ... and finally emit the ::g-properties-changed signal */
g_signal_emit (proxy, signals[PROPERTIES_CHANGED_SIGNAL],
0,
changed_properties,
g_variant_builder_end (&builder) /* consumed */,
(const gchar* const *) invalidated_properties->pdata);
g_variant_unref (changed_properties);
g_ptr_array_unref (invalidated_properties);
}
g_object_notify (G_OBJECT (proxy), "g-name-owner");

View File

@@ -63,7 +63,13 @@
* @include: gio/gio.h
*
* #GDBusServer is a helper for listening to and accepting D-Bus
* connections.
* connections. This can be used to create a new D-Bus server, allowing two
* peers to use the D-Bus protocol for their own specialized communication.
* A server instance provided in this way will not perform message routing or
* implement the org.freedesktop.DBus interface.
*
* To just export an object on a well-known name on a message bus, such as the
* session or system bus, you should instead use g_bus_own_name().
*
* <example id="gdbus-peer-to-peer"><title>D-Bus peer-to-peer example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-peer.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
@@ -979,11 +985,16 @@ on_run (GSocketService *service,
if (server->flags & G_DBUS_SERVER_FLAGS_RUN_IN_THREAD)
{
gboolean claimed;
claimed = FALSE;
g_signal_emit (server,
_signals[NEW_CONNECTION_SIGNAL],
0,
connection);
g_dbus_connection_start_message_processing (connection);
connection,
&claimed);
if (claimed)
g_dbus_connection_start_message_processing (connection);
g_object_unref (connection);
}
else

View File

@@ -64,8 +64,14 @@
#define ADDED_ASSOCIATIONS_GROUP "Added Associations"
#define REMOVED_ASSOCIATIONS_GROUP "Removed Associations"
#define MIME_CACHE_GROUP "MIME Cache"
#define GENERIC_NAME_KEY "GenericName"
#define FULL_NAME_KEY "X-GNOME-FullName"
enum {
PROP_0,
PROP_FILENAME
};
static void g_desktop_app_info_iface_init (GAppInfoIface *iface);
static GList * get_all_desktop_entries_for_mime_type (const char *base_mime_type,
const char **except,
@@ -88,7 +94,7 @@ struct _GDesktopAppInfo
char *filename;
char *name;
/* FIXME: what about GenericName ? */
char *generic_name;
char *fullname;
char *comment;
char *icon_name;
@@ -99,6 +105,7 @@ struct _GDesktopAppInfo
char *exec;
char *binary;
char *path;
char *categories;
guint nodisplay : 1;
guint hidden : 1;
@@ -161,6 +168,7 @@ g_desktop_app_info_finalize (GObject *object)
g_free (info->desktop_id);
g_free (info->filename);
g_free (info->name);
g_free (info->generic_name);
g_free (info->fullname);
g_free (info->comment);
g_free (info->icon_name);
@@ -172,16 +180,69 @@ g_desktop_app_info_finalize (GObject *object)
g_free (info->exec);
g_free (info->binary);
g_free (info->path);
g_free (info->categories);
G_OBJECT_CLASS (g_desktop_app_info_parent_class)->finalize (object);
}
static void
g_desktop_app_info_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GDesktopAppInfo *self = G_DESKTOP_APP_INFO (object);
switch (prop_id)
{
case PROP_FILENAME:
self->filename = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
g_desktop_app_info_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GDesktopAppInfo *self = G_DESKTOP_APP_INFO (object);
switch (prop_id)
{
case PROP_FILENAME:
g_value_set_string (value, self->filename);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
g_desktop_app_info_class_init (GDesktopAppInfoClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = g_desktop_app_info_get_property;
gobject_class->set_property = g_desktop_app_info_set_property;
gobject_class->finalize = g_desktop_app_info_finalize;
/**
* GDesktopAppInfo:filename
*
* The origin filename of this #GDesktopAppInfo
*/
g_object_class_install_property (gobject_class,
PROP_FILENAME,
g_param_spec_string ("filename", "Filename", "",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
static void
@@ -205,29 +266,19 @@ binary_from_exec (const char *exec)
}
/**
* g_desktop_app_info_new_from_keyfile:
* @key_file: an opened #GKeyFile
*
* Creates a new #GDesktopAppInfo.
*
* Returns: a new #GDesktopAppInfo or %NULL on error.
*
* Since: 2.18
**/
GDesktopAppInfo *
g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
static gboolean
g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
GKeyFile *key_file)
{
GDesktopAppInfo *info;
char *start_group;
char *type;
char *try_exec;
start_group = g_key_file_get_start_group (key_file);
if (start_group == NULL || strcmp (start_group, G_KEY_FILE_DESKTOP_GROUP) != 0)
{
g_free (start_group);
return NULL;
return FALSE;
}
g_free (start_group);
@@ -238,7 +289,7 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
if (type == NULL || strcmp (type, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) != 0)
{
g_free (type);
return NULL;
return FALSE;
}
g_free (type);
@@ -253,15 +304,13 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
if (t == NULL)
{
g_free (try_exec);
return NULL;
return FALSE;
}
g_free (t);
}
info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL);
info->filename = NULL;
info->name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL);
info->generic_name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, GENERIC_NAME_KEY, NULL, NULL);
info->fullname = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, FULL_NAME_KEY, NULL, NULL);
info->comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, NULL);
info->nodisplay = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL) != FALSE;
@@ -275,6 +324,7 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
info->startup_notify = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, NULL) != FALSE;
info->no_fuse = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GIO-NoFuse", NULL) != FALSE;
info->hidden = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL) != FALSE;
info->categories = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_CATEGORIES, NULL);
info->icon = NULL;
if (info->icon_name)
@@ -311,6 +361,53 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
info->path = NULL;
}
return TRUE;
}
static gboolean
g_desktop_app_info_load_file (GDesktopAppInfo *self)
{
GKeyFile *key_file;
gboolean retval = FALSE;
g_return_val_if_fail (self->filename != NULL, FALSE);
key_file = g_key_file_new ();
if (g_key_file_load_from_file (key_file,
self->filename,
G_KEY_FILE_NONE,
NULL))
{
retval = g_desktop_app_info_load_from_keyfile (self, key_file);
}
g_key_file_free (key_file);
return retval;
}
/**
* g_desktop_app_info_new_from_keyfile:
* @key_file: an opened #GKeyFile
*
* Creates a new #GDesktopAppInfo.
*
* Returns: a new #GDesktopAppInfo or %NULL on error.
*
* Since: 2.18
**/
GDesktopAppInfo *
g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
{
GDesktopAppInfo *info;
info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL);
info->filename = NULL;
if (!g_desktop_app_info_load_from_keyfile (info, key_file))
{
g_object_unref (info);
return NULL;
}
return info;
}
@@ -325,23 +422,14 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
GDesktopAppInfo *
g_desktop_app_info_new_from_filename (const char *filename)
{
GKeyFile *key_file;
GDesktopAppInfo *info = NULL;
key_file = g_key_file_new ();
if (g_key_file_load_from_file (key_file,
filename,
G_KEY_FILE_NONE,
NULL))
info = g_object_new (G_TYPE_DESKTOP_APP_INFO, "filename", filename, NULL);
if (!g_desktop_app_info_load_file (info))
{
info = g_desktop_app_info_new_from_keyfile (key_file);
if (info)
info->filename = g_strdup (filename);
}
g_key_file_free (key_file);
g_object_unref (info);
return NULL;
}
return info;
}
@@ -430,6 +518,7 @@ g_desktop_app_info_dup (GAppInfo *appinfo)
new_info->desktop_id = g_strdup (info->desktop_id);
new_info->name = g_strdup (info->name);
new_info->generic_name = g_strdup (info->generic_name);
new_info->fullname = g_strdup (info->fullname);
new_info->comment = g_strdup (info->comment);
new_info->nodisplay = info->nodisplay;
@@ -555,6 +644,31 @@ g_desktop_app_info_get_icon (GAppInfo *appinfo)
return info->icon;
}
/**
* g_desktop_app_info_get_categories:
* @info: a #GDesktopAppInfo
*
* Returns: The unparsed Categories key from the file; i.e. no attempt
* is made to split it by ';' or validate it.
*/
const char *
g_desktop_app_info_get_categories (GDesktopAppInfo *info)
{
return info->categories;
}
/**
* g_desktop_app_info_get_generic_name:
* @info: a #GDesktopAppInfo
*
* Returns: The value of the GenericName key
*/
const char *
g_desktop_app_info_get_generic_name (GDesktopAppInfo *info)
{
return info->generic_name;
}
static char *
expand_macro_single (char macro, char *uri)
{
@@ -1813,6 +1927,10 @@ g_desktop_app_info_ensure_saved (GDesktopAppInfo *info,
g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
G_KEY_FILE_DESKTOP_KEY_NAME, info->name);
if (info->generic_name != NULL)
g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
GENERIC_NAME_KEY, info->generic_name);
if (info->fullname != NULL)
g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
FULL_NAME_KEY, info->fullname);
@@ -1932,10 +2050,10 @@ g_app_info_create_from_commandline (const char *commandline,
info->filename = NULL;
info->desktop_id = NULL;
info->terminal = flags & G_APP_INFO_CREATE_NEEDS_TERMINAL;
info->startup_notify = flags & G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION;
info->terminal = (flags & G_APP_INFO_CREATE_NEEDS_TERMINAL) != 0;
info->startup_notify = (flags & G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION) != 0;
info->hidden = FALSE;
if (flags & G_APP_INFO_CREATE_SUPPORTS_URIS)
if ((flags & G_APP_INFO_CREATE_SUPPORTS_URIS) != 0)
info->exec = g_strconcat (commandline, " %u", NULL);
else
info->exec = g_strconcat (commandline, " %f", NULL);

View File

@@ -50,6 +50,9 @@ GDesktopAppInfo *g_desktop_app_info_new_from_keyfile (GKeyFile *key_file
const char * g_desktop_app_info_get_filename (GDesktopAppInfo *info);
const char * g_desktop_app_info_get_generic_name (GDesktopAppInfo *info);
const char * g_desktop_app_info_get_categories (GDesktopAppInfo *info);
GDesktopAppInfo *g_desktop_app_info_new (const char *desktop_id);
gboolean g_desktop_app_info_get_is_hidden (GDesktopAppInfo *info);

View File

@@ -2096,12 +2096,13 @@ typedef struct {
struct _GFileAttributeMatcher {
gboolean all;
SubMatcher sub_matchers[ON_STACK_MATCHERS];
gint ref;
GArray *more_sub_matchers;
/* Interator */
guint32 iterator_ns;
int iterator_pos;
int ref;
gint iterator_pos;
};
static void

View File

@@ -64,8 +64,8 @@ struct _GFilenameCompleter {
GFile *basenames_dir;
gboolean basenames_are_escaped;
GList *basenames;
gboolean dirs_only;
GList *basenames;
LoadBasenamesData *basename_loader;
};

View File

@@ -113,7 +113,7 @@ g_filter_input_stream_class_init (GFilterInputStreamClass *klass)
g_param_spec_boolean ("close-base-stream",
P_("Close Base Stream"),
P_("If the base stream should be closed when the filter stream is closed."),
TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
}

View File

@@ -866,3 +866,32 @@ g_inet_address_get_is_mc_site_local (GInetAddress *address)
else
return IN6_IS_ADDR_MC_SITELOCAL (&address->priv->addr.ipv6);
}
/**
* g_inet_address_equal:
* @address: A #GInetAddress.
* @other_address: Another #GInetAddress.
*
* Checks if two #GInetAddress instances are equal, e.g. the same address.
*
* Returns: %TRUE if @address and @other_address are equal, %FALSE otherwise.
*
* Since: 2.30
*/
gboolean
g_inet_address_equal (GInetAddress *address,
GInetAddress *other_address)
{
g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
g_return_val_if_fail (G_IS_INET_ADDRESS (other_address), FALSE);
if (g_inet_address_get_family (address) != g_inet_address_get_family (other_address))
return FALSE;
if (memcmp (g_inet_address_to_bytes (address),
g_inet_address_to_bytes (other_address),
g_inet_address_get_native_size (address)) != 0)
return FALSE;
return TRUE;
}

View File

@@ -69,6 +69,9 @@ GInetAddress * g_inet_address_new_loopback (GSocketFamily
GInetAddress * g_inet_address_new_any (GSocketFamily family);
gboolean g_inet_address_equal (GInetAddress *address,
GInetAddress *other_address);
gchar * g_inet_address_to_string (GInetAddress *address);
const guint8 * g_inet_address_to_bytes (GInetAddress *address);

View File

@@ -132,7 +132,9 @@ g_app_info_reset_type_associations
g_desktop_app_info_new_from_filename
g_desktop_app_info_new_from_keyfile
g_desktop_app_info_new
g_desktop_app_info_get_categories
g_desktop_app_info_get_filename
g_desktop_app_info_get_generic_name
g_desktop_app_info_get_is_hidden
g_desktop_app_info_get_type G_GNUC_CONST
g_desktop_app_info_launch_uris_as_manager
@@ -1123,6 +1125,7 @@ g_inet_address_get_is_site_local
g_inet_address_to_bytes
g_inet_address_get_native_size
g_inet_address_to_string
g_inet_address_equal
#endif
#endif

View File

@@ -1265,6 +1265,11 @@ typedef enum
* when editing a git commit message. The environment is available
* to the #GApplication::command-line signal handler, via
* g_application_command_line_getenv().
* @G_APPLICATION_NON_UNIQUE: Make no attempts to do any of the typical
* single-instance application negotiation. The application neither
* attempts to become the owner of the application ID nor does it
* check if an existing owner already exists. Everything occurs in
* the local process. Since: 2.30.
*
* Flags used to define the behaviour of a #GApplication.
*
@@ -1278,7 +1283,9 @@ typedef enum
G_APPLICATION_HANDLES_OPEN = (1 << 2),
G_APPLICATION_HANDLES_COMMAND_LINE = (1 << 3),
G_APPLICATION_SEND_ENVIRONMENT = (1 << 4)
G_APPLICATION_SEND_ENVIRONMENT = (1 << 4),
G_APPLICATION_NON_UNIQUE = (1 << 5),
} GApplicationFlags;
/**

View File

@@ -51,11 +51,10 @@ struct _GIOSchedulerJob {
GSourceFunc cancel_func; /* Runs under job map lock */
gpointer data;
GDestroyNotify destroy_notify;
gint io_priority;
GCancellable *cancellable;
GMainContext *context;
gint io_priority;
guint idle_tag;
};

View File

@@ -24,13 +24,16 @@
#include "config.h"
#include <gstdio.h>
#include <locale.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <gi18n.h>
#include <string.h>
#include <stdio.h>
#include <locale.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "gvdb/gvdb-builder.h"
#include "strinfo.c"

View File

@@ -47,8 +47,8 @@ struct _GLocalDirectoryMonitor
gchar *dirname;
GFileMonitorFlags flags;
/* For mount emulation */
GUnixMountMonitor *mount_monitor;
gboolean was_mounted;
GUnixMountMonitor *mount_monitor;
};
struct _GLocalDirectoryMonitorClass

View File

@@ -1297,8 +1297,8 @@ g_local_file_read (GFile *file,
GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
int fd;
struct stat buf;
int fd, ret;
GLocalFileStat buf;
fd = g_open (local->filename, O_RDONLY|O_BINARY, 0);
if (fd == -1)
@@ -1312,7 +1312,13 @@ g_local_file_read (GFile *file,
return NULL;
}
if (fstat(fd, &buf) == 0 && S_ISDIR (buf.st_mode))
#ifdef G_OS_WIN32
ret = _fstati64 (fd, &buf);
#else
ret = fstat (fd, &buf);
#endif
if (ret == 0 && S_ISDIR (buf.st_mode))
{
close (fd);
g_set_error_literal (error, G_IO_ERROR,

View File

@@ -1883,7 +1883,7 @@ set_unix_mode (char *filename,
const GFileAttributeValue *value,
GError **error)
{
guint32 val;
guint32 val = 0;
int res = 0;
if (!get_uint32 (value, &val, error))
@@ -1934,7 +1934,7 @@ set_unix_uid_gid (char *filename,
GError **error)
{
int res;
guint32 val;
guint32 val = 0;
uid_t uid;
gid_t gid;
@@ -2070,8 +2070,8 @@ set_mtime_atime (char *filename,
GError **error)
{
int res;
guint64 val;
guint32 val_usec;
guint64 val = 0;
guint32 val_usec = 0;
struct stat statbuf;
gboolean got_stat = FALSE;
struct timeval times[2] = { {0, 0}, {0, 0} };

View File

@@ -909,10 +909,16 @@ handle_overwrite_open (const char *filename,
)
)
{
struct stat tmp_statbuf;
GLocalFileStat tmp_statbuf;
int tres;
#ifdef G_OS_WIN32
tres = _fstati64 (tmpfd, &tmp_statbuf);
#else
tres = fstat (tmpfd, &tmp_statbuf);
#endif
/* Check that we really needed to change something */
if (fstat (tmpfd, &tmp_statbuf) != 0 ||
if (tres != 0 ||
original_stat.st_uid != tmp_statbuf.st_uid ||
original_stat.st_gid != tmp_statbuf.st_gid ||
original_stat.st_mode != tmp_statbuf.st_mode)

View File

@@ -212,6 +212,36 @@ g_resolver_maybe_reload (GResolver *resolver)
#endif
}
/* filter out duplicates, cf. https://bugzilla.gnome.org/show_bug.cgi?id=631379 */
static void
remove_duplicates (GList *addrs)
{
GList *l;
GList *ll;
GList *lll;
/* TODO: if this is too slow (it's O(n^2) but n is typically really
* small), we can do something more clever but note that we must not
* change the order of elements...
*/
for (l = addrs; l != NULL; l = l->next)
{
GInetAddress *address = G_INET_ADDRESS (l->data);
for (ll = l->next; ll != NULL; ll = lll)
{
GInetAddress *other_address = G_INET_ADDRESS (ll->data);
lll = ll->next;
if (g_inet_address_equal (address, other_address))
{
g_object_unref (other_address);
/* we never return the first element */
g_warn_if_fail (g_list_delete_link (addrs, ll) == addrs);
}
}
}
}
/**
* g_resolver_lookup_by_name:
* @resolver: a #GResolver
@@ -225,9 +255,12 @@ g_resolver_maybe_reload (GResolver *resolver)
* a wrapper around g_inet_address_new_from_string()).
*
* On success, g_resolver_lookup_by_name() will return a #GList of
* #GInetAddress, sorted in order of preference. (That is, you should
* attempt to connect to the first address first, then the second if
* the first fails, etc.)
* #GInetAddress, sorted in order of preference and guaranteed to not
* contain duplicates. That is, if using the result to connect to
* @hostname, you should attempt to connect to the first address
* first, then the second if the first fails, etc. If you are using
* the result to listen on a socket, it is appropriate to add each
* result using e.g. g_socket_listener_add_address().
*
* If the DNS resolution fails, @error (if non-%NULL) will be set to a
* value from #GResolverError.
@@ -272,6 +305,8 @@ g_resolver_lookup_by_name (GResolver *resolver,
addrs = G_RESOLVER_GET_CLASS (resolver)->
lookup_by_name (resolver, hostname, cancellable, error);
remove_duplicates (addrs);
g_free (ascii_hostname);
return addrs;
}
@@ -354,6 +389,8 @@ g_resolver_lookup_by_name_finish (GResolver *resolver,
GAsyncResult *result,
GError **error)
{
GList *addrs;
g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
if (G_IS_SIMPLE_ASYNC_RESULT (result))
@@ -373,8 +410,12 @@ g_resolver_lookup_by_name_finish (GResolver *resolver,
}
}
return G_RESOLVER_GET_CLASS (resolver)->
addrs = G_RESOLVER_GET_CLASS (resolver)->
lookup_by_name_finish (resolver, result, error);
remove_duplicates (addrs);
return addrs;
}
/**

View File

@@ -357,6 +357,54 @@ gsettings_reset (GSettings *settings,
g_settings_sync ();
}
static void
reset_all_keys (GSettings *settings)
{
gchar **keys;
gint i;
keys = g_settings_list_keys (settings);
for (i = 0; keys[i]; i++)
{
g_settings_reset (settings, keys[i]);
}
g_strfreev (keys);
}
static void
gsettings_reset_recursively (GSettings *settings,
const gchar *key,
const gchar *value)
{
gchar **children;
gint i;
g_settings_delay (settings);
reset_all_keys (settings);
children = g_settings_list_children (settings);
for (i = 0; children[i]; i++)
{
GSettings *child;
gchar *schema;
child = g_settings_get_child (settings, children[i]);
g_object_get (child, "schema", &schema, NULL);
if (is_schema (schema))
reset_all_keys (child);
g_object_unref (child);
g_free (schema);
}
g_strfreev (children);
g_settings_apply (settings);
g_settings_sync ();
}
static void
gsettings_writable (GSettings *settings,
const gchar *key,
@@ -409,6 +457,7 @@ gsettings_set (GSettings *settings,
GError *error = NULL;
GVariant *existing;
GVariant *new;
GVariant *stored;
gchar *freeme = NULL;
existing = g_settings_get_value (settings, key);
@@ -442,16 +491,23 @@ gsettings_set (GSettings *settings,
if (!g_settings_range_check (settings, key, new))
{
g_printerr (_("The provided value is outside of the valid range\n"));
g_variant_unref (new);
exit (1);
}
g_settings_set_value (settings, key, new);
g_settings_sync ();
stored = g_settings_get_value (settings, key);
if (g_variant_equal (stored, existing))
{
g_printerr (_("Failed to set value\n"));
exit (1);
}
g_variant_unref (stored);
g_variant_unref (existing);
g_variant_unref (new);
g_settings_sync ();
g_free (freeme);
}
@@ -529,6 +585,12 @@ gsettings_help (gboolean requested,
synopsis = N_("SCHEMA[:PATH] KEY");
}
else if (strcmp (command, "reset-recursively") == 0)
{
description = _("Reset all keys in SCHEMA to their defaults");
synopsis = N_("SCHEMA[:PATH]");
}
else if (strcmp (command, "writable") == 0)
{
description = _("Check if KEY is writable");
@@ -566,6 +628,7 @@ gsettings_help (gboolean requested,
" get Get the value of a key\n"
" set Set the value of a key\n"
" reset Reset the value of a key\n"
" reset-recursively Reset all values in a given schema\n"
" writable Check if a key is writable\n"
" monitor Watch for changes\n"
"\n"
@@ -671,6 +734,9 @@ main (int argc, char **argv)
else if (argc == 4 && strcmp (argv[1], "reset") == 0)
function = gsettings_reset;
else if (argc == 3 && strcmp (argv[1], "reset-recursively") == 0)
function = gsettings_reset_recursively;
else if (argc == 4 && strcmp (argv[1], "writable") == 0)
function = gsettings_writable;

View File

@@ -59,7 +59,7 @@
* even need to be started in this case. For this reason, you should
* only ever modify #GSettings keys in response to explicit user action.
* Particular care should be paid to ensure that modifications are not
* made during startup -- for example, when settings the initial value
* made during startup -- for example, when setting the initial value
* of preferences widgets. The built-in g_settings_bind() functionality
* is careful not to write settings in response to notify signals as a
* result of modifications that it makes to widgets.
@@ -810,8 +810,8 @@ g_settings_new_with_path (const gchar *schema,
*
* Creates a new #GSettings object with a given schema and backend.
*
* Creating settings objects with an different backend allows accessing settings
* from a database other than the usual one. For example, it may make
* Creating a #GSettings object with a different backend allows accessing
* settings from a database other than the usual one. For example, it may make
* sense to pass a backend corresponding to the "defaults" settings database on
* the system to get a settings object that modifies the system default
* settings instead of the settings for this user.

View File

@@ -45,6 +45,13 @@ struct _GSettingsBackendPrivate
GStaticMutex lock;
};
/* For g_settings_backend_sync_default(), we only want to actually do
* the sync if the backend already exists. This avoids us creating an
* entire GSettingsBackend in order to call a do-nothing sync()
* operation on it. This variable lets us avoid that.
*/
static gboolean g_settings_has_backend;
/**
* SECTION:gsettingsbackend
* @title: GSettingsBackend
@@ -982,6 +989,7 @@ g_settings_backend_get_default (void)
extension_type = g_io_extension_get_type (extension);
instance = g_object_new (extension_type, NULL);
g_settings_has_backend = TRUE;
g_once_init_leave (&backend, (gsize) instance);
}
@@ -1021,12 +1029,15 @@ g_settings_backend_get_permission (GSettingsBackend *backend,
void
g_settings_backend_sync_default (void)
{
GSettingsBackendClass *class;
GSettingsBackend *backend;
if (g_settings_has_backend)
{
GSettingsBackendClass *class;
GSettingsBackend *backend;
backend = g_settings_backend_get_default ();
class = G_SETTINGS_BACKEND_GET_CLASS (backend);
backend = g_settings_backend_get_default ();
class = G_SETTINGS_BACKEND_GET_CLASS (backend);
if (class->sync)
class->sync (backend);
if (class->sync)
class->sync (backend);
}
}

View File

@@ -323,7 +323,7 @@ g_simple_action_class_init (GSimpleActionClass *class)
g_simple_action_signals[SIGNAL_ACTIVATE] =
g_signal_new (I_("activate"),
G_TYPE_SIMPLE_ACTION,
G_SIGNAL_RUN_LAST,
G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
G_STRUCT_OFFSET (GSimpleActionClass, activate),
NULL, NULL,
g_cclosure_marshal_VOID__VARIANT,

View File

@@ -744,9 +744,13 @@ g_simple_async_result_complete (GSimpleAsyncResult *simple)
#endif
if (simple->callback)
simple->callback (simple->source_object,
G_ASYNC_RESULT (simple),
simple->user_data);
{
g_main_context_push_thread_default (simple->context);
simple->callback (simple->source_object,
G_ASYNC_RESULT (simple),
simple->user_data);
g_main_context_pop_thread_default (simple->context);
}
}
static gboolean

View File

@@ -1756,15 +1756,17 @@ g_socket_check_connect_result (GSocket *socket,
* received, the additional data will be returned in future calls to
* g_socket_receive().
*
* If the socket is in blocking mode the call will block until there is
* some data to receive or there is an error. If there is no data available
* and the socket is in non-blocking mode, a %G_IO_ERROR_WOULD_BLOCK error
* will be returned. To be notified when data is available, wait for the
* If the socket is in blocking mode the call will block until there
* is some data to receive, the connection is closed, or there is an
* error. If there is no data available and the socket is in
* non-blocking mode, a %G_IO_ERROR_WOULD_BLOCK error will be
* returned. To be notified when data is available, wait for the
* %G_IO_IN condition.
*
* On error -1 is returned and @error is set accordingly.
*
* Returns: Number of bytes read, or -1 on error
* Returns: Number of bytes read, or 0 if the connection was closed by
* the peer, or -1 on error
*
* Since: 2.22
*/
@@ -1794,7 +1796,8 @@ g_socket_receive (GSocket *socket,
* the choice of blocking or non-blocking behavior is determined by
* the @blocking argument rather than by @socket's properties.
*
* Returns: Number of bytes read, or -1 on error
* Returns: Number of bytes read, or 0 if the connection was closed by
* the peer, or -1 on error
*
* Since: 2.26
*/
@@ -1876,7 +1879,8 @@ g_socket_receive_with_blocking (GSocket *socket,
*
* See g_socket_receive() for additional information.
*
* Returns: Number of bytes read, or -1 on error
* Returns: Number of bytes read, or 0 if the connection was closed by
* the peer, or -1 on error
*
* Since: 2.22
*/
@@ -3182,14 +3186,16 @@ g_socket_send_message (GSocket *socket,
* sufficiently-large buffer.
*
* If the socket is in blocking mode the call will block until there
* is some data to receive or there is an error. If there is no data
* available and the socket is in non-blocking mode, a
* %G_IO_ERROR_WOULD_BLOCK error will be returned. To be notified when
* data is available, wait for the %G_IO_IN condition.
* is some data to receive, the connection is closed, or there is an
* error. If there is no data available and the socket is in
* non-blocking mode, a %G_IO_ERROR_WOULD_BLOCK error will be
* returned. To be notified when data is available, wait for the
* %G_IO_IN condition.
*
* On error -1 is returned and @error is set accordingly.
*
* Returns: Number of bytes read, or -1 on error
* Returns: Number of bytes read, or 0 if the connection was closed by
* the peer, or -1 on error
*
* Since: 2.22
*/

View File

@@ -58,7 +58,7 @@
* #GSocketClient is a high-level utility class for connecting to a
* network host using a connection oriented socket type.
*
* You create a #GSocketClient object, set any options you want, then
* You create a #GSocketClient object, set any options you want, and then
* call a sync or async connect operation, which returns a #GSocketConnection
* subclass on success.
*
@@ -442,7 +442,7 @@ g_socket_client_get_local_address (GSocketClient *client)
* The sockets created by this object will bound to the
* specified address (if not %NULL) before connecting.
*
* This is useful if you want to ensure the the local
* This is useful if you want to ensure that the local
* side of the connection is on a specific port, or on
* a specific interface.
*
@@ -726,7 +726,7 @@ g_socket_client_class_init (GSocketClientClass *class)
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
* @error: #GError for error reporting, or %NULL to ignore.
*
* Tries to resolve the @connectable and make a network connection to it..
* Tries to resolve the @connectable and make a network connection to it.
*
* Upon a successful connection, a new #GSocketConnection is constructed
* and returned. The caller owns this new object and must drop their
@@ -736,7 +736,7 @@ g_socket_client_class_init (GSocketClientClass *class)
* the underlying socket that is used. For instance, for a TCP/IP connection
* it will be a #GTcpConnection.
*
* The socket created will be the same family as the the address that the
* The socket created will be the same family as the address that the
* @connectable resolves to, unless family is set with g_socket_client_set_family()
* or indirectly via g_socket_client_set_local_address(). The socket type
* defaults to %G_SOCKET_TYPE_STREAM but can be set with
@@ -912,7 +912,7 @@ g_socket_client_connect (GSocketClient *client,
*
* Attempts to create a TCP connection to the named host.
*
* @host_and_port may be in any of a number of recognised formats; an IPv6
* @host_and_port may be in any of a number of recognized formats; an IPv6
* address, an IPv4 address, or a domain name (in which case a DNS
* lookup is performed). Quoting with [] is supported for all address
* types. A port override may be specified in the usual way with a
@@ -923,7 +923,7 @@ g_socket_client_connect (GSocketClient *client,
* used as the port number to connect to.
*
* In general, @host_and_port is expected to be provided by the user (allowing
* them to give the hostname, and a port overide if necessary) and
* them to give the hostname, and a port override if necessary) and
* @default_port is expected to be provided by the application.
*
* In the case that an IP address is given, a single connection
@@ -1591,7 +1591,7 @@ g_socket_client_connect_to_uri_async (GSocketClient *client,
* g_socket_client_connect_finish:
* @client: a #GSocketClient.
* @result: a #GAsyncResult.
* @error: a #GError location to store the error occuring, or %NULL to
* @error: a #GError location to store the error occurring, or %NULL to
* ignore.
*
* Finishes an async connect operation. See g_socket_client_connect_async()
@@ -1617,7 +1617,7 @@ g_socket_client_connect_finish (GSocketClient *client,
* g_socket_client_connect_to_host_finish:
* @client: a #GSocketClient.
* @result: a #GAsyncResult.
* @error: a #GError location to store the error occuring, or %NULL to
* @error: a #GError location to store the error occurring, or %NULL to
* ignore.
*
* Finishes an async connect operation. See g_socket_client_connect_to_host_async()
@@ -1638,7 +1638,7 @@ g_socket_client_connect_to_host_finish (GSocketClient *client,
* g_socket_client_connect_to_service_finish:
* @client: a #GSocketClient.
* @result: a #GAsyncResult.
* @error: a #GError location to store the error occuring, or %NULL to
* @error: a #GError location to store the error occurring, or %NULL to
* ignore.
*
* Finishes an async connect operation. See g_socket_client_connect_to_service_async()
@@ -1659,7 +1659,7 @@ g_socket_client_connect_to_service_finish (GSocketClient *client,
* g_socket_client_connect_to_uri_finish:
* @client: a #GSocketClient.
* @result: a #GAsyncResult.
* @error: a #GError location to store the error occuring, or %NULL to
* @error: a #GError location to store the error occurring, or %NULL to
* ignore.
*
* Finishes an async connect operation. See g_socket_client_connect_to_uri_async()
@@ -1684,7 +1684,7 @@ g_socket_client_connect_to_uri_finish (GSocketClient *client,
* Enable proxy protocols to be handled by the application. When the
* indicated proxy protocol is returned by the #GProxyResolver,
* #GSocketClient will consider this protocol as supported but will
* not try find a #GProxy instance to handle handshaking. The
* not try to find a #GProxy instance to handle handshaking. The
* application must check for this case by calling
* g_socket_connection_get_remote_address() on the returned
* #GSocketConnection, and seeing if it's a #GProxyAddress of the

View File

@@ -52,7 +52,7 @@
* depends on the type of the underlying socket that is in use. For
* instance, for a TCP/IP connection it will be a #GTcpConnection.
*
* Chosing what type of object to construct is done with the socket
* Choosing what type of object to construct is done with the socket
* connection factory, and it is possible for 3rd parties to register
* custom socket connection types for specific combination of socket
* family/type/protocol using g_socket_connection_factory_register_type().
@@ -404,7 +404,7 @@ G_LOCK_DEFINE_STATIC(connection_factories);
* @protocol: a protocol id
*
* Looks up the #GType to be used when creating socket connections on
* sockets with the specified @family,@type and @protocol.
* sockets with the specified @family, @type and @protocol.
*
* If no type is registered, the #GSocketConnection base type is returned.
*
@@ -458,7 +458,7 @@ init_builtin_types (void)
* @protocol_id: a protocol id
*
* Looks up the #GType to be used when creating socket connections on
* sockets with the specified @family,@type and @protocol_id.
* sockets with the specified @family, @type and @protocol_id.
*
* If no type is registered, the #GSocketConnection base type is returned.
*

View File

@@ -263,7 +263,7 @@ g_socket_listener_add_socket (GSocketListener *listener,
*
* Note that adding an IPv6 address, depending on the platform,
* may or may not result in a listener that also accepts IPv4
* connections. For more determinstic behaviour, see
* connections. For more deterministic behavior, see
* g_socket_listener_add_inet_port().
*
* @source_object will be passed out in the various calls
@@ -272,7 +272,7 @@ g_socket_listener_add_socket (GSocketListener *listener,
* different things depending on what address is connected to.
*
* If successful and @effective_address is non-%NULL then it will
* be set to the address that the binding actually occured at. This
* be set to the address that the binding actually occurred at. This
* is helpful for determining the port number that was used for when
* requesting a binding to port 0 (ie: "any port"). This address, if
* requested, belongs to the caller and must be freed.
@@ -770,7 +770,7 @@ g_socket_listener_accept_socket_async (GSocketListener *listener,
* @listener: a #GSocketListener
* @result: a #GAsyncResult.
* @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
* @error: a #GError location to store the error occuring, or %NULL to
* @error: a #GError location to store the error occurring, or %NULL to
* ignore.
*
* Finishes an async accept operation. See g_socket_listener_accept_socket_async()
@@ -837,7 +837,7 @@ g_socket_listener_accept_async (GSocketListener *listener,
* @listener: a #GSocketListener
* @result: a #GAsyncResult.
* @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
* @error: a #GError location to store the error occuring, or %NULL to
* @error: a #GError location to store the error occurring, or %NULL to
* ignore.
*
* Finishes an async accept operation. See g_socket_listener_accept_async()
@@ -928,11 +928,11 @@ g_socket_listener_close (GSocketListener *listener)
* g_socket_listener_add_any_inet_port:
* @listener: a #GSocketListener
* @source_object: (allow-none): Optional #GObject identifying this source
* @error: a #GError location to store the error occuring, or %NULL to
* @error: a #GError location to store the error occurring, or %NULL to
* ignore.
*
* Listens for TCP connections on any available port number for both
* IPv6 and IPv4 (if each are available).
* IPv6 and IPv4 (if each is available).
*
* This is useful if you need to have a socket for incoming connections
* but don't care about the specific port number.

View File

@@ -34,8 +34,8 @@
* signal is emitted.
*
* A #GSocketService is a subclass of #GSocketListener and you need
* to add the addresses you want to accept connections on to the
* with the #GSocketListener APIs.
* to add the addresses you want to accept connections on with the
* #GSocketListener APIs.
*
* There are two options for implementing a network service based on
* #GSocketService. The first is to create the service using
@@ -260,6 +260,9 @@ g_socket_service_class_init (GSocketServiceClass *class)
* handling of @connection, but may not block; in essence,
* asynchronous operations must be used.
*
* @connection will be unreffed once the signal handler returns, so
* you need to ref it yourself if you are planning to use it.
*
* Returns: %TRUE to stop other handlers from being called
*
* Since: 2.22

View File

@@ -326,7 +326,7 @@ g_tcp_connection_close_async (GIOStream *stream,
* @graceful_disconnect: Whether to do graceful disconnects or not
*
* This enabled graceful disconnects on close. A graceful disconnect
* means that we signal the recieving end that the connection is terminated
* means that we signal the receiving end that the connection is terminated
* and wait for it to close the connection before closing the connection.
*
* A graceful disconnect means that we can be sure that we successfully sent

View File

@@ -37,7 +37,7 @@
* until the connection is closed.
*
* The service is implemented using a thread pool, so there is a
* limited amount of threads availible to serve incomming requests.
* limited amount of threads available to serve incoming requests.
* The service automatically stops the #GSocketService from accepting
* new connections when all threads are busy.
*
@@ -234,7 +234,7 @@ g_threaded_socket_service_class_init (GThreadedSocketServiceClass *class)
* @connection and may perform blocking IO. The signal handler need
* not return until the connection is closed.
*
* Returns: %TRUE to stope further signal handlers from being called
* Returns: %TRUE to stop further signal handlers from being called
*/
g_threaded_socket_service_run_signal =
g_signal_new ("run", G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST,

View File

@@ -66,8 +66,8 @@ G_DEFINE_TYPE_WITH_CODE (GUnixConnection, g_unix_connection,
* @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
* @error: (allow-none): #GError for error reporting, or %NULL to ignore.
*
* Passes a file descriptor to the recieving side of the
* connection. The recieving end has to call g_unix_connection_receive_fd()
* Passes a file descriptor to the receiving side of the
* connection. The receiving end has to call g_unix_connection_receive_fd()
* to accept the file descriptor.
*
* As well as sending the fd this also writes a single byte to the
@@ -308,7 +308,7 @@ gboolean g_unix_connection_create_pair (GUnixCo
* @error: Return location for error or %NULL.
*
* Passes the credentials of the current user the receiving side
* of the connection. The recieving end has to call
* of the connection. The receiving end has to call
* g_unix_connection_receive_credentials() (or similar) to accept the
* credentials.
*

View File

@@ -24,7 +24,9 @@
#include <glib.h>
#include <fcntl.h>
#if !defined(G_OS_WIN32) || !defined(_MSC_VER)
#include <unistd.h>
#endif
#include <string.h>

View File

@@ -30,16 +30,20 @@ test_local_cmdline (GApplication *application,
argv = *arguments;
for (i = 0; argv[i]; i++)
i = 1;
while (argv[i])
{
if (g_str_has_prefix (argv[i], "--local-"))
{
g_print ("handling argument %s locally\n", argv[i]);
for (j = i + 1; argv[j]; j++)
{
argv[j - 1] = argv[j];
argv[j] = NULL;
}
g_free (argv[i]);
for (j = i; argv[j]; j++)
argv[j] = argv[j + 1];
}
else
{
g_print ("not handling argument %s locally\n", argv[i]);
i++;
}
}

View File

@@ -221,6 +221,79 @@ basic (void)
session_bus_down ();
}
static GApplication *recently_activated;
static GMainLoop *loop;
static void
nonunique_activate (GApplication *application)
{
recently_activated = application;
if (loop != NULL)
g_main_loop_quit (loop);
}
static GApplication *
make_app (gboolean non_unique)
{
GApplication *app;
gboolean ok;
app = g_application_new ("org.gtk.TestApplication",
non_unique ? G_APPLICATION_NON_UNIQUE : 0);
g_signal_connect (app, "activate", G_CALLBACK (nonunique_activate), NULL);
ok = g_application_register (app, NULL, NULL);
if (!ok)
{
g_object_unref (app);
return NULL;
}
g_application_activate (app);
return app;
}
static void
test_nonunique (void)
{
GApplication *first, *second, *third, *fourth;
session_bus_up ();
first = make_app (TRUE);
/* non-remote because it is non-unique */
g_assert (!g_application_get_is_remote (first));
g_assert (recently_activated == first);
recently_activated = NULL;
second = make_app (FALSE);
/* non-remote because it is first */
g_assert (!g_application_get_is_remote (second));
g_assert (recently_activated == second);
recently_activated = NULL;
third = make_app (TRUE);
/* non-remote because it is non-unique */
g_assert (!g_application_get_is_remote (third));
g_assert (recently_activated == third);
recently_activated = NULL;
fourth = make_app (FALSE);
/* should have failed to register due to being
* unable to register the object paths
*/
g_assert (fourth == NULL);
g_assert (recently_activated == NULL);
g_object_unref (first);
g_object_unref (second);
g_object_unref (third);
session_bus_down ();
}
static void
properties (void)
{
@@ -289,6 +362,7 @@ main (int argc, char **argv)
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/gapplication/basic", basic);
g_test_add_func ("/gapplication/non-unique", test_nonunique);
g_test_add_func ("/gapplication/properties", properties);
g_test_add_func ("/gapplication/app-id", appid);

View File

@@ -1083,7 +1083,6 @@ delayed_message_processing (void)
/* ---------------------------------------------------------------------------------------------------- */
#ifdef BUG_631379_FIXED
static gboolean
nonce_tcp_on_authorize_authenticated_peer (GDBusAuthObserver *observer,
GIOStream *stream,
@@ -1285,7 +1284,6 @@ test_nonce_tcp (void)
g_main_loop_quit (service_loop);
g_thread_join (service_thread);
}
#endif
static void
test_credentials (void)
@@ -1438,6 +1436,95 @@ test_overflow (void)
/* ---------------------------------------------------------------------------------------------------- */
static gboolean
tcp_anonymous_on_new_connection (GDBusServer *server,
GDBusConnection *connection,
gpointer user_data)
{
gboolean *seen_connection = user_data;
*seen_connection = TRUE;
return TRUE;
}
static gpointer
tcp_anonymous_service_thread_func (gpointer user_data)
{
gboolean *seen_connection = user_data;
GMainContext *service_context;
GError *error;
service_context = g_main_context_new ();
g_main_context_push_thread_default (service_context);
error = NULL;
server = g_dbus_server_new_sync ("tcp:",
G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
test_guid,
NULL, /* GDBusObserver* */
NULL, /* GCancellable* */
&error);
g_assert_no_error (error);
g_signal_connect (server,
"new-connection",
G_CALLBACK (tcp_anonymous_on_new_connection),
seen_connection);
g_dbus_server_start (server);
service_loop = g_main_loop_new (service_context, FALSE);
g_main_loop_run (service_loop);
g_main_context_pop_thread_default (service_context);
g_main_loop_unref (service_loop);
g_main_context_unref (service_context);
return NULL;
}
static void
test_tcp_anonymous (void)
{
gboolean seen_connection;
GThread *service_thread;
GDBusConnection *connection;
GError *error;
seen_connection = FALSE;
service_loop = NULL;
service_thread = g_thread_create (tcp_anonymous_service_thread_func,
&seen_connection, /* user_data */
TRUE, /* joinable */
&error);
while (service_loop == NULL)
g_thread_yield ();
g_assert (server != NULL);
error = NULL;
connection = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
NULL, /* GDBusAuthObserver* */
NULL, /* GCancellable */
&error);
g_assert_no_error (error);
g_assert (connection != NULL);
while (!seen_connection)
g_thread_yield ();
g_object_unref (connection);
g_main_loop_quit (service_loop);
g_dbus_server_stop (server);
g_object_unref (server);
server = NULL;
g_thread_join (service_thread);
}
/* ---------------------------------------------------------------------------------------------------- */
int
main (int argc,
char *argv[])
@@ -1460,9 +1547,8 @@ main (int argc,
g_test_add_func ("/gdbus/peer-to-peer", test_peer);
g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing);
#ifdef BUG_631379_FIXED
g_test_add_func ("/gdbus/nonce-tcp", test_nonce_tcp);
#endif
g_test_add_func ("/gdbus/tcp-anonymous", test_tcp_anonymous);
g_test_add_func ("/gdbus/credentials", test_credentials);
g_test_add_func ("/gdbus/overflow", test_overflow);

View File

@@ -735,16 +735,31 @@ message_serialize_complex (void)
/* ---------------------------------------------------------------------------------------------------- */
static void
replace (char *blob,
gsize len,
const char *before,
const char *after)
{
gsize i;
gsize slen = strlen (before) + 1;
g_assert_cmpuint (strlen (before), ==, strlen (after));
g_assert_cmpuint (len, >=, slen);
for (i = 0; i < (len - slen + 1); i++)
{
if (memcmp (blob + i, before, slen) == 0)
memcpy (blob + i, after, slen);
}
}
static void
message_serialize_invalid (void)
{
guint n;
/* Here we're relying on libdbus-1's DBusMessage type not checking
* anything. If that were to change, we'd need to do our own
* thing.
*
* Other things we could check (note that GDBus _does_ check for all
/* Other things we could check (note that GDBus _does_ check for all
* these things - we just don't have test-suit coverage for it)
*
* - array exceeding 64 MiB (2^26 bytes) - unfortunately libdbus-1 checks
@@ -769,9 +784,13 @@ message_serialize_invalid (void)
DBusMessage *dbus_message;
char *blob;
int blob_len;
/* these are in pairs with matching length */
const gchar *valid_utf8_str = "this is valid...";
const gchar *invalid_utf8_str = "this is invalid\xff";
const gchar *invalid_object_path = "/this/is/not a valid object path";
const gchar *valid_signature = "a{sv}a{sv}a{sv}aiai";
const gchar *invalid_signature = "not valid signature";
const gchar *valid_object_path = "/this/is/a/valid/dbus/object/path";
const gchar *invalid_object_path = "/this/is/not a valid object path!";
dbus_message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
dbus_message_set_serial (dbus_message, 0x41);
@@ -782,21 +801,21 @@ message_serialize_invalid (void)
case 0:
/* invalid UTF-8 */
dbus_message_append_args (dbus_message,
DBUS_TYPE_STRING, &invalid_utf8_str,
DBUS_TYPE_STRING, &valid_utf8_str,
DBUS_TYPE_INVALID);
break;
case 1:
/* invalid object path */
dbus_message_append_args (dbus_message,
DBUS_TYPE_OBJECT_PATH, &invalid_object_path,
DBUS_TYPE_OBJECT_PATH, &valid_object_path,
DBUS_TYPE_INVALID);
break;
case 2:
/* invalid signature */
dbus_message_append_args (dbus_message,
DBUS_TYPE_SIGNATURE, &invalid_signature,
DBUS_TYPE_SIGNATURE, &valid_signature,
DBUS_TYPE_INVALID);
break;
@@ -805,6 +824,11 @@ message_serialize_invalid (void)
break;
}
dbus_message_marshal (dbus_message, &blob, &blob_len);
/* hack up the message to be invalid by replacing each valid string
* with its invalid counterpart */
replace (blob, blob_len, valid_utf8_str, invalid_utf8_str);
replace (blob, blob_len, valid_object_path, invalid_object_path);
replace (blob, blob_len, valid_signature, invalid_signature);
error = NULL;
message = g_dbus_message_new_from_blob ((guchar *) blob,

View File

@@ -278,7 +278,7 @@ use_inet_address (gboolean synchronous)
{
GSocketAddressEnumerator *enumerator;
GSocketAddress *sockaddr;
GInetAddress *addr;
GInetAddress *addr = NULL;
guint port = 0;
gchar **ip_and_port;