split off the dirbuf stuff into its own module
authorTero Marttila <terom@fixme.fi>
Fri, 26 Sep 2008 20:39:51 +0300
changeset 7 3a603d755bcb
parent 6 d2036d7799fd
child 8 21bb5cdca4db
split off the dirbuf stuff into its own module
Makefile
src/dirbuf.c
src/dirbuf.h
src/hello.c
--- a/Makefile	Fri Sep 26 20:11:22 2008 +0300
+++ b/Makefile	Fri Sep 26 20:39:51 2008 +0300
@@ -12,8 +12,8 @@
 BIN_NAMES = hello helloworld
 
 bin/helloworld: 
-bin/hello: obj/evfuse.o obj/lib/log.o obj/lib/signals.o
-bin/simple_hello: obj/evfuse.o obj/lib/log.o obj/lib/signals.o obj/simple.o
+bin/hello: obj/evfuse.o obj/dirbuf.o obj/lib/log.o obj/lib/signals.o
+bin/simple_hello: obj/evfuse.o obj/dirbuf.o obj/lib/log.o obj/lib/signals.o obj/simple.o
 
 # computed
 LDFLAGS = ${LIBRARY_PATHS} ${LIBRARY_LIST}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dirbuf.c	Fri Sep 26 20:39:51 2008 +0300
@@ -0,0 +1,68 @@
+
+#include <stdlib.h>
+
+#include "dirbuf.h"
+#include "lib/log.h"
+#include "lib/math.h"
+
+int dirbuf_init (struct dirbuf *buf, size_t req_size) {
+    buf->len = req_size;
+    buf->off = 0;
+    
+    INFO("\tdirbuf.init: req_size=%zu", req_size);
+
+    // allocate the mem
+    if ((buf->buf = malloc(buf->len)) == NULL)
+        ERROR("malloc");
+    
+    // ok
+    return 0;
+
+error:
+    return -1;
+}
+
+int dirbuf_add (fuse_req_t req, off_t req_off, struct dirbuf *buf, off_t ent_off, off_t next_off, const char *ent_name, fuse_ino_t ent_ino, mode_t ent_mode) {
+    struct stat stbuf;
+    size_t ent_size;
+
+    INFO("\tdirbuf.add: req_off=%zu, buf->len=%zu, buf->off=%zu, ent_off=%zu, next_off=%zu, ent_name=`%s`, ent_ino=%lu, ent_mode=%07o",
+        req_off, buf->len, buf->off, ent_off, next_off, ent_name, ent_ino, ent_mode);
+    
+    // skip entries as needed
+    if (ent_off < req_off) 
+        return 0;
+
+    // set ino
+    stbuf.st_ino = ent_ino;
+    stbuf.st_mode = ent_mode;
+    
+    // try and add the dirent, and see if it fits
+    if ((ent_size = fuse_add_direntry(req, buf->buf + buf->off, buf->len - buf->off, ent_name, &stbuf, next_off)) > (buf->len - buf->off)) {
+        // 'tis full
+        return 1;
+
+    } else {
+        // it fit
+        buf->off += ent_size;
+    }
+
+    // success
+    return 0;
+}
+
+int dirbuf_done (fuse_req_t req, struct dirbuf *buf) {
+    int err;
+    
+    // send the reply, return the error later
+    err = fuse_reply_buf(req, buf->buf, buf->off);
+
+    INFO("\tdirbuf.done: size=%zu/%zu, err=%d", buf->off, buf->len, err);
+
+    // free the dirbuf
+    free(buf->buf);
+
+    // return the error code
+    return err;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dirbuf.h	Fri Sep 26 20:39:51 2008 +0300
@@ -0,0 +1,44 @@
+#ifndef DIRBUF_H
+#define DIRBUF_H
+
+/*
+ * Simple dirent building
+ */
+
+#include "evfuse.h"
+
+/*
+ * Holds the dir entries
+ */ 
+struct dirbuf {
+    char *buf;
+    size_t len;
+    size_t off;
+};
+
+
+/*
+ * Initialize a dirbuf for a request. The dirbuf will be filled with at most req_size bytes of dir entries.
+ */
+int dirbuf_init (struct dirbuf *buf, size_t req_size);
+
+/*
+ * Add an dir entry to the dirbuf. The dirbuf should not be full.
+ *
+ * Offsets are followed:
+ *  req_off     - the offset of the first dirent to include
+ *  ent_off     - the offset of this dirent
+ *  next_off    - the offset of the next dirent
+ *
+ * Only the S_IFMT bits of ent_mode are relevant.
+ *
+ * Returns 0 if the ent was added or skipped, -1 on error, 1 if the dirbuf is full (no more ents should be added).
+ */
+int dirbuf_add (fuse_req_t req, off_t req_off, struct dirbuf *buf, off_t ent_off, off_t next_off, const char *ent_name, fuse_ino_t ent_ino, mode_t ent_mode);
+
+/*
+ * Attempt to send the readdir reply, free the buf, and return the error code from fuse_reply_buf
+ */
+int dirbuf_done (fuse_req_t req, struct dirbuf *buf);
+
+#endif /* DIRBUF_H */
--- a/src/hello.c	Fri Sep 26 20:11:22 2008 +0300
+++ b/src/hello.c	Fri Sep 26 20:39:51 2008 +0300
@@ -9,6 +9,7 @@
 #include "lib/math.h"
 #include "lib/signals.h"
 #include "evfuse.h"
+#include "dirbuf.h"
 
 const char *file_name = "hello";
 const char *file_data = "Hello World\n";
@@ -81,73 +82,6 @@
     fuse_reply_attr(req, &stbuf, 1.0);
 }
 
-struct dirbuf {
-    char *buf;
-    size_t len;
-    size_t off;
-};
-
-static int dirbuf_init (struct dirbuf *buf, size_t req_size) {
-    buf->len = req_size;
-    buf->off = 0;
-    
-    // allocate the mem
-    if ((buf->buf = malloc(buf->len)) == NULL)
-        ERROR("malloc");
-    
-    // ok
-    return 0;
-
-error:
-    return -1;
-}
-
-/*
- * Add an ent to the dirbuf. This will assume that the dirbuf is not already full
- * Returns 0 if the ent was added or skipped, -1 on error, 1 if the dirbuf is full
- */
-static int dirbuf_add (fuse_req_t req, size_t req_size, off_t req_off, struct dirbuf *buf, off_t ent_off, off_t next_off, const char *ent_name, fuse_ino_t ent_ino) {
-    struct stat stbuf;
-    size_t ent_size;
-
-    INFO("\thello.dirbuf_add: req_size=%zu, req_off=%zu, buf->len=%zu, buf->off=%zu, ent_off=%zu, next_off=%zu, ent_name=`%s`, ent_ino=%lu",
-        req_size, req_off, buf->len, buf->off, ent_off, next_off, ent_name, ent_ino);
-    
-    // skip entries as needed
-    if (ent_off < req_off) 
-        return 0;
-
-    // set ino
-    stbuf.st_ino = ent_ino;
-
-    // add the dirent and update dirbuf until it fits
-    if ((ent_size = fuse_add_direntry(req, buf->buf + buf->off, buf->len - buf->off, ent_name, &stbuf, next_off)) > (buf->len - buf->off)) {
-        // 'tis full
-        return 1;
-
-    } else {
-        // it fit
-        buf->off += ent_size;
-    }
-
-    // success
-    return 0;
-}
-
-static int dirbuf_done (fuse_req_t req, struct dirbuf *buf, size_t req_size) {
-    int err;
-    
-    // send the reply, return the error later
-    err = fuse_reply_buf(req, buf->buf, MIN(buf->off, req_size));
-
-    INFO("\thello.dirbuf_done: MIN(%zu, %zu)=%zu, err=%d", buf->off, req_size, MIN(buf->off, req_size), err);
-
-    // free the dirbuf
-    free(buf->buf);
-
-    // return the error code
-    return err;
-}
 
 void hello_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) {
     int err = 0;
@@ -165,15 +99,15 @@
     if (dirbuf_init(&buf, size))
         ERROR("failed to init dirbuf");
 
-    err =   dirbuf_add(req, size, off, &buf, 0, 1,  ".",        1)
-        ||  dirbuf_add(req, size, off, &buf, 1, 2,  "..",       1)
-        ||  dirbuf_add(req, size, off, &buf, 2, 3,  file_name,  2);
+    err =   dirbuf_add(req, off, &buf, 0, 1,  ".",        1,    S_IFDIR )
+        ||  dirbuf_add(req, off, &buf, 1, 2,  "..",       1,    S_IFDIR )
+        ||  dirbuf_add(req, off, &buf, 2, 3,  file_name,  2,    S_IFREG );
 
     if (err < 0)
         ERROR("failed to add dirents to buf");
     
     // send it
-    if ((err = -dirbuf_done(req, &buf, size)))
+    if ((err = -dirbuf_done(req, &buf)))
         EERROR(-err, "failed to send buf");
 
     // success