Commit 2100f331 authored by Dafydd Harries's avatar Dafydd Harries

fake UDP: use pipe for recv queue so socket can be select()ed

darcs-hash:20070120040653-c9803-08d3e94ba3b6fb292b3bcbd7f688b7871c2ced2a.gz
parent f92750a9
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <string.h> #include <string.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h>
#include <glib.h> #include <glib.h>
...@@ -20,8 +21,9 @@ typedef struct _UDPFakeSocketManagerPriv UDPFakeSocketManagerPriv; ...@@ -20,8 +21,9 @@ typedef struct _UDPFakeSocketManagerPriv UDPFakeSocketManagerPriv;
struct _UDPFakeSocketManagerPriv struct _UDPFakeSocketManagerPriv
{ {
GSList *recv_queue;
GSList *send_queue; GSList *send_queue;
guint recv_pipe_in;
guint recv_pipe_out;
}; };
static void * static void *
...@@ -70,28 +72,20 @@ fake_recv ( ...@@ -70,28 +72,20 @@ fake_recv (
guint len, guint len,
gchar *buf) gchar *buf)
{ {
Packet *packet;
UDPSocketManager *man; UDPSocketManager *man;
UDPFakeSocketManagerPriv *priv; UDPFakeSocketManagerPriv *priv;
man = (UDPSocketManager *) sock->priv; man = (UDPSocketManager *) sock->priv;
priv = (UDPFakeSocketManagerPriv *) man->priv; priv = (UDPFakeSocketManagerPriv *) man->priv;
packet = (Packet *) _g_slist_pop (&priv->recv_queue);
if (packet == NULL)
{
g_debug ("recv queue underflow");
return 0;
}
len = packet->len; read (priv->recv_pipe_out, from, sizeof (struct sockaddr_in));
memcpy (buf, packet->buf, len); read (priv->recv_pipe_out, &len, sizeof (guint));
memcpy (from, &(packet->sin), sizeof (*from)); read (priv->recv_pipe_out, buf, len);
g_slice_free (Packet, packet);
return len; return len;
} }
/* XXX: set a port in sin */
static gboolean static gboolean
fake_socket_init ( fake_socket_init (
UDPSocketManager *man, UDPSocketManager *man,
...@@ -111,16 +105,12 @@ udp_fake_socket_manager_push_recv ( ...@@ -111,16 +105,12 @@ udp_fake_socket_manager_push_recv (
guint len, guint len,
gchar *buf) gchar *buf)
{ {
Packet *packet;
UDPFakeSocketManagerPriv *priv; UDPFakeSocketManagerPriv *priv;
packet = g_slice_new0 (Packet);
packet->len = len;
packet->sin = *from;
strncpy (packet->buf, buf, len);
priv = (UDPFakeSocketManagerPriv *) man->priv; priv = (UDPFakeSocketManagerPriv *) man->priv;
priv->recv_queue = g_slist_append (priv->recv_queue, packet); write (priv->recv_pipe_in, from, sizeof (struct sockaddr_in));
write (priv->recv_pipe_in, &len, sizeof (guint));
write (priv->recv_pipe_in, buf, len);
} }
guint guint
...@@ -146,15 +136,31 @@ udp_fake_socket_manager_pop_send ( ...@@ -146,15 +136,31 @@ udp_fake_socket_manager_pop_send (
static void static void
fake_socket_manager_close (UDPSocketManager *man) fake_socket_manager_close (UDPSocketManager *man)
{ {
g_slice_free (UDPFakeSocketManagerPriv, man->priv); UDPFakeSocketManagerPriv *priv;
priv = (UDPFakeSocketManagerPriv *) man->priv;
close (priv->recv_pipe_out);
close (priv->recv_pipe_in);
g_slice_free (UDPFakeSocketManagerPriv, priv);
} }
void void
udp_fake_socket_manager_init (UDPSocketManager *man) udp_fake_socket_manager_init (UDPSocketManager *man)
{ {
int fds[2];
UDPFakeSocketManagerPriv *priv;
if (pipe (fds) == -1)
/* XXX: this function should return boolean */
return;
priv = g_slice_new0 (UDPFakeSocketManagerPriv);
priv->recv_pipe_out = fds[0];
priv->recv_pipe_in = fds[1];
man->init = fake_socket_init; man->init = fake_socket_init;
man->select = NULL; man->select = NULL;
man->close = fake_socket_manager_close; man->close = fake_socket_manager_close;
man->priv = g_slice_new0 (UDPFakeSocketManagerPriv); man->priv = priv;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment