X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=hcconn.c;h=02f15721d5d3b45db226ebd98bd4c69181f000b1;hb=2f6f433ac65fb6f4208a3ac8519cf53941745cc4;hp=3b2a8907e5a10ed239a424acdb5bce5eb8b0fe15;hpb=8aaec8d5c79aa2bc1eae9a6ac619a30ef80e9d2e;p=cascardo%2Frnetproxy.git diff --git a/hcconn.c b/hcconn.c index 3b2a890..02f1572 100644 --- a/hcconn.c +++ b/hcconn.c @@ -20,6 +20,7 @@ #include "hcconn.h" #include #include +#include #include "hcconn_internal.h" /* The server connection watch */ @@ -96,7 +97,7 @@ hc_conn_channel_close (gpointer data) struct channel_layer *layer = data; int fd = g_io_channel_unix_get_fd (layer->channel); g_source_remove (layer->watch); - shutdown (fd, SHUT_RDWR); + close (fd); g_io_channel_unref (layer->channel); g_slice_free (struct channel_layer, layer); } @@ -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); @@ -152,7 +173,9 @@ hc_conn_set_callback (HCConn *conn, HCClientFunc func, gpointer data) ssize_t hc_conn_read (HCConn *conn, char *buffer, size_t len) { - return conn->read (conn->layer, buffer, len); + if (conn->read) + return conn->read (conn->layer, buffer, len); + return 0; } void @@ -161,12 +184,18 @@ hc_conn_write (HCConn *conn, char *buffer, size_t len) /* TODO: Do buffering or something like that */ /* Do we really need to? */ /* In case of error, we should do something */ - conn->write (conn->layer, buffer, len); + if (conn->write) + conn->write (conn->layer, buffer, len); } void hc_conn_close (HCConn *conn) { - conn->close (conn->layer); + if (conn->close) + conn->close (conn->layer); + conn->read = NULL; + conn->write = NULL; + conn->close = NULL; + conn->func = NULL; g_slice_free (HCConn, conn); }