summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2022-07-31 22:46:27 +0200
committerdzwdz2022-07-31 22:46:27 +0200
commit57e7161ce24a63e3e025d82216a15d6a95da0533 (patch)
treec569e8549299b3293a4660042da34dc34300942c
parentd59f6bbcbb01730447d998931e089e0d4a7effb9 (diff)
user/fs: make fs_dir_inject use the fs/dir lib
-rw-r--r--src/user/lib/fs/dir.c34
-rw-r--r--src/user/lib/fs/dir.h3
-rw-r--r--src/user/lib/fs/misc.c41
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: