X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgdbusserver.c;h=cf821304cecf93ed9435023fb4b5334de91ccd5e;hb=f14a66e3df9e5e3f0f170b68e976011c80ffc041;hp=d957d225bee226ebb6ded9bb0165cd78eed0c21f;hpb=19972a1b57ef092067f001bb8d870fa552cc20a2;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c index d957d22..cf82130 100644 --- a/gio/gdbusserver.c +++ b/gio/gdbusserver.c @@ -13,9 +13,7 @@ * 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, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Author: David Zeuthen */ @@ -25,12 +23,6 @@ #include #include #include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef _WIN32 -#include -#endif #include "giotypes.h" #include "gioerror.h" @@ -41,17 +33,24 @@ #include "gioenumtypes.h" #include "gdbusprivate.h" #include "gdbusauthobserver.h" -#include "gio-marshal.h" #include "ginitable.h" #include "gsocketservice.h" #include "gthreadedsocketservice.h" #include "gresolver.h" +#include "glib/gstdio.h" #include "ginetaddress.h" #include "ginetsocketaddress.h" #include "ginputstream.h" #include "giostream.h" #ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include +#endif + +#ifdef G_OS_UNIX #include "gunixsocketaddress.h" #endif @@ -63,9 +62,16 @@ * @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(). * - * D-Bus peer-to-peer exampleFIXME: MISSING XINCLUDE CONTENT + * An example of peer-to-peer communication with G-DBus can be found + * in [gdbus-example-peer.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-peer.c). */ /** @@ -94,7 +100,7 @@ struct _GDBusServer gboolean is_using_listener; gulong run_signal_handler_id; - /* The result of g_main_context_get_thread_default() when the object + /* The result of g_main_context_ref_thread_default() when the object * was created (the GObject _init() function) - this is used for delivery * of the :new-connection GObject signal. */ @@ -122,8 +128,8 @@ struct _GDBusServerClass /*< public >*/ /* Signals */ - void (*new_connection) (GDBusServer *server, - GDBusConnection *connection); + gboolean (*new_connection) (GDBusServer *server, + GDBusConnection *connection); }; enum @@ -143,7 +149,7 @@ enum LAST_SIGNAL, }; -guint _signals[LAST_SIGNAL] = {0}; +static guint _signals[LAST_SIGNAL] = {0}; static void initable_iface_init (GInitableIface *initable_iface); @@ -178,8 +184,7 @@ g_dbus_server_finalize (GObject *object) */ g_free (server->nonce_file); - if (server->main_context_at_construction != NULL) - g_main_context_unref (server->main_context_at_construction); + g_main_context_unref (server->main_context_at_construction); G_OBJECT_CLASS (g_dbus_server_parent_class)->finalize (object); } @@ -391,32 +396,37 @@ g_dbus_server_class_init (GDBusServerClass *klass) * g_dbus_connection_get_peer_credentials() to figure out what * identity (if any), was authenticated. * - * If you want to accept the connection, simply ref the @connection - * object. Then call g_dbus_connection_close() and unref it when you - * are done with it. A typical thing to do when accepting a - * connection is to listen to the #GDBusConnection::closed signal. + * If you want to accept the connection, take a reference to the + * @connection object and return %TRUE. When you are done with the + * connection call g_dbus_connection_close() and give up your + * reference. Note that the other peer may disconnect at any time - + * a typical thing to do when accepting a connection is to listen to + * the #GDBusConnection::closed signal. * * If #GDBusServer:flags contains %G_DBUS_SERVER_FLAGS_RUN_IN_THREAD * then the signal is emitted in a new thread dedicated to the - * connection. Otherwise the signal is emitted in the thread-default main - * loop of the thread that @server was constructed in. + * connection. Otherwise the signal is emitted in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread that @server was constructed in. * * You are guaranteed that signal handlers for this signal runs * before incoming messages on @connection are processed. This means * that it's suitable to call g_dbus_connection_register_object() or * similar from the signal handler. * + * Returns: %TRUE to claim @connection, %FALSE to let other handlers + * run. + * * Since: 2.26 */ _signals[NEW_CONNECTION_SIGNAL] = g_signal_new ("new-connection", G_TYPE_DBUS_SERVER, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GDBusServerClass, new_connection), + g_signal_accumulator_true_handled, + NULL, /* accu_data */ NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, + G_TYPE_BOOLEAN, 1, G_TYPE_DBUS_CONNECTION); } @@ -424,9 +434,7 @@ g_dbus_server_class_init (GDBusServerClass *klass) static void g_dbus_server_init (GDBusServer *server) { - server->main_context_at_construction = g_main_context_get_thread_default (); - if (server->main_context_at_construction != NULL) - g_main_context_ref (server->main_context_at_construction); + server->main_context_at_construction = g_main_context_ref_thread_default (); } static gboolean @@ -440,8 +448,8 @@ on_run (GSocketService *service, * @address: A D-Bus address. * @flags: Flags from the #GDBusServerFlags enumeration. * @guid: A D-Bus GUID. - * @observer: A #GDBusAuthObserver or %NULL. - * @cancellable: A #GCancellable or %NULL. + * @observer: (allow-none): A #GDBusAuthObserver or %NULL. + * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for server or %NULL. * * Creates a new D-Bus server that listens on the first address in @@ -456,8 +464,7 @@ on_run (GSocketService *service, * The returned #GDBusServer isn't active - you have to start it with * g_dbus_server_start(). * - * See for how #GDBusServer can - * be used. + * #GDBusServer is used in this [example][gdbus-peer-to-peer]. * * This is a synchronous failable constructor. See * g_dbus_server_new() for the asynchronous version. @@ -489,15 +496,6 @@ g_dbus_server_new_sync (const gchar *address, "guid", guid, "authentication-observer", observer, NULL); - if (server != NULL) - { - /* Right now we don't have any transport not using the listener... */ - g_assert (server->is_using_listener); - server->run_signal_handler_id = g_signal_connect (G_SOCKET_SERVICE (server->listener), - "run", - G_CALLBACK (on_run), - server); - } return server; } @@ -765,7 +763,7 @@ try_unix (GDBusServer *server, /* ---------------------------------------------------------------------------------------------------- */ /* note that address_entry has already been validated => - * both host and port (guranteed to be a number in [0, 65535]) are set (family is optional) + * both host and port (guaranteed to be a number in [0, 65535]) are set (family is optional) */ static gboolean try_tcp (GDBusServer *server, @@ -777,21 +775,18 @@ try_tcp (GDBusServer *server, gboolean ret; const gchar *host; const gchar *port; - const gchar *family; gint port_num; - GSocketAddress *address; GResolver *resolver; GList *resolved_addresses; GList *l; ret = FALSE; - address = NULL; resolver = NULL; resolved_addresses = NULL; host = g_hash_table_lookup (key_value_pairs, "host"); port = g_hash_table_lookup (key_value_pairs, "port"); - family = g_hash_table_lookup (key_value_pairs, "family"); + /* family = g_hash_table_lookup (key_value_pairs, "family"); */ if (g_hash_table_lookup (key_value_pairs, "noncefile") != NULL) { g_set_error_literal (error, @@ -848,6 +843,7 @@ try_tcp (GDBusServer *server, guint n; gsize bytes_written; gsize bytes_remaining; + char *file_escaped; server->nonce = g_new0 (guchar, 16); for (n = 0; n < 16; n++) @@ -874,7 +870,7 @@ try_tcp (GDBusServer *server, g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - _("Error writing nonce file at `%s': %s"), + _("Error writing nonce file at '%s': %s"), server->nonce_file, strerror (errno)); goto out; @@ -882,11 +878,14 @@ try_tcp (GDBusServer *server, bytes_written += ret; bytes_remaining -= ret; } - close (fd); + if (!g_close (fd, error)) + goto out; + file_escaped = g_uri_escape_string (server->nonce_file, "/\\", FALSE); server->client_address = g_strdup_printf ("nonce-tcp:host=%s,port=%d,noncefile=%s", host, port_num, - server->nonce_file); + file_escaped); + g_free (file_escaped); } else { @@ -896,9 +895,9 @@ try_tcp (GDBusServer *server, ret = TRUE; out: - g_list_foreach (resolved_addresses, (GFunc) g_object_unref, NULL); - g_list_free (resolved_addresses); - g_object_unref (resolver); + g_list_free_full (resolved_addresses, g_object_unref); + if (resolver) + g_object_unref (resolver); return ret; } @@ -922,12 +921,17 @@ static gboolean emit_new_connection_in_idle (gpointer user_data) { EmitIdleData *data = user_data; + gboolean claimed; + claimed = FALSE; g_signal_emit (data->server, _signals[NEW_CONNECTION_SIGNAL], 0, - data->connection); - g_dbus_connection_start_message_processing (data->connection); + data->connection, + &claimed); + + if (claimed) + g_dbus_connection_start_message_processing (data->connection); g_object_unref (data->connection); return FALSE; @@ -981,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 @@ -1003,6 +1012,7 @@ on_run (GSocketService *service, emit_new_connection_in_idle, data, (GDestroyNotify) emit_idle_data_free); + g_source_set_name (idle_source, "[gio] emit_new_connection_in_idle"); g_source_attach (idle_source, server->main_context_at_construction); g_source_unref (idle_source); } @@ -1031,7 +1041,7 @@ initable_init (GInitable *initable, g_set_error (&last_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - _("The string `%s' is not a valid D-Bus GUID"), + _("The string '%s' is not a valid D-Bus GUID"), server->guid); goto out; } @@ -1071,7 +1081,7 @@ initable_init (GInitable *initable, g_set_error (&this_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - _("Cannot listen on unsupported transport `%s'"), + _("Cannot listen on unsupported transport '%s'"), transport_name); g_free (transport_name); @@ -1093,9 +1103,6 @@ initable_init (GInitable *initable, } } - if (!ret) - goto out; - out: g_strfreev (addr_array); @@ -1104,6 +1111,13 @@ initable_init (GInitable *initable, { if (last_error != NULL) g_error_free (last_error); + + /* Right now we don't have any transport not using the listener... */ + g_assert (server->is_using_listener); + server->run_signal_handler_id = g_signal_connect (G_SOCKET_SERVICE (server->listener), + "run", + G_CALLBACK (on_run), + server); } else {