summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2021-09-20 19:30:37 +0200
committerdzwdz2021-09-20 19:30:37 +0200
commit6371724809b057b25a4efd6c022e7d95068c42f1 (patch)
tree5cc6484ae767cd27f2ae4ccd24c0fb01e9beb163 /src
parent9a08099fb7148a69b0655f0e559661b1021b17b5 (diff)
add an offset parameter to read() and write()
Diffstat (limited to 'src')
-rw-r--r--src/init/main.c8
-rw-r--r--src/init/syscalls.c8
-rw-r--r--src/init/tar.c14
-rw-r--r--src/kernel/syscalls.c10
-rw-r--r--src/kernel/vfs/request.c5
-rw-r--r--src/kernel/vfs/request.h1
-rw-r--r--src/shared/syscalls.h5
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);