summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/user/driver/tmpfs.c82
1 files changed, 60 insertions, 22 deletions
diff --git a/src/user/driver/tmpfs.c b/src/user/driver/tmpfs.c
index 225204b..80c0196 100644
--- a/src/user/driver/tmpfs.c
+++ b/src/user/driver/tmpfs.c
@@ -5,8 +5,10 @@
struct node {
const char *name;
- size_t len;
+ size_t namelen;
struct node *next;
+ char *buf;
+ size_t size, capacity;
};
struct node *root = NULL;
@@ -14,7 +16,7 @@ static struct node special_root;
static struct node *lookup(const char *path, size_t len) {
for (struct node *iter = root; iter; iter = iter->next) {
- if (iter->len == len && !memcmp(path, iter->name, len))
+ if (iter->namelen == len && !memcmp(path, iter->name, len))
return iter;
}
return NULL;
@@ -33,10 +35,12 @@ static struct node *tmpfs_open(const char *path, struct fs_wait_response *res) {
if (res->flags & OPEN_CREATE) {
if (lookup(path, res->len)) return NULL; /* already exists */
struct node *new = malloc(sizeof *new);
+ memset(new, 0, sizeof *new);
+
char *namebuf = malloc(res->len);
memcpy(namebuf, path, res->len);
new->name = namebuf;
- new->len = res->len;
+ new->namelen = res->len;
new->next = root;
root = new;
return new;
@@ -58,31 +62,65 @@ void tmpfs_drv(void) {
break;
case VFSOP_READ:
- if (res.id != &special_root) {
- // rw unimplemented
- _syscall_fs_respond(NULL, -1, 0);
- break;
- }
- size_t buf_pos = 0;
- size_t to_skip = res.offset;
+ ptr = (void*)res.id;
+ if (ptr == &special_root) {
+ size_t buf_pos = 0;
+ size_t to_skip = res.offset;
- for (struct node *iter = root; iter; iter = iter->next) {
- if (iter->len <= to_skip) {
- to_skip -= iter->len;
- continue;
+ for (struct node *iter = root; iter; iter = iter->next) {
+ if (iter->namelen <= to_skip) {
+ to_skip -= iter->namelen;
+ continue;
+ }
+
+ if (iter->namelen + buf_pos - to_skip >= sizeof(buf)) {
+ memcpy(buf + buf_pos, iter->name + to_skip, sizeof(buf) - buf_pos - to_skip);
+ buf_pos = sizeof(buf);
+ break;
+ }
+ memcpy(buf + buf_pos, iter->name + to_skip, iter->namelen - to_skip);
+ buf_pos += iter->namelen - to_skip;
+ buf[buf_pos++] = '\0';
+ to_skip = 0;
}
+ _syscall_fs_respond(buf, buf_pos, 0);
+ } else {
+ // TODO offset
+ if (res.offset)
+ _syscall_fs_respond(NULL, 0, 0);
+ else
+ _syscall_fs_respond(ptr->buf, ptr->size, 0);
+ break;
+ }
+ break;
- if (iter->len + buf_pos - to_skip >= sizeof(buf)) {
- memcpy(buf + buf_pos, iter->name + to_skip, sizeof(buf) - buf_pos - to_skip);
- buf_pos = sizeof(buf);
+ case VFSOP_WRITE:
+ ptr = (void*)res.id;
+ if (ptr == &special_root) {
+ _syscall_fs_respond(NULL, -1, 0);
+ break;
+ }
+ if (res.len == 0) {
+ _syscall_fs_respond(NULL, 0, 0);
+ break;
+ }
+ if (!ptr->buf) {
+ ptr->buf = malloc(256);
+ if (!ptr->buf) {
+ _syscall_fs_respond(NULL, -1, 0);
break;
}
- memcpy(buf + buf_pos, iter->name + to_skip, iter->len - to_skip);
- buf_pos += iter->len - to_skip;
- buf[buf_pos++] = '\0';
- to_skip = 0;
+ memset(ptr->buf, 0, 256);
+ ptr->capacity = 256;
}
- _syscall_fs_respond(buf, buf_pos, 0);
+
+ size_t len = res.len;
+ if (len > ptr->capacity - res.offset)
+ len = ptr->capacity - res.offset;
+ memcpy(ptr->buf + res.offset, buf, len);
+ if (ptr->size < res.offset + len)
+ ptr->size = res.offset + len;
+ _syscall_fs_respond(NULL, len, 0);
break;
default: