summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/kernel/arch/amd64/driver/fsroot.c2
-rw-r--r--src/kernel/arch/amd64/driver/serial.c2
-rw-r--r--src/kernel/syscalls.c2
-rw-r--r--src/shared/include/camellia/syscalls.h1
-rw-r--r--src/user/app/init/driver/ansiterm.c12
-rw-r--r--src/user/app/init/driver/tmpfs.c9
-rw-r--r--src/user/lib/file.c5
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;