diff options
-rw-r--r-- | src/init/main.c | 8 | ||||
-rw-r--r-- | src/init/syscalls.c | 8 | ||||
-rw-r--r-- | src/init/tar.c | 14 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 10 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 5 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 1 | ||||
-rw-r--r-- | src/shared/syscalls.h | 5 |
7 files changed, 31 insertions, 20 deletions
diff --git a/src/init/main.c b/src/init/main.c index 66d4b2b..1e2d16f 100644 --- a/src/init/main.c +++ b/src/init/main.c @@ -4,7 +4,7 @@ #include <stdint.h> #define argify(str) str, sizeof(str) - 1 -#define log(str) _syscall_write(tty_fd, argify(str)) +#define log(str) _syscall_write(tty_fd, argify(str), 0) extern char _bss_start; // provided by the linker extern char _bss_end; @@ -34,15 +34,15 @@ void read_file(const char *path, size_t len) { static char buf[64]; int buf_len = 64; - _syscall_write(tty_fd, path, len); + _syscall_write(tty_fd, path, len, 0); log(": "); if (fd < 0) { log("couldn't open.\n"); return; } - buf_len = _syscall_read(fd, buf, buf_len); - _syscall_write(tty_fd, buf, buf_len); + buf_len = _syscall_read(fd, buf, buf_len, 0); + _syscall_write(tty_fd, buf, buf_len, 0); _syscall_close(fd); } diff --git a/src/init/syscalls.c b/src/init/syscalls.c index 7d0fef9..f32594e 100644 --- a/src/init/syscalls.c +++ b/src/init/syscalls.c @@ -22,12 +22,12 @@ int _syscall_mount(handle_t handle, const char __user *path, int len) { return _syscall(_SYSCALL_MOUNT, handle, (int)path, len, 0); } -int _syscall_read(handle_t handle, char __user *buf, int len) { - return _syscall(_SYSCALL_READ, handle, (int)buf, len, 0); +int _syscall_read(handle_t handle, char __user *buf, int len, int offset) { + return _syscall(_SYSCALL_READ, handle, (int)buf, len, offset); } -int _syscall_write(handle_t handle, const char __user *buf, int len) { - return _syscall(_SYSCALL_WRITE, handle, (int)buf, len, 0); +int _syscall_write(handle_t handle, const char __user *buf, int len, int offset) { + return _syscall(_SYSCALL_WRITE, handle, (int)buf, len, offset); } int _syscall_close(handle_t handle) { diff --git a/src/init/tar.c b/src/init/tar.c index 74e4c83..691768c 100644 --- a/src/init/tar.c +++ b/src/init/tar.c @@ -24,7 +24,13 @@ void tar_driver(handle_t back, void *base) { case VFSOP_READ: { void *meta = (void*)res.id; - _syscall_fs_respond(meta + 512, tar_size(meta)); + int size = tar_size(meta); + if (res.offset < 0 || res.offset > size) { + // TODO support negative offsets + _syscall_fs_respond(NULL, -1); + } else { + _syscall_fs_respond(meta + 512 + res.offset, size - res.offset); + } break; } @@ -38,14 +44,14 @@ void tar_driver(handle_t back, void *base) { while (0 == memcmp(base + 257, "ustar", 5)) { int size = oct_parse(base + 124, 12); - _syscall_write(tty_fd, base, 100); - _syscall_write(tty_fd, " ", 1); + _syscall_write(tty_fd, base, 100, 0); + _syscall_write(tty_fd, " ", 1, 0); base += 512; // skip metadata sector base += (size + 511) & ~511; // skip file (size rounded up to 512) // TODO might pagefault if the last sector was at a page boundary } - _syscall_write(tty_fd, "done.", 5); + _syscall_write(tty_fd, "done.", 5, 0); } static int tar_open(const char *path, int len, void *base, size_t base_len) { diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index bc185bd..d321d33 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -136,7 +136,7 @@ fail: return -1; } -int _syscall_read(handle_t handle_num, char __user *buf, int len) { +int _syscall_read(handle_t handle_num, char __user *buf, int len, int offset) { struct handle *handle = &process_current->handles[handle_num]; if (handle_num < 0 || handle_num >= HANDLE_MAX) return -1; if (handle->type != HANDLE_FILE) return -1; @@ -147,12 +147,13 @@ int _syscall_read(handle_t handle_num, char __user *buf, int len) { .len = len, }, .id = handle->file.id, + .offset = offset, .caller = process_current, .backend = handle->file.backend, }); } -int _syscall_write(handle_t handle_num, const char __user *buf, int len) { +int _syscall_write(handle_t handle_num, const char __user *buf, int len, int offset) { struct handle *handle = &process_current->handles[handle_num]; if (handle_num < 0 || handle_num >= HANDLE_MAX) return -1; if (handle->type != HANDLE_FILE) return -1; @@ -163,6 +164,7 @@ int _syscall_write(handle_t handle_num, const char __user *buf, int len) { .len = len, }, .id = handle->file.id, + .offset = offset, .caller = process_current, .backend = handle->file.backend, }); @@ -286,9 +288,9 @@ int _syscall(int num, int a, int b, int c, int d) { case _SYSCALL_MOUNT: return _syscall_mount(a, (userptr_t)b, c); case _SYSCALL_READ: - return _syscall_read(a, (userptr_t)b, c); + return _syscall_read(a, (userptr_t)b, c, d); case _SYSCALL_WRITE: - return _syscall_write(a, (userptr_t)b, c); + return _syscall_write(a, (userptr_t)b, c, d); case _SYSCALL_CLOSE: return _syscall_close(a); case _SYSCALL_FS_CREATE: diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index 33a8458..b197f4b 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -64,8 +64,9 @@ _Noreturn void vfs_request_pass2handler(struct vfs_request *req) { goto fail; // can't copy buffer } - res.len = len; - res.id = req->id; + res.len = len; + res.id = req->id; + res.offset = req->offset; if (!virt_cpy_to(handler->pages, handler->awaited_req.res, &res, sizeof res)) diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index a03fba9..0e96db6 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -34,6 +34,7 @@ struct vfs_request { } output; int id; // handle.file.id + int offset; struct process *caller; struct vfs_backend *backend; diff --git a/src/shared/syscalls.h b/src/shared/syscalls.h index f6ee44f..44a2f5d 100644 --- a/src/shared/syscalls.h +++ b/src/shared/syscalls.h @@ -43,8 +43,8 @@ int _syscall_fork(void); handle_t _syscall_open(const char __user *path, int len); int _syscall_mount(handle_t, const char __user *path, int len); -int _syscall_read(handle_t, char __user *buf, int len); -int _syscall_write(handle_t, const char __user *buf, int len); +int _syscall_read(handle_t, char __user *buf, int len, int offset); +int _syscall_write(handle_t, const char __user *buf, int len, int offset); int _syscall_close(handle_t); /** Creates a pair of front/back filesystem handles. @@ -54,6 +54,7 @@ handle_t _syscall_fs_create(handle_t __user *back); struct fs_wait_response { int len; // how much was put in *buf int id; // file id (returned by the open handler, passed to other calls) + int offset; }; int _syscall_fs_wait(handle_t back, char __user *buf, int max_len, struct fs_wait_response __user *res); |