diff options
-rw-r--r-- | src/kernel/arch/amd64/driver/fsroot.c | 2 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/serial.c | 2 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 2 | ||||
-rw-r--r-- | src/shared/include/camellia/syscalls.h | 1 | ||||
-rw-r--r-- | src/user/app/init/driver/ansiterm.c | 12 | ||||
-rw-r--r-- | src/user/app/init/driver/tmpfs.c | 9 | ||||
-rw-r--r-- | src/user/lib/file.c | 5 |
7 files changed, 20 insertions, 13 deletions
diff --git a/src/kernel/arch/amd64/driver/fsroot.c b/src/kernel/arch/amd64/driver/fsroot.c index c4c3de4..2feaf67 100644 --- a/src/kernel/arch/amd64/driver/fsroot.c +++ b/src/kernel/arch/amd64/driver/fsroot.c @@ -94,6 +94,8 @@ static int handle(struct vfs_request *req) { switch (id) { case HANDLE_VGA: { void *vga = (void*)0xB8000; + if (req->flags) + return -1; fs_normslice(&req->offset, &req->input.len, 80*25*2, false); if (!virt_cpy_from(req->caller->pages, vga + req->offset, req->input.buf, req->input.len)) diff --git a/src/kernel/arch/amd64/driver/serial.c b/src/kernel/arch/amd64/driver/serial.c index 6dda657..93202c2 100644 --- a/src/kernel/arch/amd64/driver/serial.c +++ b/src/kernel/arch/amd64/driver/serial.c @@ -93,7 +93,7 @@ static void accept(struct vfs_request *req) { } break; case VFSOP_WRITE: - if (req->caller) { + if (req->caller && !req->flags) { struct virt_iter iter; virt_iter_new(&iter, req->input.buf, req->input.len, req->caller->pages, true, false); diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 0dec4c5..4537ff5 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -233,7 +233,7 @@ long _syscall_read(handle_t handle_num, void __user *buf, size_t len, long offse long _syscall_write(handle_t handle_num, const void __user *buf, size_t len, long offset, int flags) { struct handle *h = process_handle_get(process_current, handle_num); if (!h) SYSCALL_RETURN(-1); - if (flags != 0) + if (flags & ~(WRITE_TRUNCATE)) SYSCALL_RETURN(-ENOSYS); switch (h->type) { case HANDLE_FILE: diff --git a/src/shared/include/camellia/syscalls.h b/src/shared/include/camellia/syscalls.h index 67bd713..84af276 100644 --- a/src/shared/include/camellia/syscalls.h +++ b/src/shared/include/camellia/syscalls.h @@ -4,6 +4,7 @@ #define FORK_NOREAP 1 #define FORK_NEWFS 2 +#define WRITE_TRUNCATE 1 #define OPEN_CREATE 1 #define FSR_DELEGATE 1 diff --git a/src/user/app/init/driver/ansiterm.c b/src/user/app/init/driver/ansiterm.c index 5daab41..0c720eb 100644 --- a/src/user/app/init/driver/ansiterm.c +++ b/src/user/app/init/driver/ansiterm.c @@ -84,10 +84,14 @@ void ansiterm_drv(void) { break; case VFSOP_WRITE: - for (size_t i = 0; i < res.len; i++) - in_char(buf[i]); - /* if (pendingFlush) */ flush(); - _syscall_fs_respond(NULL, res.len, 0); + if (res.flags) { + _syscall_fs_respond(NULL, -1, 0); + } else { + for (size_t i = 0; i < res.len; i++) + in_char(buf[i]); + /* if (pendingFlush) */ flush(); + _syscall_fs_respond(NULL, res.len, 0); + } break; default: diff --git a/src/user/app/init/driver/tmpfs.c b/src/user/app/init/driver/tmpfs.c index e4c079c..7bda37f 100644 --- a/src/user/app/init/driver/tmpfs.c +++ b/src/user/app/init/driver/tmpfs.c @@ -99,11 +99,7 @@ void tmpfs_drv(void) { _syscall_fs_respond(NULL, -1, 0); break; } - if (res.len == 0) { - _syscall_fs_respond(NULL, 0, 0); - break; - } - if (!ptr->buf) { + if (res.len > 0 && !ptr->buf) { ptr->buf = malloc(256); if (!ptr->buf) { _syscall_fs_respond(NULL, -1, 0); @@ -121,8 +117,9 @@ void tmpfs_drv(void) { } memcpy(ptr->buf + res.offset, buf, res.len); - if (ptr->size < res.offset + res.len) + if ((res.flags & WRITE_TRUNCATE) || ptr->size < res.offset + res.len) { ptr->size = res.offset + res.len; + } _syscall_fs_respond(NULL, res.len, 0); break; diff --git a/src/user/lib/file.c b/src/user/lib/file.c index b7e70e6..bd8cb76 100644 --- a/src/user/lib/file.c +++ b/src/user/lib/file.c @@ -17,13 +17,16 @@ FILE *fopen(const char *path, const char *mode) { int flags = 0; if (mode[0] == 'w' || mode[0] == 'a') flags |= OPEN_CREATE; - // TODO truncate on w h = _syscall_open(path, strlen(path), flags); if (h < 0) { errno = -h; return NULL; } + + if (mode[0] == 'w') + _syscall_write(h, NULL, 0, 0, WRITE_TRUNCATE); + f = fdopen(h, mode); if (!f) close(h); return f; |