initial untested code...
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile Fri Sep 19 01:04:41 2008 +0300
@@ -0,0 +1,41 @@
+LIBEVENT_PATH = libs/libevent
+LIBFUSE_PATH = libs/libfuse
+
+LIBRARY_PATHS = -L${LIBEVENT_PATH}/lib -L${LIBFUSE_PATH}/lib
+INCLUDE_PATHS = -I${LIBEVENT_PATH}/include -I${LIBFUSE_PATH}/include
+LDLIBS = -levent
+
+DEFINES =
+MY_CFLAGS = -Wall -g -std=gnu99
+
+BIN_NAMES = helloworld
+
+bin/helloworld: obj/helloworld.o
+
+# computed
+LDFLAGS = ${LIBRARY_PATHS} ${LIBRARY_LIST}
+CFLAGS = ${INCLUDE_PATHS} ${DEFINES} ${MY_CFLAGS}
+
+SRC_PATHS = $(wildcard src/*.c)
+SRC_NAMES = $(patsubst src/%,%,$(SRC_PATHS))
+
+BIN_PATHS = $(addprefix bin/,$(BIN_NAMES))
+
+# targets
+all: depend ${BIN_PATHS}
+
+clean :
+ -rm obj/* bin/*
+
+depend:
+ cd src
+ makedepend -p../obj/ -Y -- $(CFLAGS) -- $(SRC_NAMES) 2> /dev/null
+ cd ..
+
+obj/%.o : src/%.c
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
+
+bin/% : obj/%.o
+ $(CC) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -o $@
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/evfuse.c Fri Sep 19 01:04:41 2008 +0300
@@ -0,0 +1,101 @@
+
+#include "evfuse.h"
+
+struct evfuse {
+ // the /dev/fuse fd/channel that we get from fuse_mount
+ struct fuse_chan *chan;
+
+ // the session that we use to process the fuse stuff
+ struct fuse_session *session;
+
+ // the event that we use to receive requests
+ struct event *ev;
+
+ // what our receive-message length is
+ size_t recv_size;
+
+ // the buffer that we use to receive events
+ char *recv_buf;
+};
+
+static void _evfuse_ev_read (evutil_socket_t fd, short what, void *arg) {
+ struct evfuse *ctx = arg;
+ struct fuse_chan *ch = ctx->ch;
+ int res;
+
+ // loop until we complete a recv
+ do {
+ // a new fuse_req is available
+ res = fuse_chan_recv(&ch, ctx->recv_buf, ctx->recv_size);
+ } while (res == -EINTR);
+
+ if (res == 0)
+ ERROR("fuse_chan_recv gave EOF");
+
+ if (res < 0 && res != -EAGAIN)
+ ERROR("fuse_chan_recv failed: %s", strerror(-res));
+
+ if (res > 0) {
+ // received a fuse_req, so process it
+ fuse_session_process(ctx->session, ctx->recv_buf, res, ch);
+ }
+
+ // reschedule
+ if (event_add(ctx->ev, NULL))
+ PERROR("event_add");
+
+ // ok, wait for the next event
+ return;
+
+error:
+ // XXX: fail
+ FATAL("no error handling yet...");
+}
+
+struct evfuse *evfuse_new (struct event_base *evbase, struct fuse_args *args, struct fuse_lowlevel_ops *llops, void *cb_data) {
+ struct evfuse *ctx = NULL;
+ char *mountpoint;
+ int multithreaded, foreground;
+
+ // allocate our context
+ if ((ctx = calloc(1, sizeof(*evfuse))) == NULL)
+ ERROR("calloc");
+
+ // parse the commandline for the mountpoint
+ if (fuse_parse_cmdline(args, &mountpoint, &multithreaded, &foreground) == -1)
+ ERROR("fuse_parse_cmdline");
+
+ // mount it
+ if ((ctx->chan = fuse_mount(mountpoint, args)) == NULL)
+ PERROR("fuse_mount_common");
+
+ // the receive buffer stufff
+ ctx->recv_size = fuse_chan_bufsize(ctx->chan);
+
+ // allocate the recv buffer
+ if ((ctx->recv_buf = malloc(ctx->recv_size)) == NULL)
+ ERROR("malloc");
+
+ // allocate a low-level session
+ if ((ctx->session = fuse_lowlevel_new(args, llops, sizeof(*llops), cb_data)) == NULL)
+ PERROR("fuse_lowlevel_new");
+
+ // add the channel to the session
+ // this isn't strictly necessary, but let's do it anyways
+ fuse_session_add_chan(ctx->session, ctx->chan);
+
+ // now, we can start listening for events on the channel
+ if ((ctx->ev = event_new(evbase, fuse_chan_fd(ctx->chan), EV_READ, &_evfuse_ev_read, ctx)) == NULL)
+ ERROR("event_new");
+
+ if (event_add(ctx->ev, NULL))
+ PERROR("event_add");
+
+ // and then we wait
+ return evfuse;
+
+error:
+ free(ctx);
+
+ return NULL;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/evfuse.h Fri Sep 19 01:04:41 2008 +0300
@@ -0,0 +1,17 @@
+#ifndef EVFUSE_H
+#define EVFUSE_H
+
+#include <event2/event.h>
+#include <fuse_lowlevel.h>
+
+/*
+ * A wrapper for the fuse + libevent context
+ */
+struct evfuse;
+
+/*
+ * Create a new new evfuse context.
+ */
+struct evfuse *evfuse_new (struct event_base *evbase, struct fuse_args *args, struct fuse_lowlevel_ops *llops, void *cb_data);
+
+#ENDIf /* EVFUSE_H */