diff options
-rw-r--r-- | src/init/driver/ansiterm.c | 6 | ||||
-rw-r--r-- | src/init/driver/ps2.c | 6 | ||||
-rw-r--r-- | src/init/fs/misc.c | 11 | ||||
-rw-r--r-- | src/init/main.c | 12 | ||||
-rw-r--r-- | src/init/shell.c | 15 | ||||
-rw-r--r-- | src/init/stdlib.c | 4 | ||||
-rw-r--r-- | src/init/stdlib.h | 2 | ||||
-rw-r--r-- | src/init/syscalls.c | 4 | ||||
-rw-r--r-- | src/init/tar.c | 4 | ||||
-rw-r--r-- | src/init/tests/main.c | 4 | ||||
-rw-r--r-- | src/kernel/arch/i386/driver/fsroot.c | 2 | ||||
-rw-r--r-- | src/kernel/arch/i386/driver/ps2.c | 5 | ||||
-rw-r--r-- | src/kernel/arch/i386/driver/serial.c | 5 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 5 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 1 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 1 | ||||
-rw-r--r-- | src/shared/syscalls.h | 4 |
17 files changed, 63 insertions, 28 deletions
diff --git a/src/init/driver/ansiterm.c b/src/init/driver/ansiterm.c index 01ad984..60aad72 100644 --- a/src/init/driver/ansiterm.c +++ b/src/init/driver/ansiterm.c @@ -56,7 +56,7 @@ static void in_char(char c) { } void ansiterm_drv(void) { - vga_fd = _syscall_open("/vga", 4); + vga_fd = _syscall_open("/vga", 4, 0); _syscall_read(vga_fd, vga, sizeof vga, 0); // find first empty line @@ -78,6 +78,10 @@ void ansiterm_drv(void) { while (!_syscall_fs_wait(buf, sizeof buf, &res)) { switch (res.op) { case VFSOP_OPEN: + if (res.flags & OPEN_CREATE) { + _syscall_fs_respond(NULL, -1); + break; + } // TODO check path _syscall_fs_respond(NULL, 1); break; diff --git a/src/init/driver/ps2.c b/src/init/driver/ps2.c index b2d42e5..0c6d548 100644 --- a/src/init/driver/ps2.c +++ b/src/init/driver/ps2.c @@ -51,6 +51,10 @@ static void main_loop(void) { while (!_syscall_fs_wait(buf, sizeof buf, &res)) { switch (res.op) { case VFSOP_OPEN: + if (res.flags & OPEN_CREATE) { + _syscall_fs_respond(NULL, -1); + break; + } _syscall_fs_respond(NULL, 1); break; @@ -74,7 +78,7 @@ static void main_loop(void) { } void ps2_drv(void) { - fd = _syscall_open("/ps2", 4); + fd = _syscall_open("/ps2", 4, 0); if (fd < 0) _syscall_exit(1); main_loop(); diff --git a/src/init/fs/misc.c b/src/init/fs/misc.c index f4965d5..914cfb2 100644 --- a/src/init/fs/misc.c +++ b/src/init/fs/misc.c @@ -105,10 +105,10 @@ void fs_passthru(const char *prefix) { memcpy(tmp, buf, res.len); memcpy(buf, prefix, prefix_len); memcpy(buf + prefix_len, tmp, res.len); - ret = _syscall_open(buf, res.len + prefix_len); + ret = _syscall_open(buf, res.len + prefix_len, res.flags); } else ret = -1; } else { - ret = _syscall_open(buf, res.len); + ret = _syscall_open(buf, res.len, res.flags); } _syscall_fs_respond(NULL, ret); break; @@ -147,7 +147,7 @@ void fs_dir_inject(const char *path) { } if (hid < 0) _syscall_fs_respond(NULL, -2); // we ran out of handles - ret = _syscall_open(buf, res.len); /* errors handled in inject handler */ + ret = _syscall_open(buf, res.len, res.flags); /* errors handled in inject handler */ handles[hid].delegate = ret; handles[hid].inject = NULL; handles[hid].taken = true; @@ -155,9 +155,12 @@ void fs_dir_inject(const char *path) { if (buf[res.len - 1] == '/' && res.len < path_len && !memcmp(path, buf, res.len)) { handles[hid].inject = path + res.len; + + /* if we're making up the opened directory, disallow create */ + if (ret < 0 && (res.flags & OPEN_CREATE)) hid = ret; } else { /* not injecting, don't allow opening nonexistent stuff */ - if (ret < 0) _syscall_fs_respond(NULL, ret); + if (ret < 0) hid = ret; } _syscall_fs_respond(NULL, hid); break; diff --git a/src/init/main.c b/src/init/main.c index 998db9c..198bd88 100644 --- a/src/init/main.c +++ b/src/init/main.c @@ -19,7 +19,7 @@ int main(void) { // allocate bss _syscall_memflag(&_bss_start, &_bss_end - &_bss_start, MEMFLAG_PRESENT); - file_open(&__stdout, "/com1"); + file_open(&__stdout, "/com1", 0); printf("preinit\n"); MOUNT("/init/", tar_driver(&_initrd)); @@ -48,7 +48,7 @@ int main(void) { } if (!_syscall_fork(0, NULL)) { - if (file_open(&__stdout, "/com1") < 0 || file_open(&__stdin, "/com1") < 0) + if (file_open(&__stdout, "/com1", 0) < 0 || file_open(&__stdin, "/com1", 0) < 0) _syscall_exit(1); shell_loop(); @@ -57,10 +57,10 @@ int main(void) { if (!_syscall_fork(0, NULL)) { - if (file_open(&__stdout, "/vga_tty") < 0) + if (file_open(&__stdout, "/vga_tty", 0) < 0) _syscall_exit(1); - if (file_open(&__stdin, "/keyboard") < 0) { + if (file_open(&__stdin, "/keyboard", 0) < 0) { printf("couldn't open /keyboard\n"); _syscall_exit(1); } @@ -71,8 +71,8 @@ int main(void) { // try to find any working output - if (file_open(&__stdout, "/com1") < 0) - file_open(&__stdout, "/vga_tty"); + if (file_open(&__stdout, "/com1", 0) < 0) + file_open(&__stdout, "/vga_tty", 0); _syscall_await(); printf("init: quitting\n"); diff --git a/src/init/shell.c b/src/init/shell.c index 105231e..edcd480 100644 --- a/src/init/shell.c +++ b/src/init/shell.c @@ -63,7 +63,7 @@ static void cmd_cat_ls(const char *args, bool ls) { } } - if (file_open(&file, buf) < 0) { + if (file_open(&file, buf, 0) < 0) { printf("couldn't open.\n"); return; } @@ -85,7 +85,7 @@ static void cmd_hexdump(const char *args) { static uint8_t buf[512]; int fd, len; - fd = _syscall_open(args, strlen(args)); + fd = _syscall_open(args, strlen(args), 0); if (fd < 0) { printf("couldn't open.\n"); return; @@ -113,6 +113,15 @@ static void cmd_hexdump(const char *args) { _syscall_close(fd); } +static void cmd_touch(const char *args) { + int fd = _syscall_open(args, strlen(args), OPEN_CREATE); + if (fd < 0) { + printf("couldn't create file.\n"); + return; + } + _syscall_close(fd); +} + void shell_loop(void) { static char cmd[256]; int level = 0; @@ -140,6 +149,8 @@ void shell_loop(void) { cmd_cat_ls(files[i], false); printf("\n"); } + } else if (!strcmp(cmd, "touch")) { + cmd_touch(args); } else if (!strcmp(cmd, "shadow")) { _syscall_mount(-1, args, strlen(args)); } else if (!strcmp(cmd, "exit")) { diff --git a/src/init/stdlib.c b/src/init/stdlib.c index f59635e..9b7a329 100644 --- a/src/init/stdlib.c +++ b/src/init/stdlib.c @@ -18,10 +18,10 @@ int printf(const char *fmt, ...) { return ret; } -int file_open(libc_file *f, const char *path) { +int file_open(libc_file *f, const char *path, int flags) { f->pos = 0; f->eof = false; - f->fd = _syscall_open(path, strlen(path)); + f->fd = _syscall_open(path, strlen(path), flags); if (f->fd < 0) return f->fd; return 0; } diff --git a/src/init/stdlib.h b/src/init/stdlib.h index b1709e0..3dc1c81 100644 --- a/src/init/stdlib.h +++ b/src/init/stdlib.h @@ -11,7 +11,7 @@ typedef struct { int pos; bool eof; } libc_file; -int file_open(libc_file*, const char *path); // TODO return a libc_file* +int file_open(libc_file*, const char *path, int flags); // TODO return a libc_file* int file_read(libc_file*, char *buf, size_t len); int file_write(libc_file*, const char *buf, size_t len); void file_close(libc_file*); diff --git a/src/init/syscalls.c b/src/init/syscalls.c index 7c3664c..e48043f 100644 --- a/src/init/syscalls.c +++ b/src/init/syscalls.c @@ -18,8 +18,8 @@ int _syscall_fork(int flags, handle_t __user *fs_front) { return _syscall(_SYSCALL_FORK, flags, (int)fs_front, 0, 0); } -handle_t _syscall_open(const char __user *path, int len) { - return _syscall(_SYSCALL_OPEN, (int)path, len, 0, 0); +handle_t _syscall_open(const char __user *path, int len, int flags) { + return _syscall(_SYSCALL_OPEN, (int)path, len, flags, 0); } int _syscall_mount(handle_t h, const char __user *path, int len) { diff --git a/src/init/tar.c b/src/init/tar.c index c289edc..ce8c066 100644 --- a/src/init/tar.c +++ b/src/init/tar.c @@ -21,6 +21,10 @@ void tar_driver(void *base) { while (!_syscall_fs_wait(buf, BUF_SIZE, &res)) { switch (res.op) { case VFSOP_OPEN: + if (res.flags & OPEN_CREATE) { + _syscall_fs_respond(NULL, -1); + break; + } _syscall_fs_respond(NULL, tar_open(buf, res.len, base, ~0)); break; diff --git a/src/init/tests/main.c b/src/init/tests/main.c index d895289..1260a35 100644 --- a/src/init/tests/main.c +++ b/src/init/tests/main.c @@ -74,7 +74,7 @@ static void test_interrupted_fs(void) { _syscall_exit(0); } else { /* parent */ _syscall_mount(h, "/", 1); - int ret = _syscall_open("/", 1); + int ret = _syscall_open("/", 1, 0); // the handler quits while handling that call - but this syscall should return anyways _syscall_exit(ret < 0 ? 0 : -1); } @@ -86,7 +86,7 @@ static void test_orphaned_fs(void) { _syscall_exit(0); } else { /* parent */ _syscall_mount(h, "/", 1); - int ret = _syscall_open("/", 1); + int ret = _syscall_open("/", 1, 0); // no handler will ever be available to handle this call - the syscall should instantly return _syscall_exit(ret < 0 ? 0 : -1); } diff --git a/src/kernel/arch/i386/driver/fsroot.c b/src/kernel/arch/i386/driver/fsroot.c index e6e53cd..4207541 100644 --- a/src/kernel/arch/i386/driver/fsroot.c +++ b/src/kernel/arch/i386/driver/fsroot.c @@ -47,6 +47,8 @@ static int handle(struct vfs_request *req) { assert(req->caller); switch (req->type) { case VFSOP_OPEN: + if (req->flags & OPEN_CREATE) return -1; + if (exacteq(req, "/")) return HANDLE_ROOT; if (exacteq(req, "/vga")) return HANDLE_VGA; diff --git a/src/kernel/arch/i386/driver/ps2.c b/src/kernel/arch/i386/driver/ps2.c index b7e82eb..e1e97c0 100644 --- a/src/kernel/arch/i386/driver/ps2.c +++ b/src/kernel/arch/i386/driver/ps2.c @@ -31,10 +31,11 @@ static void accept(struct vfs_request *req) { // when you fix something here go also fix it in the COM1 driver static uint8_t buf[32]; // pretty damn stupid int ret; + bool valid; switch (req->type) { case VFSOP_OPEN: - ret = req->input.len == 0 ? 0 : -1; - vfsreq_finish(req, 0); + valid = req->input.len == 0 && !(req->flags & OPEN_CREATE); + vfsreq_finish(req, valid ? 0 : -1); break; case VFSOP_READ: if (ring_size((void*)&backlog) == 0) { diff --git a/src/kernel/arch/i386/driver/serial.c b/src/kernel/arch/i386/driver/serial.c index cda016c..b776d0c 100644 --- a/src/kernel/arch/i386/driver/serial.c +++ b/src/kernel/arch/i386/driver/serial.c @@ -69,10 +69,11 @@ void serial_write(const char *buf, size_t len) { static void accept(struct vfs_request *req) { static char buf[32]; int ret; + bool valid; switch (req->type) { case VFSOP_OPEN: - ret = req->input.len == 0 ? 0 : -1; - vfsreq_finish(req, 0); + valid = req->input.len == 0 && !(req->flags & OPEN_CREATE); + vfsreq_finish(req, valid ? 0 : -1); break; case VFSOP_READ: if (ring_size((void*)&backlog) == 0) { diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 0d18af8..7040f6b 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -79,7 +79,7 @@ int _syscall_fork(int flags, handle_t __user *fs_front) { SYSCALL_RETURN(1); } -handle_t _syscall_open(const char __user *path, int len) { +handle_t _syscall_open(const char __user *path, int len, int flags) { struct vfs_mount *mount; char *path_buf = NULL; @@ -114,6 +114,7 @@ handle_t _syscall_open(const char __user *path, int len) { }, .caller = process_current, .backend = mount->backend, + .flags = flags, }); return -1; // dummy fail: @@ -300,7 +301,7 @@ int _syscall(int num, int a, int b, int c, int d) { _syscall_fork(a, (userptr_t)b); break; case _SYSCALL_OPEN: - _syscall_open((userptr_t)a, b); + _syscall_open((userptr_t)a, b, c); break; case _SYSCALL_MOUNT: _syscall_mount(a, (userptr_t)b, c); diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index 30c0e77..4ee5986 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -113,6 +113,7 @@ void vfs_backend_user_accept(struct vfs_request *req) { res.capacity = req->output.len; res.id = req->id; res.offset = req->offset; + res.flags = req->flags; res.op = req->type; if (!virt_cpy_to(handler->pages, diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index e034bc6..cad0981 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -49,6 +49,7 @@ struct vfs_request { int id; // handle.file.id int offset; + int flags; struct process *caller; struct vfs_backend *backend; diff --git a/src/shared/syscalls.h b/src/shared/syscalls.h index 5d98429..403d02c 100644 --- a/src/shared/syscalls.h +++ b/src/shared/syscalls.h @@ -4,6 +4,7 @@ #define FORK_NOREAP 1 #define FORK_NEWFS 2 +#define OPEN_CREATE 1 enum { // idc about stable syscall numbers just yet @@ -47,7 +48,7 @@ int _syscall_await(void); */ int _syscall_fork(int flags, handle_t __user *fs_front); -handle_t _syscall_open(const char __user *path, int len); +handle_t _syscall_open(const char __user *path, int len, int flags); int _syscall_mount(handle_t h, const char __user *path, int len); int _syscall_read(handle_t h, void __user *buf, size_t len, int offset); @@ -60,6 +61,7 @@ struct fs_wait_response { size_t capacity; // how much output can be accepted by the caller int id; // file id (returned by the open handler, passed to other calls) int offset; + int flags; }; /** Blocks until an fs request is made. * @return 0 if everything was successful */ |