[gnome-session] gsm-dbus-client: port to GDBus
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-session] gsm-dbus-client: port to GDBus
- Date: Fri, 12 Dec 2014 15:15:56 +0000 (UTC)
commit 96ce81a479cbd7f8c42c34b9eef7b05913844726
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Sat Oct 25 17:12:45 2014 -0700
gsm-dbus-client: port to GDBus
https://bugzilla.gnome.org/show_bug.cgi?id=622924
gnome-session/Makefile.am | 11 +
gnome-session/gsm-dbus-client.c | 488 +++++++++------------------------------
gnome-session/gsm-dbus-client.h | 14 --
3 files changed, 118 insertions(+), 395 deletions(-)
---
diff --git a/gnome-session/Makefile.am b/gnome-session/Makefile.am
index 725ea99..c6c1c9e 100644
--- a/gnome-session/Makefile.am
+++ b/gnome-session/Makefile.am
@@ -144,6 +144,15 @@ org.gnome.SessionManager.Client.h: org.gnome.SessionManager.Client.xml Makefile.
org.gnome.SessionManager.Client.c: org.gnome.SessionManager.Client.h
@: # generated as a side-effect
+org.gnome.SessionManager.ClientPrivate.h: org.gnome.SessionManager.ClientPrivate.xml Makefile.am
+ $(AM_V_GEN) gdbus-codegen --interface-prefix org.gnome.SessionManager.ClientPrivate. \
+ --generate-c-code org.gnome.SessionManager.ClientPrivate \
+ --c-namespace Gsm \
+ --annotate "org.gnome.SessionManager.ClientPrivate" "org.gtk.GDBus.C.Name" ExportedClientPrivate \
+ $(srcdir)/org.gnome.SessionManager.ClientPrivate.xml
+org.gnome.SessionManager.ClientPrivate.c: org.gnome.SessionManager.ClientPrivate.h
+ @: # generated as a side-effect
+
gsm-app-glue.h: org.gnome.SessionManager.App.xml Makefile.am
$(AM_V_GEN)dbus-binding-tool --prefix=gsm_app --mode=glib-server --output=gsm-app-glue.h
$(srcdir)/org.gnome.SessionManager.App.xml
@@ -156,6 +165,8 @@ gsm-presence-glue.h: org.gnome.SessionManager.Presence.xml Makefile.am
BUILT_SOURCES = \
org.gnome.SessionManager.Client.h \
org.gnome.SessionManager.Client.c \
+ org.gnome.SessionManager.ClientPrivate.h \
+ org.gnome.SessionManager.ClientPrivate.c \
org.gnome.SessionManager.h \
org.gnome.SessionManager.c \
gsm-presence-glue.h \
diff --git a/gnome-session/gsm-dbus-client.c b/gnome-session/gsm-dbus-client.c
index fdd43d2..e4609d5 100644
--- a/gnome-session/gsm-dbus-client.c
+++ b/gnome-session/gsm-dbus-client.c
@@ -25,11 +25,9 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <gio/gio.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
+#include "org.gnome.SessionManager.ClientPrivate.h"
#include "gsm-dbus-client.h"
#include "gsm-manager.h"
@@ -46,7 +44,9 @@ struct GsmDBusClientPrivate
char *bus_name;
GPid caller_pid;
GsmClientRestartStyle restart_style_hint;
- DBusConnection *connection;
+
+ GDBusConnection *connection;
+ GsmExportedClientPrivate *skeleton;
};
enum {
@@ -56,182 +56,36 @@ enum {
G_DEFINE_TYPE (GsmDBusClient, gsm_dbus_client, GSM_TYPE_CLIENT)
-GQuark
-gsm_dbus_client_error_quark (void)
-{
- static GQuark ret = 0;
- if (ret == 0) {
- ret = g_quark_from_static_string ("gsm_dbus_client_error");
- }
-
- return ret;
-}
-
-#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
-
-GType
-gsm_dbus_client_error_get_type (void)
-{
- static GType etype = 0;
-
- if (etype == 0) {
- static const GEnumValue values[] = {
- ENUM_ENTRY (GSM_DBUS_CLIENT_ERROR_GENERAL, "GeneralError"),
- ENUM_ENTRY (GSM_DBUS_CLIENT_ERROR_NOT_CLIENT, "NotClient"),
- { 0, 0, 0 }
- };
-
- g_assert (GSM_DBUS_CLIENT_NUM_ERRORS == G_N_ELEMENTS (values) - 1);
-
- etype = g_enum_register_static ("GsmDbusClientError", values);
- }
-
- return etype;
-}
-
static gboolean
setup_connection (GsmDBusClient *client)
{
- DBusError error;
-
- dbus_error_init (&error);
+ GError *error = NULL;
if (client->priv->connection == NULL) {
- client->priv->connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
- if (client->priv->connection == NULL) {
- if (dbus_error_is_set (&error)) {
- g_debug ("GsmDbusClient: Couldn't connect to session bus: %s",
- error.message);
- dbus_error_free (&error);
- }
+ client->priv->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+ if (error != NULL) {
+ g_debug ("GsmDbusClient: Couldn't connect to session bus: %s",
+ error->message);
+ g_error_free (error);
return FALSE;
}
-
- dbus_connection_setup_with_g_main (client->priv->connection, NULL);
- dbus_connection_set_exit_on_disconnect (client->priv->connection, FALSE);
}
return TRUE;
}
static void
-raise_error (DBusConnection *connection,
- DBusMessage *in_reply_to,
- const char *error_name,
- char *format, ...) G_GNUC_PRINTF (4, 5);
-
-static void
-raise_error (DBusConnection *connection,
- DBusMessage *in_reply_to,
- const char *error_name,
- char *format, ...)
-{
- char buf[512];
- DBusMessage *reply;
-
- va_list args;
- va_start (args, format);
- vsnprintf (buf, sizeof (buf), format, args);
- va_end (args);
-
- reply = dbus_message_new_error (in_reply_to, error_name, buf);
- if (reply == NULL) {
- g_error ("No memory");
- }
- if (! dbus_connection_send (connection, reply, NULL)) {
- g_error ("No memory");
- }
-
- dbus_message_unref (reply);
-}
-
-static void
-handle_end_session_response (GsmDBusClient *client,
- DBusMessage *message)
+handle_end_session_response (GsmExportedClientPrivate *skeleton,
+ GDBusMethodInvocation *invocation,
+ gboolean is_ok,
+ const char *reason,
+ GsmDBusClient *client)
{
- const char *sender;
- DBusMessage *reply;
- DBusError error;
- dbus_bool_t is_ok;
- const char *reason;
-
- dbus_error_init (&error);
- if (! dbus_message_get_args (message, &error,
- DBUS_TYPE_BOOLEAN, &is_ok,
- DBUS_TYPE_STRING, &reason,
- DBUS_TYPE_INVALID)) {
- if (dbus_error_is_set (&error)) {
- g_warning ("Invalid method call: %s", error.message);
- dbus_error_free (&error);
- }
- raise_error (client->priv->connection,
- message,
- DBUS_ERROR_FAILED,
- "There is a syntax error in the invocation of the method EndSessionResponse");
- return;
- }
-
g_debug ("GsmDBusClient: got EndSessionResponse is-ok:%d reason=%s", is_ok, reason);
-
- /* make sure it is from our client */
- sender = dbus_message_get_sender (message);
- if (sender == NULL
- || IS_STRING_EMPTY (client->priv->bus_name)
- || strcmp (sender, client->priv->bus_name) != 0) {
-
- raise_error (client->priv->connection,
- message,
- DBUS_ERROR_FAILED,
- "Caller not recognized as the client");
- return;
- }
-
- reply = dbus_message_new_method_return (message);
- if (reply == NULL) {
- g_error ("No memory");
- }
-
gsm_client_end_session_response (GSM_CLIENT (client),
is_ok, FALSE, FALSE, reason);
-
- if (! dbus_connection_send (client->priv->connection, reply, NULL)) {
- g_error ("No memory");
- }
-
- dbus_message_unref (reply);
-}
-
-static DBusHandlerResult
-client_dbus_filter_function (DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- GsmDBusClient *client = GSM_DBUS_CLIENT (user_data);
- const char *path;
-
- g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
- g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
-
- path = dbus_message_get_path (message);
-
- g_debug ("GsmDBusClient: obj_path=%s interface=%s method=%s",
- dbus_message_get_path (message),
- dbus_message_get_interface (message),
- dbus_message_get_member (message));
-
- if (dbus_message_is_method_call (message, SM_DBUS_CLIENT_PRIVATE_INTERFACE, "EndSessionResponse")) {
- g_assert (gsm_client_peek_id (GSM_CLIENT (client)) != NULL);
-
- if (path != NULL && strcmp (path, gsm_client_peek_id (GSM_CLIENT (client))) != 0) {
- /* Different object path */
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
- handle_end_session_response (client, message);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ gsm_exported_client_private_complete_end_session_response (skeleton, invocation);
}
static GObject *
@@ -240,6 +94,8 @@ gsm_dbus_client_constructor (GType type,
GObjectConstructParam *construct_properties)
{
GsmDBusClient *client;
+ GError *error = NULL;
+ GsmExportedClientPrivate *skeleton;
client = GSM_DBUS_CLIENT (G_OBJECT_CLASS (gsm_dbus_client_parent_class)->constructor (type,
n_construct_properties,
@@ -250,8 +106,23 @@ gsm_dbus_client_constructor (GType type,
return NULL;
}
- /* Object path is already registered by base class */
- dbus_connection_add_filter (client->priv->connection, client_dbus_filter_function, client, NULL);
+ skeleton = gsm_exported_client_private_skeleton_new ();
+ client->priv->skeleton = skeleton;
+ g_debug ("exporting dbus client to object path: %s", gsm_client_peek_id (GSM_CLIENT (client)));
+ g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton),
+ client->priv->connection,
+ gsm_client_peek_id (GSM_CLIENT (client)),
+ &error);
+
+ if (error != NULL) {
+ g_critical ("error exporting client private on session bus: %s", error->message);
+ g_error_free (error);
+ g_object_unref (client);
+ return NULL;
+ }
+
+ g_signal_connect (skeleton, "handle-end-session-response",
+ G_CALLBACK (handle_end_session_response), client);
return G_OBJECT (client);
}
@@ -266,77 +137,91 @@ gsm_dbus_client_init (GsmDBusClient *client)
static gboolean
get_caller_info (GsmDBusClient *client,
const char *sender,
- uid_t *calling_uid,
- pid_t *calling_pid)
+ uid_t *calling_uid_out,
+ pid_t *calling_pid_out)
{
- gboolean res;
+ GDBusConnection *connection;
+ gboolean retval;
GError *error;
- DBusGConnection *connection;
- DBusGProxy *bus_proxy;
+ GVariant *uid_variant, *pid_variant;
+ uid_t uid;
+ pid_t pid;
- res = FALSE;
- bus_proxy = NULL;
+ retval = FALSE;
if (sender == NULL) {
goto out;
}
error = NULL;
- connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
- if (connection == NULL) {
- if (error != NULL) {
- g_warning ("error getting session bus: %s", error->message);
- g_error_free (error);
- }
+ uid_variant = pid_variant = NULL;
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+
+ if (error != NULL) {
+ g_warning ("error getting session bus: %s", error->message);
+ g_error_free (error);
goto out;
}
- bus_proxy = dbus_g_proxy_new_for_name (connection,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS);
+ uid_variant = g_dbus_connection_call_sync (connection,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixUser",
+ g_variant_new ("(s)", sender),
+ G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &error);
- error = NULL;
- if (! dbus_g_proxy_call (bus_proxy, "GetConnectionUnixUser", &error,
- G_TYPE_STRING, sender,
- G_TYPE_INVALID,
- G_TYPE_UINT, calling_uid,
- G_TYPE_INVALID)) {
+ if (error != NULL) {
g_debug ("GetConnectionUnixUser() failed: %s", error->message);
g_error_free (error);
goto out;
}
- error = NULL;
- if (! dbus_g_proxy_call (bus_proxy, "GetConnectionUnixProcessID", &error,
- G_TYPE_STRING, sender,
- G_TYPE_INVALID,
- G_TYPE_UINT, calling_pid,
- G_TYPE_INVALID)) {
+ pid_variant = g_dbus_connection_call_sync (connection,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID",
+ g_variant_new ("(s)", sender),
+ G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &error);
+
+ if (error != NULL) {
g_debug ("GetConnectionUnixProcessID() failed: %s", error->message);
g_error_free (error);
goto out;
}
- res = TRUE;
+ g_variant_get (uid_variant, "(u)", &uid);
+ g_variant_get (pid_variant, "(u)", &pid);
- g_debug ("uid = %d", *calling_uid);
- g_debug ("pid = %d", *calling_pid);
+ if (calling_uid_out != NULL) {
+ *calling_uid_out = uid;
+ }
+ if (calling_pid_out != NULL) {
+ *calling_pid_out = pid;
+ }
+
+ retval = TRUE;
+
+ g_debug ("uid = %d", uid);
+ g_debug ("pid = %d", pid);
out:
- if (bus_proxy != NULL) {
- g_object_unref (bus_proxy);
- }
- return res;
+ g_clear_pointer (&uid_variant, (GDestroyNotify) g_variant_unref);
+ g_clear_pointer (&pid_variant, (GDestroyNotify) g_variant_unref);
+ g_clear_object (&connection);
+
+ return retval;
}
static void
gsm_dbus_client_set_bus_name (GsmDBusClient *client,
const char *bus_name)
{
- uid_t uid;
- pid_t pid;
-
g_return_if_fail (GSM_IS_DBUS_CLIENT (client));
g_free (client->priv->bus_name);
@@ -344,17 +229,9 @@ gsm_dbus_client_set_bus_name (GsmDBusClient *client,
client->priv->bus_name = g_strdup (bus_name);
g_object_notify (G_OBJECT (client), "bus-name");
- if (client->priv->bus_name != NULL) {
- gboolean res;
-
- res = get_caller_info (client, bus_name, &uid, &pid);
- if (! res) {
- pid = 0;
- }
- } else {
- pid = 0;
+ if (!get_caller_info (client, bus_name, NULL, &client->priv->caller_pid)) {
+ client->priv->caller_pid = 0;
}
- client->priv->caller_pid = pid;
}
const char *
@@ -412,6 +289,14 @@ gsm_dbus_client_finalize (GObject *object)
g_free (client->priv->bus_name);
+ if (client->priv->skeleton != NULL) {
+ g_dbus_interface_skeleton_unexport_from_connection (G_DBUS_INTERFACE_SKELETON
(client->priv->skeleton),
+ client->priv->connection);
+ g_clear_object (&client->priv->skeleton);
+ }
+
+ g_clear_object (&client->priv->connection);
+
G_OBJECT_CLASS (gsm_dbus_client_parent_class)->finalize (object);
}
@@ -433,34 +318,8 @@ dbus_client_stop (GsmClient *client,
GError **error)
{
GsmDBusClient *dbus_client = (GsmDBusClient *) client;
- DBusMessage *message;
- gboolean ret;
-
- ret = FALSE;
-
- /* unicast the signal to only the registered bus name */
- message = dbus_message_new_signal (gsm_client_peek_id (client),
- SM_DBUS_CLIENT_PRIVATE_INTERFACE,
- "Stop");
- if (message == NULL) {
- goto out;
- }
- if (!dbus_message_set_destination (message, dbus_client->priv->bus_name)) {
- goto out;
- }
-
- if (!dbus_connection_send (dbus_client->priv->connection, message, NULL)) {
- goto out;
- }
-
- ret = TRUE;
-
- out:
- if (message != NULL) {
- dbus_message_unref (message);
- }
-
- return ret;
+ gsm_exported_client_private_emit_stop (dbus_client->priv->skeleton);
+ return TRUE;
}
static char *
@@ -488,11 +347,6 @@ dbus_client_query_end_session (GsmClient *client,
GError **error)
{
GsmDBusClient *dbus_client = (GsmDBusClient *) client;
- DBusMessage *message;
- DBusMessageIter iter;
- gboolean ret;
-
- ret = FALSE;
if (dbus_client->priv->bus_name == NULL) {
g_set_error (error,
@@ -504,44 +358,8 @@ dbus_client_query_end_session (GsmClient *client,
g_debug ("GsmDBusClient: sending QueryEndSession signal to %s", dbus_client->priv->bus_name);
- /* unicast the signal to only the registered bus name */
- message = dbus_message_new_signal (gsm_client_peek_id (client),
- SM_DBUS_CLIENT_PRIVATE_INTERFACE,
- "QueryEndSession");
- if (message == NULL) {
- g_set_error (error,
- GSM_CLIENT_ERROR,
- GSM_CLIENT_ERROR_NOT_REGISTERED,
- "Unable to send QueryEndSession message");
- goto out;
- }
- if (!dbus_message_set_destination (message, dbus_client->priv->bus_name)) {
- g_set_error (error,
- GSM_CLIENT_ERROR,
- GSM_CLIENT_ERROR_NOT_REGISTERED,
- "Unable to send QueryEndSession message");
- goto out;
- }
-
- dbus_message_iter_init_append (message, &iter);
- dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &flags);
-
- if (!dbus_connection_send (dbus_client->priv->connection, message, NULL)) {
- g_set_error (error,
- GSM_CLIENT_ERROR,
- GSM_CLIENT_ERROR_NOT_REGISTERED,
- "Unable to send QueryEndSession message");
- goto out;
- }
-
- ret = TRUE;
-
- out:
- if (message != NULL) {
- dbus_message_unref (message);
- }
-
- return ret;
+ gsm_exported_client_private_emit_query_end_session (dbus_client->priv->skeleton, flags);
+ return TRUE;
}
static gboolean
@@ -550,49 +368,9 @@ dbus_client_end_session (GsmClient *client,
GError **error)
{
GsmDBusClient *dbus_client = (GsmDBusClient *) client;
- DBusMessage *message;
- DBusMessageIter iter;
- gboolean ret;
-
- ret = FALSE;
-
- /* unicast the signal to only the registered bus name */
- message = dbus_message_new_signal (gsm_client_peek_id (client),
- SM_DBUS_CLIENT_PRIVATE_INTERFACE,
- "EndSession");
- if (message == NULL) {
- g_set_error (error,
- GSM_CLIENT_ERROR,
- GSM_CLIENT_ERROR_NOT_REGISTERED,
- "Unable to send EndSession message");
- goto out;
- }
- if (!dbus_message_set_destination (message, dbus_client->priv->bus_name)) {
- g_set_error (error,
- GSM_CLIENT_ERROR,
- GSM_CLIENT_ERROR_NOT_REGISTERED,
- "Unable to send EndSession message");
- goto out;
- }
-
- dbus_message_iter_init_append (message, &iter);
- dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &flags);
- if (!dbus_connection_send (dbus_client->priv->connection, message, NULL)) {
- g_set_error (error,
- GSM_CLIENT_ERROR,
- GSM_CLIENT_ERROR_NOT_REGISTERED,
- "Unable to send EndSession message");
- goto out;
- }
-
- ret = TRUE;
-
- out:
- if (message != NULL) {
- dbus_message_unref (message);
- }
- return ret;
+ gsm_exported_client_private_emit_end_session (dbus_client->priv->skeleton, flags);
+ return TRUE;
}
static gboolean
@@ -600,59 +378,8 @@ dbus_client_cancel_end_session (GsmClient *client,
GError **error)
{
GsmDBusClient *dbus_client = (GsmDBusClient *) client;
- DBusMessage *message;
- gboolean ret = FALSE;
-
- /* unicast the signal to only the registered bus name */
- message = dbus_message_new_signal (gsm_client_peek_id (client),
- SM_DBUS_CLIENT_PRIVATE_INTERFACE,
- "CancelEndSession");
- if (message == NULL) {
- g_set_error (error,
- GSM_CLIENT_ERROR,
- GSM_CLIENT_ERROR_NOT_REGISTERED,
- "Unable to send CancelEndSession message");
- goto out;
- }
- if (!dbus_message_set_destination (message, dbus_client->priv->bus_name)) {
- g_set_error (error,
- GSM_CLIENT_ERROR,
- GSM_CLIENT_ERROR_NOT_REGISTERED,
- "Unable to send CancelEndSession message");
- goto out;
- }
-
- if (!dbus_connection_send (dbus_client->priv->connection, message, NULL)) {
- g_set_error (error,
- GSM_CLIENT_ERROR,
- GSM_CLIENT_ERROR_NOT_REGISTERED,
- "Unable to send CancelEndSession message");
- goto out;
- }
-
- ret = TRUE;
-
- out:
- if (message != NULL) {
- dbus_message_unref (message);
- }
-
- return ret;
-}
-
-static void
-gsm_dbus_client_dispose (GObject *object)
-{
- GsmDBusClient *client;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GSM_IS_DBUS_CLIENT (object));
-
- client = GSM_DBUS_CLIENT (object);
-
- dbus_connection_remove_filter (client->priv->connection, client_dbus_filter_function, client);
-
- G_OBJECT_CLASS (gsm_dbus_client_parent_class)->dispose (object);
+ gsm_exported_client_private_emit_cancel_end_session (dbus_client->priv->skeleton);
+ return TRUE;
}
static void
@@ -665,7 +392,6 @@ gsm_dbus_client_class_init (GsmDBusClientClass *klass)
object_class->constructor = gsm_dbus_client_constructor;
object_class->get_property = gsm_dbus_client_get_property;
object_class->set_property = gsm_dbus_client_set_property;
- object_class->dispose = gsm_dbus_client_dispose;
client_class->impl_save = dbus_client_save;
client_class->impl_stop = dbus_client_stop;
diff --git a/gnome-session/gsm-dbus-client.h b/gnome-session/gsm-dbus-client.h
index ba34574..10c5057 100644
--- a/gnome-session/gsm-dbus-client.h
+++ b/gnome-session/gsm-dbus-client.h
@@ -46,20 +46,6 @@ struct _GsmDBusClientClass
GsmClientClass parent_class;
};
-typedef enum
-{
- GSM_DBUS_CLIENT_ERROR_GENERAL = 0,
- GSM_DBUS_CLIENT_ERROR_NOT_CLIENT,
- GSM_DBUS_CLIENT_NUM_ERRORS
-} GsmDBusClientError;
-
-#define GSM_DBUS_CLIENT_ERROR gsm_dbus_client_error_quark ()
-
-GType gsm_dbus_client_error_get_type (void);
-#define GSM_DBUS_CLIENT_TYPE_ERROR (gsm_dbus_client_error_get_type ())
-
-GQuark gsm_dbus_client_error_quark (void);
-
GType gsm_dbus_client_get_type (void) G_GNUC_CONST;
GsmClient * gsm_dbus_client_new (const char *startup_id,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]