diff options
author | dzwdz | 2022-06-29 21:52:15 +0200 |
---|---|---|
committer | dzwdz | 2022-06-29 21:52:15 +0200 |
commit | bf4cbc830d78774ac00d9501c45e8b84d0ae9ae7 (patch) | |
tree | f302f92badf74dade9e724e37f85d1ee2dd99833 /src/init | |
parent | 43de6a4d8ead1e609828ef34ad1957d34c94ee6a (diff) |
kernel/vfs: add the OPEN_CREATE flag
Diffstat (limited to 'src/init')
-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 |
10 files changed, 47 insertions, 21 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); } |