summaryrefslogtreecommitdiff
path: root/src/debug/stream.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-12-31 11:49:34 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-12-31 11:49:34 (GMT)
commit651c94450df8619c26e26a133289dbaa197616f4 (patch)
tree1a81a2625687116d205cb5c6583497cb657f8460 /src/debug/stream.c
parentdbec8e8af5f296f0b95cd9c07e7d96b1a4277137 (diff)
Supported a first basic packet of the Java Debug Wire Protocol.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@204 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/debug/stream.c')
-rw-r--r--src/debug/stream.c298
1 files changed, 298 insertions, 0 deletions
diff --git a/src/debug/stream.c b/src/debug/stream.c
new file mode 100644
index 0000000..4c4767a
--- /dev/null
+++ b/src/debug/stream.c
@@ -0,0 +1,298 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * stream.c - gestion des connexions aux serveurs de débogage.
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "stream.h"
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib/gthread.h>
+
+
+#include "stream-int.h"
+#include "../common/dllist.h" /* FIXME : remme ! */
+
+
+
+/* Initialise la classe des flux de communication de débogage. */
+static void g_debug_stream_class_init(GDebugStreamClass *);
+
+/* Initialise une instance de flux de communication de débogage. */
+static void g_debug_stream_init(GDebugStream *);
+
+/* Ecoute une connexion à un serveur de débogage. */
+static void *debug_stream_thread(GDebugStream *);
+
+/* Réceptionne un paquet d'un serveur de débogage. */
+static bool g_debug_stream_read_packet(GDebugStream *, GDebugPacket *);
+
+
+
+/* Indique le type défini pour un flux de communication avec un serveur de débogage. */
+G_DEFINE_TYPE(GDebugStream, g_debug_stream, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des flux de communication de débogage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_debug_stream_class_init(GDebugStreamClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stream = instance à initialiser. *
+* *
+* Description : Initialise une instance de flux de communication de débogage.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_debug_stream_init(GDebugStream *stream)
+{
+ stream->free_mutex = g_mutex_new();
+
+ stream->recv_cond = g_cond_new();
+ stream->recv_mutex = g_mutex_new();
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stream = paramètres de connexion distante. *
+* *
+* Description : Etablit de façon effective une connexion à la cible. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_debug_stream_connect(GDebugStream *stream)
+{
+ GError *error; /* Bilan de création de thread */
+
+ if (stream->connect == NULL || !stream->connect(stream))
+ return false;
+
+ if (!g_thread_create((GThreadFunc)debug_stream_thread, stream, FALSE, &error))
+ {
+ /* TODO : disconnect ! */
+ return false;
+ }
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stream = encadrement associée à l'opération. *
+* *
+* Description : Ecoute une connexion à un serveur de débogage. *
+* *
+* Retour : ??? *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void *debug_stream_thread(GDebugStream *stream)
+{
+ bool status; /* Bilan d'évolution */
+ GDebugPacket *packet; /* Nouveau paquet reçu */
+
+ while (1)
+ {
+ status = stream->poll(stream);
+ if (!status) break;
+
+ packet = g_debug_stream_get_free_packet(stream);
+
+ if (stream->recv_packet(stream, packet))
+ {
+ g_mutex_lock(stream->recv_mutex);
+ g_debug_packet_push(&stream->recv_packets, packet);
+ g_mutex_unlock(stream->recv_mutex);
+
+ g_cond_signal(stream->recv_cond);
+
+ }
+ else g_debug_stream_mark_packet_as_free(stream, packet);
+
+ }
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stream = flux de communication de débogage à consulter. *
+* *
+* Description : Fournit un paquet prêt à emploi. *
+* *
+* Retour : Paquet prêt à emploi. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDebugPacket *g_debug_stream_get_free_packet(GDebugStream *stream)
+{
+ GDebugPacket *result; /* Paquet à retourner */
+
+ g_mutex_lock(stream->free_mutex);
+
+ if (dl_list_empty(stream->free_packets))
+ result = g_object_new(stream->pkt_type, NULL);
+
+ else
+ result = g_debug_packet_pop(&stream->free_packets);
+
+ g_mutex_unlock(stream->free_mutex);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stream = flux de communication de débogage à mettre à jour. *
+* packet = paquet à considérer comme disponible. *
+* *
+* Description : Place un paquet en attente d'une future utilisation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_debug_stream_mark_packet_as_free(GDebugStream *stream, GDebugPacket *packet)
+{
+ g_mutex_lock(stream->free_mutex);
+
+ g_debug_packet_push(&stream->free_packets, packet);
+
+ g_mutex_unlock(stream->free_mutex);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stream = flux ouvert en écriture à mettre à jour. *
+* packet = données à transmettre. *
+* *
+* Description : Envoie un paquet à un serveur de débogage. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_debug_stream_send_packet(GDebugStream *stream, GDebugPacket *packet)
+{
+ bool result; /* Bilan à retourner */
+
+ result = stream->send_packet(stream, packet);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stream = flux de communication de débogage à consulter. *
+* filter = éventuelle fonction de sélection du paquet. *
+* data = éventuelle donnée à associer au filtrage. *
+* *
+* Description : Fournit un paquet reçu d'un serveur de débogage. *
+* *
+* Retour : Paquet de débogage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDebugPacket *g_debug_stream_recv_packet(GDebugStream *stream, filter_packet_fc filter, void *data)
+{
+ GDebugPacket *result; /* Paquet à retourner */
+
+ g_mutex_lock(stream->recv_mutex);
+
+ if (filter != NULL)
+ {
+ gdsrp_try_again:
+
+ for (result = stream->recv_packets;
+ result != NULL;
+ result = g_debug_packet_get_next_iter(stream->recv_packets, result))
+ {
+ if (filter(result, data))
+ break;
+ }
+
+ if (result == NULL)
+ {
+ g_cond_wait(stream->recv_cond, stream->recv_mutex);
+ goto gdsrp_try_again;
+ }
+
+ }
+ else
+ {
+ if (dl_list_empty(stream->recv_packets))
+ g_cond_wait(stream->recv_cond, stream->recv_mutex);
+
+ result = g_debug_packet_pop(&stream->recv_packets);
+
+ }
+
+ g_mutex_unlock(stream->recv_mutex);
+
+ return result;
+
+}