diff --git a/pw3270-plugin-ipc.cbp b/pw3270-plugin-ipc.cbp index 8ff68d1..5a1d9f5 100644 --- a/pw3270-plugin-ipc.cbp +++ b/pw3270-plugin-ipc.cbp @@ -74,6 +74,9 @@ + + diff --git a/src/core/linux/gobject.c b/src/core/linux/gobject.c index fefb188..b4144ac 100644 --- a/src/core/linux/gobject.c +++ b/src/core/linux/gobject.c @@ -50,11 +50,7 @@ static void ipc3270_finalize(GObject *object) { debug("ipc3270::%s(%p)",__FUNCTION__,object); - ipc3270 * ipc = IPC3270(object); - - if(ipc->id) { - g_dbus_connection_unregister_object(ipc->connection,ipc->id); - } + ipc3270_release_object(IPC3270(object)); G_OBJECT_CLASS(ipc3270_parent_class)->finalize(object); } @@ -155,7 +151,7 @@ void ipc3270_add_terminal_introspection(GString *introspection) { // Boolean properties const LIB3270_INT_PROPERTY * bol_props = lib3270_get_boolean_properties_list(); for(ix = 0; bol_props[ix].name; ix++) { - debug("Boolean(%s)",bol_props[ix].name); +// debug("Boolean(%s)",bol_props[ix].name); g_string_append_printf(introspection, " ", bol_props[ix].name, ((bol_props[ix].set == NULL) ? "read" : "readwrite") diff --git a/src/core/linux/gobject.h b/src/core/linux/gobject.h index 989c481..b74fa35 100644 --- a/src/core/linux/gobject.h +++ b/src/core/linux/gobject.h @@ -56,8 +56,13 @@ struct _ipc3270 { GObject parent; - GDBusConnection * connection; - guint id; + + struct { + gchar * name; + GDBusConnection * connection; + guint id; + } dbus; + H3270 * hSession; GQuark error_domain; }; @@ -66,6 +71,8 @@ GObjectClass parent; }; + G_GNUC_INTERNAL void ipc3270_release_object(ipc3270 *object); + G_END_DECLS #endif // LINUX_GOBJECT_H_INCLUDED diff --git a/src/core/linux/start.c b/src/core/linux/start.c index 743ddfb..ef192eb 100644 --- a/src/core/linux/start.c +++ b/src/core/linux/start.c @@ -121,15 +121,15 @@ void ipc3270_export_object(GObject *object, const char *name, GError **error) { ipc3270 * ipc = IPC3270(object); - ipc->connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, error); + ipc->dbus.connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, error); if(*error) { g_message("Can't get session bus: %s",(*error)->message); return; } - g_dbus_connection_set_exit_on_close(ipc->connection,FALSE); + g_dbus_connection_set_exit_on_close(ipc->dbus.connection,FALSE); - for(id='a'; id < 'z' && !ipc->id && !*error; id++) { + for(id='a'; id < 'z' && !ipc->dbus.id && !*error; id++) { g_autofree gchar *object_name = g_strdup_printf(PW3270_IPC_SESSION_BUS_NAME,name,id); @@ -140,7 +140,7 @@ void ipc3270_export_object(GObject *object, const char *name, GError **error) { GVariant * response = g_dbus_connection_call_sync ( - ipc->connection, + ipc->dbus.connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, @@ -167,7 +167,8 @@ void ipc3270_export_object(GObject *object, const char *name, GError **error) { if(reply == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - g_message("Got %s", object_name); + ipc->dbus.name = g_strdup(object_name); + g_message("Got %s", ipc->dbus.name); lib3270_set_session_id(ipc->hSession, id); @@ -178,13 +179,13 @@ void ipc3270_export_object(GObject *object, const char *name, GError **error) { gchar * introspection_xml = g_string_free(introspection,FALSE); - debug("\n%s\n",introspection_xml); + // debug("\n%s\n",introspection_xml); GDBusNodeInfo * introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL); // Register object-id - ipc->id = g_dbus_connection_register_object ( - ipc->connection, + ipc->dbus.id = g_dbus_connection_register_object ( + ipc->dbus.connection, PW3270_IPC_SESSION_OBJECT_PATH, introspection_data->interfaces[0], &interface_vtable, diff --git a/src/core/linux/stop.c b/src/core/linux/stop.c new file mode 100644 index 0000000..c7e9608 --- /dev/null +++ b/src/core/linux/stop.c @@ -0,0 +1,111 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como main.c e possui - linhas de código. + * + * Referências: + * + * https://github.com/joprietoe/gdbus/blob/master/gdbus-example-server.c + * https://github.com/bratsche/glib/blob/master/gio/tests/gdbus-example-export.c + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +#include "gobject.h" +#include +#include + +#include +#include + +void ipc3270_release_object(ipc3270 *object) { + + if(object->dbus.id) { + g_dbus_connection_unregister_object(object->dbus.connection,object->dbus.id); + } + + if(object->dbus.name) { + + debug("Releasing %s",object->dbus.name); + + // https://dbus.freedesktop.org/doc/dbus-specification.html + GError *err = NULL; + + GVariant * response = + g_dbus_connection_call_sync ( + object->dbus.connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "ReleaseName", + g_variant_new ("(s)", object->dbus.name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err + ); + + if(err) { + + g_message("Can't release \"%s\": %s",object->dbus.name,err->message); + g_error_free(err); + err = NULL; + + } else if(response) { + + guint32 reply = 0; + g_variant_get(response, "(u)", &reply); + g_variant_unref(response); + + switch(reply) + { + case DBUS_RELEASE_NAME_REPLY_RELEASED: + // The caller has released his claim on the given name. + // Either the caller was the primary owner of the name, and the name is + // now unused or taken by somebody waiting in the queue for the name, + // or the caller was waiting in the queue for the name and has now been removed from the queue. + g_message("%s released",object->dbus.name); + break; + + case DBUS_RELEASE_NAME_REPLY_NON_EXISTENT: + // The given name does not exist on this bus. + g_message("%s does not exist on this bus",object->dbus.name); + break; + + case DBUS_RELEASE_NAME_REPLY_NOT_OWNER: + // The caller was not the primary owner of this name, and was also not waiting in the queue to own this name. + g_message("%s does not exist on this bus", object->dbus.name); + break; + + default: + g_message("Unexpected response %u when removing %s",(unsigned int) reply, object->dbus.name); + } + } + + g_free(object->dbus.name); + object->dbus.name = NULL; + } + +} -- libgit2 0.21.2