From 2ab7ad075cb00443065ad08e09980fb5f96ed074 Mon Sep 17 00:00:00 2001 From: Robert Roth Date: Mon, 2 Sep 2013 02:55:31 +0300 Subject: Added initial almost-empty implementation of dbus service --- .gitignore | 3 + Makefile.am | 2 +- configure.ac | 10 ++- service/Makefile.am | 8 ++ service/gtop-dbus-service.c | 207 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+), 2 deletions(-) create mode 100644 service/Makefile.am create mode 100644 service/gtop-dbus-service.c diff --git a/.gitignore b/.gitignore index f0b17042..98f3a934 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +service/*.o +service/.deps +service/gtop-dbus-service sysdeps/Makefile sysdeps/Makefile.in sysdeps/*/Makefile diff --git a/Makefile.am b/Makefile.am index eca41ffd..1e6a3340 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ else EXAMPLES_DIR = endif -SUBDIRS = po misc include sysdeps lib src $(EXAMPLES_DIR) doc +SUBDIRS = po misc include sysdeps lib src $(EXAMPLES_DIR) doc service libgtopinclude_HEADERS = glibtop.h libgtopconfig.h libgtopincludedir = $(includedir)/libgtop-2.0 diff --git a/configure.ac b/configure.ac index dc4e6543..b6cf7a40 100644 --- a/configure.ac +++ b/configure.ac @@ -226,7 +226,7 @@ GLIB_DEFINE_LOCALEDIR([GTOPLOCALEDIR]) AC_PATH_XTRA dnl For Solaris -dnl Please don't move this before AC_PATH_XTRA +dnl Please don\'t move this before AC_PATH_XTRA AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)]) AC_CHECK_FUNC(connect,,[AC_CHECK_LIB(socket,connect)]) AC_CHECK_FUNC(inet_aton,,[AC_CHECK_LIB(resolv,inet_aton)]) @@ -364,12 +364,20 @@ AC_SUBST(sysdeps_suid_lib) AC_SUBST(server_programs) GTK_DOC_CHECK(1.4) +GLIB_REQUIRED=2.37.3 + +PKG_CHECK_MODULES(GTOP_DBUS, + glib-2.0 >= $GLIB_REQUIRED + gio-2.0 >= $GLIB_REQUIRED + gio-unix-2.0 >= $GLIB_REQUIRED +) AC_CONFIG_FILES([ Makefile libgtop.spec po/Makefile.in misc/Makefile +service/Makefile include/Makefile include/glibtop/Makefile sysdeps/Makefile diff --git a/service/Makefile.am b/service/Makefile.am new file mode 100644 index 00000000..5277f35c --- /dev/null +++ b/service/Makefile.am @@ -0,0 +1,8 @@ +LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(AM_LDFLAGS) -o $@ + +noinst_PROGRAMS = gtop-dbus-service + +AM_CPPFLAGS= ${GTOP_DBUS_CFLAGS} + +gtop_dbus_service_SOURCES = gtop-dbus-service.c +gtop_dbus_service_LDADD = $(GTOP_DBUS_LIBS) diff --git a/service/gtop-dbus-service.c b/service/gtop-dbus-service.c new file mode 100644 index 00000000..e6909192 --- /dev/null +++ b/service/gtop-dbus-service.c @@ -0,0 +1,207 @@ +#include +#include +#include +#include + +#define MSG_PREFIX "[libgtop dbus server] " + +static const gchar service[] = "org.gnome.gtopServer"; + +static const gchar object_name[] = "/org/gnome/gtopServer"; +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusNodeInfo *introspection_data = NULL; + +/* Introspection data for the service we are exporting */ +static const gchar introspection_xml[] = + "" + " " + " " + " " + ""; + +/** + * Handle a call to a method. (Parameters should be obvious.) + */ +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) +{ +#ifdef VERBOSE + gchar *paramstr = g_variant_print (parameters, TRUE); + fprintf (stderr, "[server 0] " + "handle_method_call (%p,\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",(invocation),%p)\n", + connection, sender, object_path, interface_name, method_name, + paramstr, user_data); + g_free (paramstr); +#endif + + // Default: No such method + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + MSG_PREFIX "Invalid method: '%s'", + method_name); +} // handle_method_call + +/** + * Handle a request to set a property. + */ +static gboolean +handle_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, + gpointer user_data) +{ + // Print an optional log message +#ifdef VERBOSE + gchar *valstr = g_variant_print (value, TRUE); + fprintf (stderr, MSG_PREFIX + "handle_set_property (%p,\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",(error),%p)\n", + connection, sender, object_path, interface_name, property_name, + valstr, user_data); + g_free (valstr); +#endif + + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + MSG_PREFIX "No such property: '%s'", + property_name); + return 0; +} // handle_set_property + +/** + * Handle a request for a property. (Parameters should be obvious.) + */ +static GVariant * +handle_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + // Print an optional log message +#ifdef VERBOSE + fprintf (stderr, MSG_PREFIX + "handle_get_property (%p,\"%s\",\"%s\",\"%s\",\"%s\",(error),%p)\n", + connection, sender, object_path, interface_name, property_name, + user_data); +#endif + + if (g_strcmp0 (property_name, "Version") == 0) + { + return g_variant_new_string (LIBGTOP_VERSION); + } + + // Anything else is an error. + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + MSG_PREFIX "Invalid property '%s'", + property_name); + return NULL; + } // unknown property +} // handle_get_property + +/** + * What to do when the bus gets acquired. + */ +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + static GDBusInterfaceVTable interface_vtable = + { + handle_method_call, + handle_get_property, + handle_set_property + }; + + guint registration_id; + GError *error = NULL; + + // A bit of (optional) notification +#ifdef VERBOSE + fprintf (stderr, MSG_PREFIX "on_bus_acquired (%p, \"%s\", %p)\n", + connection, name, user_data); +#endif + + registration_id = + g_dbus_connection_register_object (connection, + object_name, + introspection_data->interfaces[0], + &interface_vtable, + NULL, // Optional user data + NULL, // Func. for freeing user data + &error); + +} // on_bus_acquired + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + // A bit of (optional) notification +#ifdef VERBOSE + fprintf (stderr, MSG_PREFIX "on_name_acquired (%p, \"%s\", %p)\n", + connection, name, user_data); +#endif +} // on_name_acquired + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + // A bit of (optional) notification +#ifdef VERBOSE + fprintf (stderr, MSG_PREFIX "on_name_lost (%p, \"%s\", %p)\n", + connection, name, user_data); +#endif + // Things seem to have gone badly wrong, so give up + exit (1); +} // on_name_lost + +int main ( int argc, char ** argv ) { + guint owner_id; + GMainLoop *loop; + + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + + owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + service, + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + // Tell the bus that we're done with the name + g_bus_unown_name (owner_id); + + // Clean up after ourselves + g_dbus_node_info_unref (introspection_data); + + return 0; +} -- cgit v1.2.1