/*
- * Copyright (C) 2009 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ * Copyright (C) 2009 Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int fd = g_io_channel_unix_get_fd (channel);
char buffer;
int r;
- switch (cond)
+ if (cond & G_IO_IN)
{
- 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;
+ }
+ else if (r == -1)
+ {
+ /* FIXME: create HC_EVENT_ERROR */
+ event = HC_EVENT_CLOSE;
+ }
+ }
+ else if (cond & G_IO_HUP)
+ {
+ event = HC_EVENT_CLOSE;
+ }
+ else if (cond & G_IO_ERR)
+ {
+ /* FIXME: create HC_EVENT_ERROR */
event = HC_EVENT_CLOSE;
- break;
- default:
+ }
+ else
+ {
/* 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;
}
-void
+int
hc_conn_set_driver_channel (HCConn *conn, int fd)
{
struct channel_layer *layer = g_slice_new (struct channel_layer);
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 | G_IO_HUP,
+ layer->watch = g_io_add_watch (layer->channel,
+ G_IO_IN | G_IO_HUP | G_IO_ERR,
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);
fcntl (fd, F_SETFL, fcntl (fd, F_GETFL, 0) | O_NONBLOCK);
+ return 0;
}
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
/* 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);
}