--- 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