summaryrefslogtreecommitdiff
path: root/src/user/lib/fs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/lib/fs/dir.c')
-rw-r--r--src/user/lib/fs/dir.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/user/lib/fs/dir.c b/src/user/lib/fs/dir.c
index 25ae606..0529bfe 100644
--- a/src/user/lib/fs/dir.c
+++ b/src/user/lib/fs/dir.c
@@ -1,3 +1,4 @@
+#include <camellia/syscalls.h>
#include <errno.h>
#include <string.h>
#include <user/lib/fs/dir.h>
@@ -14,9 +15,13 @@ void dir_start(struct dirbuild *db, long offset, char *buf, size_t buflen) {
}
bool dir_append(struct dirbuild *db, const char *name) {
+ return dir_appendl(db, name, strlen(name));
+}
+
+bool dir_appendl(struct dirbuild *db, const char *name, size_t len) {
if (db->error) return true;
- long len = strlen(name) + 1;
+ len++; // account for the null byte
if (db->offset < len) {
name += db->offset;
@@ -24,7 +29,8 @@ bool dir_append(struct dirbuild *db, const char *name) {
db->offset = 0;
// TODO no buffer overrun check
- memcpy(db->buf + db->bpos, name, len);
+ memcpy(db->buf + db->bpos, name, len - 1);
+ db->buf[db->bpos + len - 1] = '\0';
db->bpos += len;
} else {
db->offset -= len;
@@ -32,6 +38,30 @@ bool dir_append(struct dirbuild *db, const char *name) {
return false;
}
+bool dir_append_from(struct dirbuild *db, handle_t h) {
+ if (db->error) return true;
+
+ if (db->bpos == db->blen)
+ return false;
+
+ int ret = _syscall_read(h, db->buf + db->bpos, db->blen - db->bpos, db->offset);
+ if (ret < 0) {
+ db->error = ret;
+ return true;
+ }
+ if (ret == 0) {
+ // TODO no idea how much we've overread
+ db->error = -ENOSYS;
+ return true;
+ }
+
+ // TODO deduplicate
+
+ db->offset = 0;
+ db->bpos += ret;
+ return false;
+}
+
long dir_finish(struct dirbuild *db) {
return db->error ? db->error : db->bpos;
}