From 4c8caaec8e856686581feb0a84089cdad07a0018 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Wed, 3 Aug 2022 13:20:50 +0200 Subject: user/libc: "!files" similar to /dev/{stdin,stdout,stderr} on Linux, except handled by the libc instead of the kernel because that's the simplest way --- src/user/app/shell/builtins.c | 2 +- src/user/lib/file.c | 39 +++++++++++++++++++++++++-------------- src/user/lib/include/stdio.h | 2 +- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/user/app/shell/builtins.c b/src/user/app/shell/builtins.c index e272cf3..d0a2e3a 100644 --- a/src/user/app/shell/builtins.c +++ b/src/user/app/shell/builtins.c @@ -13,7 +13,7 @@ static void cmd_cat(int argc, const char **argv) { if (argv[1]) file = fopen(argv[1], "r"); else - file = file_clone(stdin); + file = file_clone(stdin, "r"); if (!file) { eprintf("couldn't open"); diff --git a/src/user/lib/file.c b/src/user/lib/file.c index b55a19d..ffea99b 100644 --- a/src/user/lib/file.c +++ b/src/user/lib/file.c @@ -18,21 +18,31 @@ FILE *fopen(const char *path, const char *mode) { FILE *f; handle_t h; int flags = 0; - if (mode[0] == 'w' || mode[0] == 'a') - flags |= OPEN_CREATE; - - h = _syscall_open(path, strlen(path), flags); - if (h < 0) { - errno = -h; + if (path && path[0] == '!') { + /* special handling for "!files" */ + path++; + if (!strcmp(path, "stdin")) return file_clone(stdin, mode); + if (!strcmp(path, "stdout")) return file_clone(stdout, mode); + if (!strcmp(path, "stderr")) return file_clone(stderr, mode); + errno = -1; return NULL; - } + } else { + if (mode[0] == 'w' || mode[0] == 'a') + flags |= OPEN_CREATE; - if (mode[0] == 'w') - _syscall_write(h, NULL, 0, 0, WRITE_TRUNCATE); + h = _syscall_open(path, strlen(path), flags); + if (h < 0) { + errno = -h; + return NULL; + } - f = fdopen(h, mode); - if (!f) close(h); - return f; + if (mode[0] == 'w') + _syscall_write(h, NULL, 0, 0, WRITE_TRUNCATE); + + f = fdopen(h, mode); + if (!f) close(h); + return f; + } } FILE *freopen(const char *path, const char *mode, FILE *f) { @@ -70,12 +80,12 @@ FILE *fdopen(int fd, const char *mode) { return f; } -FILE *file_clone(const FILE *f) { +FILE *file_clone(const FILE *f, const char *mode) { handle_t h = _syscall_dup(f->fd, -1, 0); FILE *f2; if (h < 0) return NULL; - f2 = fdopen(h, "r+"); + f2 = fdopen(h, mode); if (!f2) { close(h); return NULL; @@ -105,6 +115,7 @@ size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict f) { return 0; while (pos < total) { + // TODO shouldn't repeat reads long res = _syscall_read(f->fd, buf + pos, total - pos, f->pos); if (res < 0) { f->error = true; diff --git a/src/user/lib/include/stdio.h b/src/user/lib/include/stdio.h index fd4a676..74c5230 100644 --- a/src/user/lib/include/stdio.h +++ b/src/user/lib/include/stdio.h @@ -25,7 +25,7 @@ extern FILE *const stdin, *const stdout, *const stderr; FILE *fopen(const char *path, const char *mode); FILE *freopen(const char *path, const char *mode, FILE *); FILE *fdopen(int fd, const char *mode); -FILE *file_clone(const FILE *); +FILE *file_clone(const FILE *, const char *mode); int fclose(FILE *); int fflush(FILE *f); -- cgit v1.2.3