a working hello
authorTero Marttila <terom@fixme.fi>
Thu, 25 Sep 2008 15:03:09 +0300
changeset 1 b31db3248246
parent 0 487cbfbafa2c
child 2 11757d6b43a6
a working hello
.hgignore
Makefile
src/evfuse.c
src/evfuse.h
src/hello.c
src/helloworld.c
src/lib/common.c
src/lib/common.h
--- /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
+