initial untested code...
authorTero Marttila <terom@fixme.fi>
Fri, 19 Sep 2008 01:04:41 +0300
changeset 0 487cbfbafa2c
child 1 b31db3248246
initial untested code...
Makefile
bin/.empty_dir
obj/.empty_dir
src/evfuse.c
src/evfuse.h
--- /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 */