summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-11-01 16:56:45 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-11-01 16:56:45 +0000
commitfe8f6f45a86efb2d356c3084b7991b90d8f319ea (patch)
tree92bdc34e409c5e85b76525688a89a59d8b22314e /common
parent0443fc32d957c04964d6b875fbb203980b57775a (diff)
Move glib-ectomy.[ch] into the common directory
Diffstat (limited to 'common')
-rw-r--r--common/Makefile.am4
-rw-r--r--common/glib-ectomy.c185
-rw-r--r--common/glib-ectomy.h92
3 files changed, 280 insertions, 1 deletions
diff --git a/common/Makefile.am b/common/Makefile.am
index 71592813..5a5a4702 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -1,8 +1,10 @@
-noinst_LIBRARIES = libtextfile.a
+noinst_LIBRARIES = libtextfile.a libglib-ectomy.a
libtextfile_a_SOURCES = textfile.h textfile.c
+libglib_ectomy_a_SOURCES = glib-ectomy.h glib-ectomy.c
+
noinst_PROGRAMS = test_textfile
test_textfile_LDADD = libtextfile.a
diff --git a/common/glib-ectomy.c b/common/glib-ectomy.c
new file mode 100644
index 00000000..bea7f47c
--- /dev/null
+++ b/common/glib-ectomy.c
@@ -0,0 +1,185 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include <limits.h>
+
+#include "glib-ectomy.h"
+
+GIOError g_io_channel_read(GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read)
+{
+ int fd = channel->fd;
+ gssize result;
+
+ /* At least according to the Debian manpage for read */
+ if (count > SSIZE_MAX)
+ count = SSIZE_MAX;
+
+retry:
+ result = read (fd, buf, count);
+
+ if (result < 0) {
+ *bytes_read = 0;
+
+ switch (errno) {
+#ifdef EINTR
+ case EINTR:
+ goto retry;
+#endif
+#ifdef EAGAIN
+ case EAGAIN:
+ return G_IO_STATUS_AGAIN;
+#endif
+ default:
+ return G_IO_STATUS_ERROR;
+ }
+ }
+
+ *bytes_read = result;
+
+ return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+}
+
+void g_io_channel_close(GIOChannel *channel)
+{
+ if (!channel)
+ return;
+
+ close(channel->fd);
+
+ memset(channel, 0, sizeof(channel));
+ free(channel);
+}
+
+GIOChannel *g_io_channel_unix_new(int fd)
+{
+ GIOChannel *channel;
+
+ channel = malloc(sizeof(GIOChannel));
+ if (!channel)
+ return NULL;
+
+ channel->fd = fd;
+
+ return channel;
+}
+
+gint g_io_channel_unix_get_fd(GIOChannel *channel)
+{
+ return channel->fd;
+}
+
+struct watch {
+ guint id;
+ GIOChannel *channel;
+ GIOCondition condition;
+ GIOFunc func;
+ gpointer user_data;
+
+ struct watch *next;
+};
+
+static struct watch watch_head = { .id = 0, .next = 0 };
+
+void g_io_remove_watch(guint id)
+{
+ struct watch *w, *p;
+
+ for (p = &watch_head, w = watch_head.next; w; w = w->next)
+ if (w->id == id) {
+ p->next = w->next;
+ free (w);
+ return;
+ }
+}
+
+guint g_io_add_watch(GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data)
+{
+ struct watch *watch = malloc(sizeof(struct watch));
+
+ watch->id = ++watch_head.id;
+ watch->channel = channel;
+ watch->condition = condition;
+ watch->func = func;
+ watch->user_data = user_data;
+
+ watch->next = watch_head.next;
+ watch_head.next = watch;
+
+ return watch->id;
+}
+
+GMainLoop *g_main_loop_new(GMainContext *context, gboolean is_running)
+{
+ GMainLoop *ml;
+
+ ml = malloc(sizeof(GMainLoop));
+ if (!ml)
+ return NULL;
+
+ ml->bail = 0;
+
+ return ml;
+}
+
+void g_main_loop_run(GMainLoop *loop)
+{
+ int open_max = sysconf(_SC_OPEN_MAX);
+ struct pollfd *ufds;
+
+ ufds = malloc(open_max * sizeof(struct pollfd));
+ if (!ufds)
+ return;
+
+ while (!loop->bail) {
+ int nfds, rc, i;
+ struct watch *p, *w;
+
+ nfds = 0;
+ for (w = watch_head.next; w != NULL; w = w->next) {
+ ufds[nfds].fd = w->channel->fd;
+ ufds[nfds].events = w->condition;
+ ufds[nfds].revents = 0;
+ nfds++;
+ }
+
+ rc = poll(ufds, nfds, -1);
+ if (rc < 0)
+ continue;
+
+ p = &watch_head;
+ w = watch_head.next;
+ i = 0;
+
+ while (w) {
+ if (ufds[i].revents) {
+ gboolean keep = w->func(w->channel, ufds[i].revents, w->user_data);
+ if (!keep) {
+ p->next = w->next;
+ memset(w, 0, sizeof(*w));
+ w = p->next;
+ i++;
+ continue;
+ }
+ }
+
+ p = w;
+ w = w->next;
+ i++;
+ }
+ }
+
+ free(ufds);
+}
+
+void g_main_loop_quit(GMainLoop *loop)
+{
+ loop->bail = 1;
+}
diff --git a/common/glib-ectomy.h b/common/glib-ectomy.h
new file mode 100644
index 00000000..c507e3c7
--- /dev/null
+++ b/common/glib-ectomy.h
@@ -0,0 +1,92 @@
+#ifndef __GLIB_ECTOMY_H
+#define __GLIB_ECTOMY_H
+
+#include <stdlib.h>
+#include <sys/poll.h>
+
+typedef char gchar;
+typedef short gshort;
+typedef long glong;
+typedef int gint;
+typedef gint gboolean;
+
+typedef unsigned char guchar;
+typedef unsigned short gushort;
+typedef unsigned long gulong;
+typedef unsigned int guint;
+
+typedef float gfloat;
+typedef double gdouble;
+
+typedef void * gpointer;
+typedef const void * gconstpointer;
+
+typedef size_t gsize;
+typedef ssize_t gssize;
+
+#ifndef SSIZE_MAX
+#define SSIZE_MAX INT_MAX
+#endif
+
+typedef struct _GIOChannel {
+ int fd;
+} GIOChannel;
+
+typedef struct _GMainContext {
+ int dummy;
+} GMainContext;
+
+typedef struct _GMainLoop {
+ int bail;
+} GMainLoop;
+
+typedef enum {
+ G_IO_ERROR_NONE,
+ G_IO_ERROR_AGAIN,
+ G_IO_ERROR_INVAL,
+ G_IO_ERROR_UNKNOWN
+} GIOError;
+
+typedef enum {
+ G_IO_STATUS_ERROR = -1,
+ G_IO_STATUS_NORMAL = 0,
+ G_IO_STATUS_EOF = 1,
+ G_IO_STATUS_AGAIN = 2
+} GIOStatus;
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+typedef enum {
+ G_IO_IN = POLLIN,
+ G_IO_OUT = POLLOUT,
+ G_IO_PRI = POLLPRI,
+ G_IO_ERR = POLLERR,
+ G_IO_HUP = POLLHUP,
+ G_IO_NVAL = POLLNVAL
+} GIOCondition;
+
+typedef gboolean (*GIOFunc) (GIOChannel *source, GIOCondition condition, gpointer data);
+
+GIOError g_io_channel_read(GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read);
+void g_io_channel_close(GIOChannel *channel);
+
+GIOChannel *g_io_channel_unix_new(int fd);
+gint g_io_channel_unix_get_fd(GIOChannel *channel);
+guint g_io_add_watch(GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data);
+void g_io_remove_watch(guint id);
+
+GMainLoop *g_main_loop_new(GMainContext *context, gboolean is_running);
+void g_main_loop_run(GMainLoop *loop);
+void g_main_loop_quit(GMainLoop *loop);
+
+#define g_main_new(is_running) g_main_loop_new(NULL, is_running);
+#define g_main_run(loop) g_main_loop_run(loop)
+#define g_main_quit(loop) g_main_loop_quit(loop)
+
+#endif /* __GLIB_ECTOMY_H */