| GIO Reference Manual | ||||
|---|---|---|---|---|
| Top | Description | Object Hierarchy | Implemented Interfaces | Properties | Signals | ||||
#include <gio/gio.h>
GDBusServer;
GDBusServerClass;
enum GDBusServerFlags;
GDBusServer * g_dbus_server_new_sync (const gchar *address,
GDBusServerFlags flags,
const gchar *guid,
GDBusAuthObserver *observer,
GCancellable *cancellable,
GError **error);
void g_dbus_server_start (GDBusServer *server);
void g_dbus_server_stop (GDBusServer *server);
gboolean g_dbus_server_is_active (GDBusServer *server);
const gchar * g_dbus_server_get_guid (GDBusServer *server);
GDBusServerFlags g_dbus_server_get_flags (GDBusServer *server);
const gchar * g_dbus_server_get_client_address (GDBusServer *server);
"active" gchar* : Read "address" gchar* : Read / Write / Construct Only "authentication-observer" GDBusAuthObserver* : Read / Write / Construct Only "client-address" gchar* : Read "flags" GDBusServerFlags : Read / Write / Construct Only "guid" gchar* : Read / Write / Construct Only
GDBusServer is a helper for listening to and accepting D-Bus connections.
Example 6. D-Bus peer-to-peer example
/*
Usage examples (modulo addresses / credentials).
UNIX domain socket transport:
Server:
$ ./gdbus-example-peer --server --address unix:abstract=myaddr
Server is listening at: unix:abstract=myaddr
Client connected.
Peer credentials: GCredentials:unix-user=500,unix-group=500,unix-process=13378
Negotiated capabilities: unix-fd-passing=1
Client said: Hey, it's 1273093080 already!
Client:
$ ./gdbus-example-peer --address unix:abstract=myaddr
Connected.
Negotiated capabilities: unix-fd-passing=1
Server said: You said 'Hey, it's 1273093080 already!'. KTHXBYE!
Nonce-secured TCP transport on the same host:
Server:
$ ./gdbus-example-peer --server --address nonce-tcp:
Server is listening at: nonce-tcp:host=localhost,port=43077,noncefile=/tmp/gdbus-nonce-file-X1ZNCV
Client connected.
Peer credentials: (no credentials received)
Negotiated capabilities: unix-fd-passing=0
Client said: Hey, it's 1273093206 already!
Client:
$ ./gdbus-example-peer -address nonce-tcp:host=localhost,port=43077,noncefile=/tmp/gdbus-nonce-file-X1ZNCV
Connected.
Negotiated capabilities: unix-fd-passing=0
Server said: You said 'Hey, it's 1273093206 already!'. KTHXBYE!
TCP transport on two different hosts with a shared home directory:
Server:
host1 $ ./gdbus-example-peer --server --address tcp:host=0.0.0.0
Server is listening at: tcp:host=0.0.0.0,port=46314
Client connected.
Peer credentials: (no credentials received)
Negotiated capabilities: unix-fd-passing=0
Client said: Hey, it's 1273093337 already!
Client:
host2 $ ./gdbus-example-peer -a tcp:host=host1,port=46314
Connected.
Negotiated capabilities: unix-fd-passing=0
Server said: You said 'Hey, it's 1273093337 already!'. KTHXBYE!
TCP transport on two different hosts without authentication:
Server:
host1 $ ./gdbus-example-peer --server --address tcp:host=0.0.0.0 --allow-anonymous
Server is listening at: tcp:host=0.0.0.0,port=59556
Client connected.
Peer credentials: (no credentials received)
Negotiated capabilities: unix-fd-passing=0
Client said: Hey, it's 1273093652 already!
Client:
host2 $ ./gdbus-example-peer -a tcp:host=host1,port=59556
Connected.
Negotiated capabilities: unix-fd-passing=0
Server said: You said 'Hey, it's 1273093652 already!'. KTHXBYE!
*/
#include <gio/gio.h>
#include <stdlib.h>
/* ---------------------------------------------------------------------------------------------------- */
static GDBusNodeInfo *introspection_data = NULL;
/* Introspection data for the service we are exporting */
static const gchar introspection_xml[] =
"<node>"
" <interface name='org.gtk.GDBus.TestPeerInterface'>"
" <method name='HelloWorld'>"
" <arg type='s' name='greeting' direction='in'/>"
" <arg type='s' name='response' direction='out'/>"
" </method>"
" </interface>"
"</node>";
/* ---------------------------------------------------------------------------------------------------- */
static void
handle_method_call (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
if (g_strcmp0 (method_name, "HelloWorld") == 0)
{
const gchar *greeting;
gchar *response;
g_variant_get (parameters, "(&s)", &greeting);
response = g_strdup_printf ("You said '%s'. KTHXBYE!", greeting);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(s)", response));
g_free (response);
g_print ("Client said: %s\n", greeting);
}
}
static const GDBusInterfaceVTable interface_vtable =
{
handle_method_call,
NULL,
NULL,
};
/* ---------------------------------------------------------------------------------------------------- */
static void
on_new_connection (GDBusServer *server,
GDBusConnection *connection,
gpointer user_data)
{
guint registration_id;
GCredentials *credentials;
gchar *s;
credentials = g_dbus_connection_get_peer_credentials (connection);
if (credentials == NULL)
s = g_strdup ("(no credentials received)");
else
s = g_credentials_to_string (credentials);
g_print ("Client connected.\n"
"Peer credentials: %s\n"
"Negotiated capabilities: unix-fd-passing=%d\n",
s,
g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
g_object_ref (connection);
registration_id = g_dbus_connection_register_object (connection,
"/org/gtk/GDBus/TestObject",
introspection_data->interfaces[0],
&interface_vtable,
NULL, /* user_data */
NULL, /* user_data_free_func */
NULL); /* GError** */
g_assert (registration_id > 0);
}
/* ---------------------------------------------------------------------------------------------------- */
int
main (int argc, char *argv[])
{
gint ret;
gboolean opt_server;
gchar *opt_address;
GOptionContext *opt_context;
gboolean opt_allow_anonymous;
GError *error;
GOptionEntry opt_entries[] =
{
{ "server", 's', 0, G_OPTION_ARG_NONE, &opt_server, "Start a server instead of a client", NULL },
{ "address", 'a', 0, G_OPTION_ARG_STRING, &opt_address, "D-Bus address to use", NULL },
{ "allow-anonymous", 'n', 0, G_OPTION_ARG_NONE, &opt_allow_anonymous, "Allow anonymous authentication", NULL },
{ NULL}
};
ret = 1;
g_type_init ();
opt_address = NULL;
opt_server = FALSE;
opt_allow_anonymous = FALSE;
opt_context = g_option_context_new ("peer-to-peer example");
error = NULL;
g_option_context_add_main_entries (opt_context, opt_entries, NULL);
if (!g_option_context_parse (opt_context, &argc, &argv, &error))
{
g_printerr ("Error parsing options: %s\n", error->message);
g_error_free (error);
goto out;
}
if (opt_address == NULL)
{
g_printerr ("Incorrect usage, try --help.\n");
goto out;
}
if (!opt_server && opt_allow_anonymous)
{
g_printerr ("The --allow-anonymous option only makes sense when used with --server.\n");
goto out;
}
/* We are lazy here - we don't want to manually provide
* the introspection data structures - so we just build
* them from XML.
*/
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
g_assert (introspection_data != NULL);
if (opt_server)
{
GDBusServer *server;
gchar *guid;
GMainLoop *loop;
GDBusServerFlags server_flags;
guid = g_dbus_generate_guid ();
server_flags = G_DBUS_SERVER_FLAGS_NONE;
if (opt_allow_anonymous)
server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
error = NULL;
server = g_dbus_server_new_sync (opt_address,
server_flags,
guid,
NULL, /* GDBusAuthObserver */
NULL, /* GCancellable */
&error);
g_dbus_server_start (server);
g_free (guid);
if (server == NULL)
{
g_printerr ("Error creating server at address %s: %s\n", opt_address, error->message);
g_error_free (error);
goto out;
}
g_print ("Server is listening at: %s\n", g_dbus_server_get_client_address (server));
g_signal_connect (server,
"new-connection",
G_CALLBACK (on_new_connection),
NULL);
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
g_object_unref (server);
g_main_loop_unref (loop);
}
else
{
GDBusConnection *connection;
const gchar *greeting_response;
GVariant *value;
gchar *greeting;
error = NULL;
connection = g_dbus_connection_new_for_address_sync (opt_address,
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
NULL, /* GDBusAuthObserver */
NULL, /* GCancellable */
&error);
if (connection == NULL)
{
g_printerr ("Error connecting to D-Bus address %s: %s\n", opt_address, error->message);
g_error_free (error);
goto out;
}
g_print ("Connected.\n"
"Negotiated capabilities: unix-fd-passing=%d\n",
g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
greeting = g_strdup_printf ("Hey, it's %" G_GUINT64_FORMAT " already!", (guint64) time (NULL));
value = g_dbus_connection_call_sync (connection,
NULL, /* bus_name */
"/org/gtk/GDBus/TestObject",
"org.gtk.GDBus.TestPeerInterface",
"HelloWorld",
g_variant_new ("(s)", greeting),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if (value == NULL)
{
g_printerr ("Error invoking HelloWorld(): %s\n", error->message);
g_error_free (error);
goto out;
}
g_variant_get (value, "(&s)", &greeting_response);
g_print ("Server said: %s\n", greeting_response);
g_variant_unref (value);
g_object_unref (connection);
}
g_dbus_node_info_unref (introspection_data);
ret = 0;
out:
return ret;
}
typedef struct _GDBusServer GDBusServer;
The GDBusServer structure contains only private data and should only be accessed using the provided API.
Since 2.26
typedef struct {
/* Signals */
void (*new_connection) (GDBusServer *server,
GDBusConnection *connection);
} GDBusServerClass;
Class structure for GDBusServer.
| Signal class handler for the "new-connection" signal. |
Since 2.26
typedef enum
{
G_DBUS_SERVER_FLAGS_NONE = 0,
G_DBUS_SERVER_FLAGS_RUN_IN_THREAD = (1<<0),
G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS = (1<<1)
} GDBusServerFlags;
Flags used when creating a GDBusServer.
| No flags set. | |
| All "new-connection" signals will run in separated dedicated threads (see signal for details). | |
| Allow the anonymous authentication method. |
Since 2.26
GDBusServer * g_dbus_server_new_sync (const gchar *address,GDBusServerFlags flags,const gchar *guid,GDBusAuthObserver *observer,GCancellable *cancellable,GError **error);
Creates a new D-Bus server that listens on the first address in
address that works.
Once constructed, you can use g_dbus_server_get_client_address() to
get a D-Bus address string that clients can use to connect.
Connect to the "new-connection" signal to handle incoming connections.
The returned GDBusServer isn't active - you have to start it with
g_dbus_server_start().
See Example 6, “D-Bus peer-to-peer example” for how GDBusServer can be used.
This is a synchronous failable constructor. See
g_dbus_server_new() for the asynchronous version.
|
A D-Bus address. |
|
Flags from the GDBusServerFlags enumeration. |
|
A D-Bus GUID. |
|
A GDBusAuthObserver or NULL.
|
|
A GCancellable or NULL.
|
|
Return location for server or NULL.
|
Returns : |
A GDBusServer or NULL if error is set. Free with
g_object_unref().
|
Since 2.26
void g_dbus_server_start (GDBusServer *server);
Starts server.
|
A GDBusServer. |
Since 2.26
void g_dbus_server_stop (GDBusServer *server);
Stops server.
|
A GDBusServer. |
Since 2.26
gboolean g_dbus_server_is_active (GDBusServer *server);
Gets whether server is active.
|
A GDBusServer. |
Returns : |
TRUE if server is active, FALSE otherwise.
|
Since 2.26
const gchar * g_dbus_server_get_guid (GDBusServer *server);
Gets the GUID for server.
|
A GDBusServer. |
Returns : |
A D-Bus GUID. Do not free this string, it is owned by server.
|
Since 2.26
GDBusServerFlags g_dbus_server_get_flags (GDBusServer *server);
Gets the flags for server.
|
A GDBusServer. |
Returns : |
A set of flags from the GDBusServerFlags enumeration. |
Since 2.26
const gchar * g_dbus_server_get_client_address (GDBusServer *server);
Gets a D-Bus address string that can be used by clients to connect
to server.
|
A GDBusServer. |
Returns : |
A D-Bus address string. Do not free, the string is owned
by server.
|
Since 2.26
"active" property"active" gchar* : Read
Whether the server is currently active.
Default value: NULL
Since 2.26
"address" property"address" gchar* : Read / Write / Construct Only
The D-Bus address to listen on.
Default value: NULL
Since 2.26
"authentication-observer" property"authentication-observer" GDBusAuthObserver* : Read / Write / Construct Only
A GDBusAuthObserver object to assist in the authentication process or NULL.
Since 2.26
"client-address" property"client-address" gchar* : Read
The D-Bus address that clients can use.
Default value: NULL
Since 2.26
"flags" property"flags" GDBusServerFlags : Read / Write / Construct Only
Flags from the GDBusServerFlags enumeration.
Since 2.26
"guid" property"guid" gchar* : Read / Write / Construct Only
The guid of the server.
Default value: NULL
Since 2.26
"new-connection" signalvoid user_function (GDBusServer *server, GDBusConnection *connection, gpointer user_data) : Run Last
Emitted when a new authenticated connection has been made. Use
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 "closed" signal.
If "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 server was constructed in.
|
The GDBusServer emitting the signal. |
|
A GDBusConnection for the new connection. |
|
user data set when the signal handler was connected. |
Since 2.26