Diff between d18e1ad69c28b2288afbcb3c55d51fd134b54428 and 8df53c86a2c8730f36a160271bb21d3cfb6107e8

Changed Files

File Additions Deletions Status
src/shared/io-glib.c +180 -0 modified
src/shared/io.h +22 -0 modified

Full Patch

diff --git a/src/shared/io-glib.c b/src/shared/io-glib.c
index 8a7fb9a..a7ac95f 100644
--- a/src/shared/io-glib.c
+++ b/src/shared/io-glib.c
@@ -25,4 +25,184 @@
 #include <config.h>
 #endif
 
+#include <glib.h>
+
 #include "src/shared/io.h"
+
+struct io {
+	GIOChannel *channel;
+	guint read_watch;
+	io_callback_func_t read_callback;
+	io_destroy_func_t read_destroy;
+	void *read_data;
+	guint write_watch;
+	io_callback_func_t write_callback;
+	io_destroy_func_t write_destroy;
+	void *write_data;
+};
+
+struct io *io_new(int fd)
+{
+	struct io *io;
+
+	if (fd < 0)
+		return NULL;
+
+	io = g_try_new0(struct io, 1);
+	if (!io)
+		return NULL;
+
+	io->channel = g_io_channel_unix_new(fd);
+
+	g_io_channel_set_encoding(io->channel, NULL, NULL);
+	g_io_channel_set_buffered(io->channel, FALSE);
+
+	g_io_channel_set_close_on_unref(io->channel, FALSE);
+
+	io->read_watch = 0;
+	io->read_callback = NULL;
+	io->read_destroy = NULL;
+	io->read_data = NULL;
+
+	io->write_watch = 0;
+	io->write_callback = NULL;
+	io->write_destroy = NULL;
+	io->write_data = NULL;
+
+	return io;
+}
+
+void io_destroy(struct io *io)
+{
+	if (!io)
+		return;
+
+	g_io_channel_unref(io->channel);
+
+	g_free(io);
+}
+
+int io_get_fd(struct io *io)
+{
+	if (!io)
+		return -1;
+
+	return g_io_channel_unix_get_fd(io->channel);
+}
+
+bool io_set_close_on_destroy(struct io *io, bool do_close)
+{
+	if (!io)
+		return false;
+
+	if (do_close)
+		g_io_channel_set_close_on_unref(io->channel, TRUE);
+	else
+		g_io_channel_set_close_on_unref(io->channel, FALSE);
+
+	return true;
+}
+
+static void read_watch_destroy(gpointer user_data)
+{
+	struct io *io = user_data;
+
+	if (io->read_destroy)
+		io->read_destroy(io->read_data);
+
+	io->read_watch = 0;
+	io->read_callback = NULL;
+	io->read_destroy = NULL;
+	io->read_data = NULL;
+}
+
+static gboolean read_callback(GIOChannel *channel, GIOCondition cond,
+							gpointer user_data)
+{
+	struct io *io = user_data;
+
+	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
+		return FALSE;
+
+	if (io->read_callback)
+		io->read_callback(io, io->read_data);
+
+	return TRUE;
+}
+
+bool io_set_read_handler(struct io *io, io_callback_func_t callback,
+				void *user_data, io_destroy_func_t destroy)
+{
+	if (!io)
+		return false;
+
+	if (io->read_watch > 0)
+		g_source_remove(io->read_watch);
+
+	io->read_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				read_callback, io, read_watch_destroy);
+	if (io->read_watch == 0)
+		return false;
+
+	io->read_callback = callback;
+	io->read_destroy = destroy;
+	io->read_data = user_data;
+
+	return true;
+}
+
+static void write_watch_destroy(gpointer user_data)
+{
+	struct io *io = user_data;
+
+	if (io->write_destroy)
+		io->write_destroy(io->write_data);
+
+	io->write_watch = 0;
+	io->write_callback = NULL;
+	io->write_destroy = NULL;
+	io->write_data = NULL;
+}
+
+static gboolean write_callback(GIOChannel *channel, GIOCondition cond,
+							gpointer user_data)
+{
+	struct io *io = user_data;
+
+	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
+		return FALSE;
+
+	if (io->write_callback)
+		io->write_callback(io, io->write_data);
+
+	return TRUE;
+}
+
+bool io_set_write_handler(struct io *io, io_callback_func_t callback,
+				void *user_data, io_destroy_func_t destroy)
+{
+	if (!io)
+		return false;
+
+	if (io->write_watch > 0)
+		g_source_remove(io->write_watch);
+
+	io->write_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
+				G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				write_callback, io, write_watch_destroy);
+	if (io->write_watch == 0)
+		return false;
+
+	io->write_callback = callback;
+	io->write_destroy = destroy;
+	io->write_data = user_data;
+
+	return true;
+}
+
+bool io_set_disconnect_handler(struct io *io, io_callback_func_t callback,
+				void *user_data, io_destroy_func_t destroy)
+{
+	return false;
+}
diff --git a/src/shared/io.h b/src/shared/io.h
index 29ead9c..c48a7ab 100644
--- a/src/shared/io.h
+++ b/src/shared/io.h
@@ -21,3 +21,25 @@
  *
  */
 
+#include <stdbool.h>
+
+typedef void (*io_destroy_func_t)(void *data);
+
+struct io;
+
+typedef void (*io_callback_func_t) (struct io *io, void *user_data);
+
+struct io *io_new(int fd);
+void io_destroy(struct io *io);
+
+int io_get_fd(struct io *io);
+bool io_set_close_on_destroy(struct io *io, bool do_close);
+
+typedef void (*io_callback_func_t)(struct io *io, void *user_data);
+
+bool io_set_read_handler(struct io *io, io_callback_func_t callback,
+				void *user_data, io_destroy_func_t destroy);
+bool io_set_write_handler(struct io *io, io_callback_func_t callback,
+				void *user_data, io_destroy_func_t destroy);
+bool io_set_disconnect_handler(struct io *io, io_callback_func_t callback,
+				void *user_data, io_destroy_func_t destroy);