Updated Spanish translation
[anjuta.git] / plugins / js-debugger / debugger-server.c
blob0e48e2f2a87a70fbc39d04aaf7c837f79633f8c7
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 Copyright (C) 2009 Maxim Ermilov <zaspire@rambler.ru>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <sys/ioctl.h>
23 #include <netinet/in.h>
24 #include <netinet/tcp.h>
25 #include <unistd.h>
26 #include <string.h>
28 #include <glib.h>
29 #include <errno.h>
30 #include <glib/gi18n.h>
32 #include "debugger-server.h"
34 typedef struct _DebuggerServerPrivate DebuggerServerPrivate;
35 struct _DebuggerServerPrivate
37 GList* in;
38 GList* out;
39 int server_socket;
40 int socket;
41 gboolean work;
42 guint id;
45 #define DEBUGGER_SERVER_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEBUGGER_TYPE_SERVER, DebuggerServerPrivate))
47 enum
49 DATA_ARRIVED,
50 ERROR_SIGNAL,
51 LAST_SIGNAL
54 #define CANT_SEND _("App exited unexpectedly.")
55 #define CANT_RECV _("App exited unexpectedly.")
58 static guint server_signals[LAST_SIGNAL] = { 0 };
60 G_DEFINE_TYPE (DebuggerServer, debugger_server, G_TYPE_OBJECT);
62 static void
63 debugger_server_init (DebuggerServer *object)
65 DebuggerServerPrivate *priv = DEBUGGER_SERVER_PRIVATE (object);
66 priv->in = NULL;
67 priv->out = NULL;
68 priv->id = 0;
69 priv->server_socket = 0;
70 priv->socket = 0;
71 priv->work = TRUE;
74 static void
75 debugger_server_finalize (GObject *object)
77 DebuggerServerPrivate *priv = DEBUGGER_SERVER_PRIVATE (object);
79 g_assert (priv);
80 if (priv->socket)
82 close (priv->socket);
84 if (priv->id)
85 g_source_remove (priv->id);
87 g_list_foreach (priv->in, (GFunc)g_free, NULL);
88 g_list_free (priv->in);
89 g_list_foreach (priv->out, (GFunc)g_free, NULL);
90 g_list_free (priv->out);
92 G_OBJECT_CLASS (debugger_server_parent_class)->finalize (object);
95 static void
96 debugger_server_data_arrived (DebuggerServer *self)
100 static void
101 debugger_server_error_signal (DebuggerServer *self, const gchar *text)
105 static void
106 debugger_server_class_init (DebuggerServerClass *klass)
108 GObjectClass* object_class = G_OBJECT_CLASS (klass);
110 g_type_class_add_private (klass, sizeof (DebuggerServerPrivate));
112 object_class->finalize = debugger_server_finalize;
114 klass->data_arrived = debugger_server_data_arrived;
115 klass->error = debugger_server_error_signal;
117 server_signals[DATA_ARRIVED] =
118 g_signal_new ("data-arrived",
119 G_OBJECT_CLASS_TYPE (klass),
120 G_SIGNAL_RUN_FIRST,
121 G_STRUCT_OFFSET (DebuggerServerClass, data_arrived),
122 NULL, NULL,
123 g_cclosure_marshal_VOID__VOID,
124 G_TYPE_NONE, 0);
125 server_signals[ERROR_SIGNAL] =
126 g_signal_new ("error",
127 G_OBJECT_CLASS_TYPE (klass),
128 G_SIGNAL_RUN_FIRST,
129 G_STRUCT_OFFSET (DebuggerServerClass, error),
130 NULL, NULL,
131 g_cclosure_marshal_VOID__POINTER,
132 G_TYPE_NONE, 1, G_TYPE_POINTER);
135 static gboolean
136 SourceFunc (gpointer d)
138 DebuggerServer *object = DEBUGGER_SERVER (d);
139 DebuggerServerPrivate *priv = DEBUGGER_SERVER_PRIVATE (object);
140 gint size;
142 if (priv->socket == 0)
144 fd_set accept_fd;
145 struct timeval timeo;
146 struct sockaddr *cp = NULL;
147 socklen_t sz;
149 FD_ZERO(&accept_fd);
150 FD_SET(priv->server_socket, &accept_fd);
151 timeo.tv_sec=0;
152 timeo.tv_usec=1;
153 if (select(priv->server_socket + 1,&accept_fd,NULL,NULL,&timeo) > 0)
155 if(FD_ISSET(priv->server_socket,&accept_fd))
157 if ((priv->socket = accept(priv->server_socket, cp, &sz)) == -1)
159 g_signal_emit (object, server_signals[ERROR_SIGNAL], 0, "Can not accept.");
160 return FALSE;
162 close (priv->server_socket);
166 else
168 int len;
169 if (ioctl (priv->socket, FIONREAD, &len) == -1)
171 g_signal_emit (object, server_signals[ERROR_SIGNAL], 0, "Error in ioctl call.");
172 return FALSE;
174 if (len > 4)
176 int in;
177 gchar *buf;
178 if (recv (priv->socket, &len, 4, 0) == -1)
180 g_signal_emit (object, server_signals[ERROR_SIGNAL], 0, CANT_RECV);
181 return FALSE;
183 if (len <= 0)
185 g_signal_emit (object, server_signals[ERROR_SIGNAL], 0, "Incorrect data recived.");
186 return FALSE;
188 buf = g_new (char, len + 1);
191 if (ioctl (priv->socket, FIONREAD, &in) == -1)
193 g_signal_emit (object, server_signals[ERROR_SIGNAL], 0, "Error in ioctl call.");
194 return FALSE;
196 if (in < len)
197 usleep (20);
198 } while (in < len);
199 if (recv (priv->socket, buf, len, 0) == -1)
201 g_signal_emit (object, server_signals[ERROR_SIGNAL], 0, CANT_RECV);
202 return FALSE;
204 buf [len] = '\0';
206 priv->in = g_list_append (priv->in, buf);
207 g_signal_emit (object, server_signals[DATA_ARRIVED], 0);
209 while (priv->out != NULL)
211 size = strlen ((gchar*)priv->out->data) + 1;
212 if (send(priv->socket, &size, 4, 0) == -1)
214 g_signal_emit (object, server_signals[ERROR_SIGNAL], 0, CANT_SEND);
215 return FALSE;
217 if (send(priv->socket, priv->out->data, size, 0) == -1)
219 g_signal_emit (object, server_signals[ERROR_SIGNAL], 0, CANT_SEND);
220 return FALSE;
222 g_free (priv->out->data);
223 priv->out = g_list_delete_link (priv->out, priv->out);
225 g_signal_emit (object, server_signals[DATA_ARRIVED], 0);//TODO:FIX
228 if (!priv->work)
230 close (priv->socket);
231 priv->socket = 0;
233 return priv->work;
237 DebuggerServer*
238 debugger_server_new (gint port)
240 DebuggerServer* object = g_object_new (DEBUGGER_TYPE_SERVER, NULL);
241 DebuggerServerPrivate *priv = DEBUGGER_SERVER_PRIVATE (object);
242 struct sockaddr_in serverAddr;
243 int flag = 1;
245 priv->server_socket = socket (AF_INET, SOCK_STREAM, 0);
247 if (priv->server_socket == -1)
248 return NULL;
250 serverAddr.sin_family = AF_INET;
251 serverAddr.sin_addr.s_addr= htonl (INADDR_ANY);
252 serverAddr.sin_port = htons (port);
253 setsockopt (priv->server_socket, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
254 if (bind (priv->server_socket, ((struct sockaddr*)&serverAddr), sizeof (serverAddr)) == -1)
256 g_warning("%s\n", strerror(errno));
257 g_object_unref (object);
258 return NULL;
260 listen (priv->server_socket , 5);
262 priv->id = g_timeout_add (2, (GSourceFunc)SourceFunc, object);
264 return object;
267 void
268 debugger_server_send_line (DebuggerServer *object, const gchar* line)
270 DebuggerServerPrivate *priv = DEBUGGER_SERVER_PRIVATE (object);
271 g_assert (line != NULL);
272 priv->out = g_list_append (priv->out, g_strdup (line));
275 void
276 debugger_server_stop (DebuggerServer *object)
278 DebuggerServerPrivate *priv = DEBUGGER_SERVER_PRIVATE (object);
279 if (priv)
280 priv->work = FALSE;
283 gchar*
284 debugger_server_get_line (DebuggerServer *object)
286 DebuggerServerPrivate *priv = DEBUGGER_SERVER_PRIVATE (object);
287 gchar *ret = NULL;
289 g_assert (priv->in != NULL);
291 g_assert (priv->in->data != NULL);
293 ret = g_strdup ((gchar*)priv->in->data);
295 priv->in = g_list_delete_link (priv->in, priv->in);
296 return ret;
299 gint
300 debugger_server_get_line_col (DebuggerServer *object)
302 DebuggerServerPrivate *priv = DEBUGGER_SERVER_PRIVATE (object);
303 return g_list_length (priv->in);