diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2005-11-01 16:56:45 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2005-11-01 16:56:45 +0000 |
commit | fe8f6f45a86efb2d356c3084b7991b90d8f319ea (patch) | |
tree | 92bdc34e409c5e85b76525688a89a59d8b22314e /common | |
parent | 0443fc32d957c04964d6b875fbb203980b57775a (diff) |
Move glib-ectomy.[ch] into the common directory
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile.am | 4 | ||||
-rw-r--r-- | common/glib-ectomy.c | 185 | ||||
-rw-r--r-- | common/glib-ectomy.h | 92 |
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 */ |