--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore Thu Sep 25 15:03:09 2008 +0300
@@ -0,0 +1,5 @@
+type: re
+
+^bin/
+^obj/
+\.[^/]+.sw[op]$
--- a/Makefile Fri Sep 19 01:04:41 2008 +0300
+++ b/Makefile Thu Sep 25 15:03:09 2008 +0300
@@ -1,16 +1,18 @@
-LIBEVENT_PATH = libs/libevent
-LIBFUSE_PATH = libs/libfuse
+LIBEVENT_PATH = ../libs/libevent-dev
+LIBFUSE_PATH = ../libs/libfuse-2.7.4
LIBRARY_PATHS = -L${LIBEVENT_PATH}/lib -L${LIBFUSE_PATH}/lib
INCLUDE_PATHS = -I${LIBEVENT_PATH}/include -I${LIBFUSE_PATH}/include
-LDLIBS = -levent
+LDLIBS = -levent -lfuse
-DEFINES =
+# XXX: ugh... use `pkg-config fuse`
+DEFINES = -D_FILE_OFFSET_BITS=64
MY_CFLAGS = -Wall -g -std=gnu99
-BIN_NAMES = helloworld
+BIN_NAMES = hello helloworld
-bin/helloworld: obj/helloworld.o
+bin/helloworld:
+bin/hello: obj/evfuse.o obj/lib/common.o
# computed
LDFLAGS = ${LIBRARY_PATHS} ${LIBRARY_LIST}
@@ -18,6 +20,7 @@
SRC_PATHS = $(wildcard src/*.c)
SRC_NAMES = $(patsubst src/%,%,$(SRC_PATHS))
+SRC_DIRS = $(dir $(SRC_NAMES))
BIN_PATHS = $(addprefix bin/,$(BIN_NAMES))
@@ -32,10 +35,13 @@
makedepend -p../obj/ -Y -- $(CFLAGS) -- $(SRC_NAMES) 2> /dev/null
cd ..
+obj-dirs:
+ python build/make_obj_dirs.py $(BIN_PATHS)
+
obj/%.o : src/%.c
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $^ -o $@
bin/% : obj/%.o
- $(CC) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -o $@
+ $(CC) $(LDFLAGS) $+ $(LOADLIBES) $(LDLIBS) -o $@
# DO NOT DELETE THIS LINE -- make depend depends on it.
--- a/src/evfuse.c Fri Sep 19 01:04:41 2008 +0300
+++ b/src/evfuse.c Thu Sep 25 15:03:09 2008 +0300
@@ -1,5 +1,10 @@
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
#include "evfuse.h"
+#include "lib/common.h"
struct evfuse {
// the /dev/fuse fd/channel that we get from fuse_mount
@@ -20,7 +25,7 @@
static void _evfuse_ev_read (evutil_socket_t fd, short what, void *arg) {
struct evfuse *ctx = arg;
- struct fuse_chan *ch = ctx->ch;
+ struct fuse_chan *ch = ctx->chan;
int res;
// loop until we complete a recv
@@ -36,6 +41,8 @@
ERROR("fuse_chan_recv failed: %s", strerror(-res));
if (res > 0) {
+ INFO("[evfuse] got %d bytes from /dev/fuse", res);
+
// received a fuse_req, so process it
fuse_session_process(ctx->session, ctx->recv_buf, res, ch);
}
@@ -58,7 +65,7 @@
int multithreaded, foreground;
// allocate our context
- if ((ctx = calloc(1, sizeof(*evfuse))) == NULL)
+ if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
ERROR("calloc");
// parse the commandline for the mountpoint
@@ -92,7 +99,7 @@
PERROR("event_add");
// and then we wait
- return evfuse;
+ return ctx;
error:
free(ctx);
--- a/src/evfuse.h Fri Sep 19 01:04:41 2008 +0300
+++ b/src/evfuse.h Thu Sep 25 15:03:09 2008 +0300
@@ -1,8 +1,10 @@
#ifndef EVFUSE_H
#define EVFUSE_H
+#define FUSE_USE_VERSION 26
+
#include <event2/event.h>
-#include <fuse_lowlevel.h>
+#include <fuse/fuse_lowlevel.h>
/*
* A wrapper for the fuse + libevent context
@@ -14,4 +16,4 @@
*/
struct evfuse *evfuse_new (struct event_base *evbase, struct fuse_args *args, struct fuse_lowlevel_ops *llops, void *cb_data);
-#ENDIf /* EVFUSE_H */
+#endif /* EVFUSE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hello.c Thu Sep 25 15:03:09 2008 +0300
@@ -0,0 +1,47 @@
+#include <event2/event.h>
+#include <fuse/fuse_opt.h>
+
+#include "lib/common.h"
+#include "evfuse.h"
+
+struct hello {
+ struct event_base *ev_base;
+
+ struct evfuse *ev_fuse;
+} ctx;
+
+void hello_init (void *userdata, struct fuse_conn_info *conn) {
+ INFO("[hello.init] userdata=%p, conn=%p", userdata, conn);
+}
+
+void hello_destroy (void *userdata) {
+ INFO("[hello.destroy] userdata=%p", userdata);
+}
+
+struct fuse_lowlevel_ops hello_llops = {
+ .init = &hello_init,
+ .destroy = &hello_destroy,
+};
+
+
+int main (int argc, char **argv) {
+ struct fuse_args fuse_args = FUSE_ARGS_INIT(argc, argv);
+
+ // init libevent
+ if ((ctx.ev_base = event_base_new()) == NULL)
+ FATAL("event_base_new");
+
+ // open fuse
+ if ((ctx.ev_fuse = evfuse_new(ctx.ev_base, &fuse_args, &hello_llops, &ctx)) == NULL)
+ FATAL("evfuse_new");
+
+ // run libevent
+ INFO("running libevent loop");
+
+ if (event_base_dispatch(ctx.ev_base))
+ PWARNING("event_base_dispatch");
+
+ // cleanup
+ event_base_free(ctx.ev_base);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helloworld.c Thu Sep 25 15:03:09 2008 +0300
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (void) {
+ printf("Hello World\n");
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/common.c Thu Sep 25 15:03:09 2008 +0300
@@ -0,0 +1,40 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include "common.h"
+
+static void _generic_err_vargs (int use_stderr, const char *func, int perr, const char *fmt, va_list va) {
+ FILE *stream = use_stderr ? stderr : stdout;
+
+ if (func)
+ fprintf(stream, "%s: ", func);
+
+ vfprintf(stream, fmt, va);
+
+ if (perr)
+ fprintf(stream, ": %s\n", strerror(errno));
+
+ fprintf(stream, "\n");
+}
+
+void _generic_err (int use_stderr, const char *func, int perr, const char *fmt, ...) {
+ va_list va;
+
+ va_start(va, fmt);
+ _generic_err_vargs(use_stderr, func, perr, fmt, va);
+ va_end(va);
+}
+
+void _generic_err_exit (int use_stderr, const char *func, int perr, const char *fmt, ...) {
+ va_list va;
+
+ va_start(va, fmt);
+ _generic_err_vargs(use_stderr, func, perr, fmt, va);
+ va_end(va);
+
+ exit(EXIT_FAILURE);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/common.h Thu Sep 25 15:03:09 2008 +0300
@@ -0,0 +1,64 @@
+
+/*
+ * error handling
+ */
+
+void _generic_err ( /*int level, */ int use_stderr, const char *func, int perr, const char *fmt, ...)
+ __attribute__ ((format (printf, 4, 5)));
+
+// needs to be defined as its own function for the noreturn attribute
+void _generic_err_exit ( /* int level, */ int used_stderr, const char *func, int perr, const char *fmt, ...)
+ __attribute__ ((format (printf, 4, 5)))
+ __attribute__ ((noreturn));
+
+enum _debug_level {
+ DEBUG_FATAL,
+ DEBUG_ERROR,
+ DEBUG_WARNING,
+ DEBUG_INFO,
+ DEBUG_DEBUG,
+};
+
+// not currently used
+extern enum _debug_level _cur_debug_level;
+
+// various kinds of ways to handle an error, 2**3 of them, *g*
+#define info(...) _generic_err( 0, NULL, 0, __VA_ARGS__ )
+#define error(...) _generic_err( 1, NULL, 0, __VA_ARGS__ )
+#define err_exit(...) _generic_err_exit( 1, NULL, 0, __VA_ARGS__ )
+#define perr(...) _generic_err( 1, NULL, 1, __VA_ARGS__ )
+#define perr_exit(...) _generic_err_exit( 1, NULL, 1, __VA_ARGS__ )
+#define err_func(func, ...) _generic_err( 1, func, 0, __VA_ARGS__ )
+#define err_func_exit(func, ...) _generic_err_exit( 1, func, 0, __VA_ARGS__ )
+#define perr_func(func, ...) _generic_err( 1, func, 1, __VA_ARGS__ )
+#define perr_func_exit(func, ...) _generic_err_exit( 1, func, 1, __VA_ARGS__ )
+
+// error(func + colon + msg, ...) + goto error
+#define ERROR(...) do { err_func(__func__, __VA_ARGS__); goto error; } while (0)
+#define PERROR(...) do { perr_func(__func__, __VA_ARGS__); goto error; } while (0)
+#define FATAL(...) err_func_exit(__func__, __VA_ARGS__)
+#define PFATAL(...) perr_func_exit(__func__, __VA_ARGS__)
+#define WARNING(...) err_func(__func__, __VA_ARGS__)
+#define PWARNING(...) perr_func(__func__, __VA_ARGS__)
+
+#ifdef DEBUG_ENABLED
+#define DEBUG(...) err_func(__func__, __VA_ARGS__)
+#else
+#define DEBUG(...) (void) (0)
+#endif
+
+// default is to enable INFO
+#ifdef INFO_DISABLED
+ #define INFO_ENABLED 0
+#else
+ #ifndef INFO_ENABLED
+ #define INFO_ENABLED 1
+ #endif
+#endif
+
+#if INFO_ENABLED
+#define INFO(...) info(__VA_ARGS__)
+#else
+#define INFO(...) (void) (0)
+#endif
+