Handle other socket events and push them forward.
authorThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Fri, 3 Jul 2009 17:24:26 +0000 (14:24 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Fri, 3 Jul 2009 18:37:25 +0000 (15:37 -0300)
Handle HUP event and the case where the other end has closed the
connection and read returns 0.

hcconn.c

index 3b2a890..3e3f52f 100644 (file)
--- a/hcconn.c
+++ b/hcconn.c
@@ -20,6 +20,7 @@
 #include "hcconn.h"
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/socket.h>
 #include "hcconn_internal.h"
 
 /* The server connection watch */
@@ -106,7 +107,26 @@ hc_conn_watch (GIOChannel *channel, GIOCondition cond, gpointer data)
 {
   HCConn *conn = data;
   /* TODO: What about other events, like closing? */
-  HCEvent event = HC_EVENT_READ;
+  HCEvent event;
+  int fd = g_io_channel_unix_get_fd (channel);
+  char buffer;
+  int r;
+  switch (cond)
+    {
+    case G_IO_IN:
+      event = HC_EVENT_READ;
+      r = recv (fd, &buffer, 1, MSG_PEEK);
+      if (r == 0)
+        event = HC_EVENT_CLOSE;
+      break;
+    case G_IO_HUP:
+      event = HC_EVENT_CLOSE;
+      break;
+    default:
+      /* TODO: handle other conditions and create error event */
+      g_warning ("Received an unexpected IO condition.");
+      break;
+    }
   if (conn->func)
     conn->func (conn, event, conn->data);
   return TRUE;
@@ -122,7 +142,8 @@ hc_conn_set_driver_channel (HCConn *conn, int fd)
   conn->write = hc_conn_channel_write;
   conn->close = hc_conn_channel_close;
   /* TODO: We must watch other events */
-  layer->watch = g_io_add_watch (layer->channel, G_IO_IN, hc_conn_watch, conn);
+  layer->watch = g_io_add_watch (layer->channel, G_IO_IN | G_IO_HUP,
+                                 hc_conn_watch, conn);
   /* TODO: connection should be asynchronous so this could make sense */
   if (conn->func)
     conn->func (conn, HC_EVENT_CONNECT, conn->data);