diff options
author | dzwdz | 2022-07-11 20:53:03 +0200 |
---|---|---|
committer | dzwdz | 2022-07-11 20:53:03 +0200 |
commit | 6c01d9a7e34e1fccc2775b0e2187ac5e50dd4392 (patch) | |
tree | f047b55ad061c3a1dcd8d9be89e8aaf47c462979 | |
parent | 5c4fb3b3c58a2d850031e9449b5d65887e42f1c7 (diff) |
init: file_reopen, keep stdin/stdout on their standard fds
-rw-r--r-- | src/init/main.c | 22 | ||||
-rw-r--r-- | src/init/stdlib.c | 32 | ||||
-rw-r--r-- | src/init/stdlib.h | 1 |
3 files changed, 40 insertions, 15 deletions
diff --git a/src/init/main.c b/src/init/main.c index 1674f8c..88553e9 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); - stdout = file_open("/com1", 0); + file_reopen(stdout, "/com1", 0); printf("preinit\n"); /* move everything provided by the kernel to /kdev */ @@ -55,12 +55,14 @@ int main(void) { } if (!_syscall_fork(0, NULL)) { - libc_file *new = file_open("/kdev/com1", 0); - if (!new) { + if (!file_reopen(stdout, "/kdev/com1", 0)) { + printf("couldn't open /kdev/com1\n"); // TODO borked + _syscall_exit(1); + } + if (!file_reopen(stdin, "/kdev/com1", 0)) { printf("couldn't open /kdev/com1\n"); _syscall_exit(1); } - stdout = stdin = new; // TODO file_clone, this is bad shell_loop(); _syscall_exit(1); @@ -68,17 +70,11 @@ int main(void) { if (!_syscall_fork(0, NULL)) { - libc_file *new; - new = file_open("/vga_tty", 0); - if (!new) { - printf("couldn't open /vga_tty\n"); + if (!file_reopen(stdout, "/vga_tty", 0)) { + printf("couldn't open /vga_tty\n"); // TODO borked _syscall_exit(1); } - file_close(stdout); - stdout = new; - - stdin = file_open("/keyboard", 0); - if (!stdin) { + if (!file_reopen(stdin, "/keyboard", 0)) { printf("couldn't open /keyboard\n"); _syscall_exit(1); } diff --git a/src/init/stdlib.c b/src/init/stdlib.c index a02eb7c..4d26c2e 100644 --- a/src/init/stdlib.c +++ b/src/init/stdlib.c @@ -2,7 +2,11 @@ #include <shared/printf.h> #include <shared/syscalls.h> -libc_file *stdin, *stdout; +// TODO oh god this garbage - malloc, actually open, [...] +static libc_file _stdin_null = { .fd = 0 }; +static libc_file _stdout_null = { .fd = 1 }; + +libc_file *stdin = &_stdin_null, *stdout = &_stdout_null; static void backend_file(void *arg, const char *buf, size_t len) { file_write((libc_file*)arg, buf, len); @@ -67,6 +71,29 @@ libc_file *file_open(const char *path, int flags) { return f; } +libc_file *file_reopen(libc_file *f, const char *path, int flags) { + /* partially based on the musl implementation of freopen */ + libc_file *f2; + if (!path) goto fail; + f2 = file_open(path, flags); + if (!f2) goto fail; + + /* shouldn't happen, but if it happens, let's roll with it. */ + if (f->fd == f2->fd) f2->fd = -1; + + if (_syscall_dup(f2->fd, f->fd, 0) < 0) goto fail2; + f->pos = f2->pos; + f->eof = f2->eof; + file_close(f2); + return f; + +fail2: + file_close(f2); +fail: + file_close(f); + return NULL; +} + int file_read(libc_file *f, char *buf, size_t len) { if (f->fd < 0) return -1; @@ -88,5 +115,6 @@ int file_write(libc_file *f, const char *buf, size_t len) { void file_close(libc_file *f) { if (f->fd > 0) _syscall_close(f->fd); - free(f); + if (f != &_stdin_null && f != &_stdout_null) + free(f); } diff --git a/src/init/stdlib.h b/src/init/stdlib.h index f7917da..e1e753d 100644 --- a/src/init/stdlib.h +++ b/src/init/stdlib.h @@ -15,6 +15,7 @@ typedef struct { bool eof; } libc_file; libc_file *file_open(const char *path, int flags); +libc_file *file_reopen(libc_file*, const char *path, int flags); 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*); |