diff options
author | dzwdz | 2022-07-31 22:46:27 +0200 |
---|---|---|
committer | dzwdz | 2022-07-31 22:46:27 +0200 |
commit | 57e7161ce24a63e3e025d82216a15d6a95da0533 (patch) | |
tree | c569e8549299b3293a4660042da34dc34300942c /src/user/lib/fs | |
parent | d59f6bbcbb01730447d998931e089e0d4a7effb9 (diff) |
user/fs: make fs_dir_inject use the fs/dir lib
Diffstat (limited to 'src/user/lib/fs')
-rw-r--r-- | src/user/lib/fs/dir.c | 34 | ||||
-rw-r--r-- | src/user/lib/fs/dir.h | 3 | ||||
-rw-r--r-- | src/user/lib/fs/misc.c | 41 |
3 files changed, 50 insertions, 28 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; } diff --git a/src/user/lib/fs/dir.h b/src/user/lib/fs/dir.h index 1a8c7f5..c3bbfe7 100644 --- a/src/user/lib/fs/dir.h +++ b/src/user/lib/fs/dir.h @@ -1,4 +1,5 @@ #pragma once +#include <camellia/types.h> #include <stdbool.h> #include <stddef.h> @@ -11,4 +12,6 @@ struct dirbuild { void dir_start(struct dirbuild *db, long offset, char *buf, size_t buflen); bool dir_append(struct dirbuild *db, const char *name); +bool dir_appendl(struct dirbuild *db, const char *name, size_t len); +bool dir_append_from(struct dirbuild *db, handle_t h); long dir_finish(struct dirbuild *db); diff --git a/src/user/lib/fs/misc.c b/src/user/lib/fs/misc.c index 55ba9a6..0169bfe 100644 --- a/src/user/lib/fs/misc.c +++ b/src/user/lib/fs/misc.c @@ -6,6 +6,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <user/lib/fs/dir.h> #include <user/lib/fs/misc.h> bool fork2_n_mount(const char *path) { @@ -94,7 +95,8 @@ void fs_dir_inject(const char *path) { struct fs_dir_handle *data; const size_t buf_len = 1024; char *buf = malloc(buf_len); - int ret, inject_len; + int inject_len; + struct dirbuild db; if (!buf) exit(1); @@ -113,10 +115,13 @@ void fs_dir_inject(const char *path) { /* inject up to the next slash */ inject_len = 0; - while (data->inject[inject_len] && data->inject[inject_len] != '/') - inject_len++; - if (data->inject[inject_len] == '/') + while (data->inject[inject_len]) { + if (data->inject[inject_len] == '/') { + inject_len++; // include the slash + break; + } inject_len++; + } data->inject_len = inject_len; _syscall_fs_respond(data, 0, 0); @@ -128,33 +133,17 @@ void fs_dir_inject(const char *path) { case VFSOP_CLOSE: if (data->delegate >= 0) close(data->delegate); + free(data); _syscall_fs_respond(NULL, 0, 0); break; case VFSOP_READ: - if (res.offset != 0) _syscall_fs_respond(NULL, -1, 0); // TODO working offsets - - int out_len = data->inject_len; - memcpy(buf, data->inject, out_len); - buf[out_len++] = '\0'; - - if (data->delegate >= 0) { - int to_read = res.capacity < buf_len ? res.capacity : buf_len; - to_read -= out_len; - ret = _syscall_read(data->delegate, buf + out_len, to_read, 0); - if (ret > 0) out_len += ret; - // TODO deduplicate entries - } - - _syscall_fs_respond(buf, out_len, 0); - break; - - case VFSOP_WRITE: + // TODO optimization - min(buf_len, res.capacity) + dir_start(&db, res.offset, buf, buf_len); + dir_appendl(&db, data->inject, data->inject_len); if (data->delegate >= 0) - ret = _syscall_write(data->delegate, buf, res.len, res.offset, res.flags); - else - ret = -1; - _syscall_fs_respond(NULL, ret, 0); + dir_append_from(&db, data->delegate); + _syscall_fs_respond(buf, dir_finish(&db), 0); break; default: |