diff options
-rw-r--r-- | src/kernel/arch/amd64/driver/fsroot.c | 4 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 16 | ||||
-rw-r--r-- | src/shared/include/camellia/syscalls.h | 2 | ||||
-rw-r--r-- | src/shared/include/camellia/types.h | 1 | ||||
-rw-r--r-- | src/user/app/init/driver/tmpfs.c | 9 | ||||
-rw-r--r-- | src/user/app/shell/builtins.c | 18 | ||||
-rw-r--r-- | src/user/bootstrap/tar.c | 5 | ||||
-rw-r--r-- | src/user/lib/syscall.c | 4 |
8 files changed, 56 insertions, 3 deletions
diff --git a/src/kernel/arch/amd64/driver/fsroot.c b/src/kernel/arch/amd64/driver/fsroot.c index 41fe136..0970d0b 100644 --- a/src/kernel/arch/amd64/driver/fsroot.c +++ b/src/kernel/arch/amd64/driver/fsroot.c @@ -76,8 +76,8 @@ static int handle(struct vfs_request *req) { default: panic_invalid_state(); } - case VFSOP_CLOSE: - return 0; + case VFSOP_CLOSE: return 0; + case VFSOP_GETSIZE: return -ENOSYS; default: panic_invalid_state(); } diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 3096c42..07e2e36 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -263,6 +263,19 @@ long _syscall_write(handle_t handle_num, const void __user *buf, size_t len, lon return -1; // dummy } +long _syscall_getsize(handle_t hid) { + struct handle *h = process_handle_get(process_current, hid); + if (!h) SYSCALL_RETURN(-1); + if (h->type != HANDLE_FILE) SYSCALL_RETURN(-2); + vfsreq_create((struct vfs_request) { + .type = VFSOP_GETSIZE, + .id = h->file_id, + .caller = process_current, + .backend = h->backend, + }); + return -1; // dummy +} + long _syscall_close(handle_t hid) { if (hid < 0 || hid >= HANDLE_MAX) return -1; struct handle **h = &process_current->handles[hid]; @@ -424,6 +437,9 @@ long _syscall(long num, long a, long b, long c, long d, long e) { case _SYSCALL_WRITE: _syscall_write(a, (userptr_t)b, c, d, e); break; + case _SYSCALL_GETSIZE: + _syscall_getsize(a); + break; case _SYSCALL_CLOSE: _syscall_close(a); break; diff --git a/src/shared/include/camellia/syscalls.h b/src/shared/include/camellia/syscalls.h index 40cb68d..ade75a5 100644 --- a/src/shared/include/camellia/syscalls.h +++ b/src/shared/include/camellia/syscalls.h @@ -20,6 +20,7 @@ enum { _SYSCALL_READ, _SYSCALL_WRITE, + _SYSCALL_GETSIZE, _SYSCALL_CLOSE, _SYSCALL_FS_FORK2, @@ -63,6 +64,7 @@ handle_t _syscall_dup(handle_t from, handle_t to, int flags); long _syscall_read(handle_t h, void __user *buf, size_t len, long offset); long _syscall_write(handle_t h, const void __user *buf, size_t len, long offset, int flags); +long _syscall_getsize(handle_t h); long _syscall_close(handle_t h); struct fs_wait_response { diff --git a/src/shared/include/camellia/types.h b/src/shared/include/camellia/types.h index f47e1bb..cb17b3a 100644 --- a/src/shared/include/camellia/types.h +++ b/src/shared/include/camellia/types.h @@ -16,5 +16,6 @@ enum vfs_operation { VFSOP_OPEN, VFSOP_READ, VFSOP_WRITE, + VFSOP_GETSIZE, VFSOP_CLOSE, }; diff --git a/src/user/app/init/driver/tmpfs.c b/src/user/app/init/driver/tmpfs.c index 96fdf39..7414320 100644 --- a/src/user/app/init/driver/tmpfs.c +++ b/src/user/app/init/driver/tmpfs.c @@ -15,7 +15,9 @@ struct node { }; struct node *root = NULL; -static struct node special_root; +static struct node special_root = { + .size = 0, +}; static struct node *lookup(const char *path, size_t len) { for (struct node *iter = root; iter; iter = iter->next) { @@ -109,6 +111,11 @@ void tmpfs_drv(void) { _syscall_fs_respond(NULL, res.len, 0); break; + case VFSOP_GETSIZE: + ptr = (void*)res.id; + _syscall_fs_respond(NULL, ptr->size, 0); + break; + default: _syscall_fs_respond(NULL, -1, 0); break; diff --git a/src/user/app/shell/builtins.c b/src/user/app/shell/builtins.c index d409bfd..53534ed 100644 --- a/src/user/app/shell/builtins.c +++ b/src/user/app/shell/builtins.c @@ -48,6 +48,23 @@ static void cmd_echo(int argc, char **argv) { printf("\n"); } +void cmd_getsize(int argc, char **argv) { + if (argc < 2) { + eprintf("missing arguments"); + return; + } + + for (int i = 1; i < argc; i++) { + handle_t h = _syscall_open(argv[i], strlen(argv[i]), 0); + if (h < 0) { + eprintf("error opening %s", argv[i]); + continue; + } + printf("%s: %d\n", argv[i], (int)_syscall_getsize(h)); + _syscall_close(h); + } +} + void cmd_hexdump(int argc, char **argv) { const size_t buflen = 512; uint8_t *buf = malloc(buflen); @@ -141,6 +158,7 @@ static void cmd_touch(int argc, char **argv) { struct builtin builtins[] = { {"cat", cmd_cat}, {"echo", cmd_echo}, + {"getsize", cmd_getsize}, {"hexdump", cmd_hexdump}, {"ls", cmd_ls}, {"sleep", cmd_sleep}, diff --git a/src/user/bootstrap/tar.c b/src/user/bootstrap/tar.c index 150a993..0356987 100644 --- a/src/user/bootstrap/tar.c +++ b/src/user/bootstrap/tar.c @@ -33,6 +33,11 @@ void tar_driver(void *base) { tar_read(&res, base, ~0); break; + case VFSOP_GETSIZE: + // TODO works weirdly on directories / the root dir + _syscall_fs_respond(NULL, tar_size(res.id), 0); + break; + default: _syscall_fs_respond(NULL, -1, 0); // unsupported break; diff --git a/src/user/lib/syscall.c b/src/user/lib/syscall.c index ffda454..e22f718 100644 --- a/src/user/lib/syscall.c +++ b/src/user/lib/syscall.c @@ -38,6 +38,10 @@ long _syscall_write(handle_t h, const void __user *buf, size_t len, long offset, return _syscall(_SYSCALL_WRITE, (long)h, (long)buf, (long)len, offset, (long)flags); } +long _syscall_getsize(handle_t h) { + return _syscall(_SYSCALL_GETSIZE, (long)h, 0, 0, 0, 0); +} + long _syscall_close(handle_t h) { return _syscall(_SYSCALL_CLOSE, (long)h, 0, 0, 0, 0); } |