From 6a279840b778869d8a80b6ef179d0114de12d0d4 Mon Sep 17 00:00:00 2001 From: Minep Date: Tue, 9 Aug 2022 13:34:37 +0100 Subject: [PATCH 1/1] feat: stdin/stdout into process --- lunaix-os/includes/lunaix/fs.h | 3 +++ lunaix-os/kernel/demos/iotest.c | 28 +++++++++++++--------------- lunaix-os/kernel/fs/vfs.c | 18 +++++++++++++----- lunaix-os/kernel/proc0.c | 7 +++++++ lunaix-os/kernel/process.c | 14 +++++++++++++- 5 files changed, 49 insertions(+), 21 deletions(-) diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index 87f259a..0764a61 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -234,6 +234,9 @@ vfs_i_alloc(); void vfs_i_free(struct v_inode* inode); +int +vfs_dup_fd(struct v_fd* old, struct v_fd** new); + void pcache_init(struct pcache* pcache); diff --git a/lunaix-os/kernel/demos/iotest.c b/lunaix-os/kernel/demos/iotest.c index f41c9a8..5e17b02 100644 --- a/lunaix-os/kernel/demos/iotest.c +++ b/lunaix-os/kernel/demos/iotest.c @@ -6,6 +6,9 @@ LOG_MODULE("IOTEST") +#define STDIN 1 +#define STDOUT 0 + void _iotest_main() { @@ -18,12 +21,7 @@ _iotest_main() // Lunaix会尽可能缓存任何对此设备的上层读写,并使用延迟写入策略。(FO_DIRECT可用于屏蔽该功能) int fd = open("/dev/sda", 0); - // tty 设备 - 控制台。 - // tty设备属于序列设备(Sequential Device),该类型设备的上层读写 - // 无须经过Lunaix的缓存层,而是直接下发到底层驱动。(不受FO_DIRECT的影响) - int tty = open("/dev/tty", 0); - - if (fd < 0 || tty < 0) { + if (fd < 0) { kprintf(KERROR "fail to open (%d)\n", geterrno()); return; } @@ -36,29 +34,29 @@ _iotest_main() write(fd, test_sequence, sizeof(test_sequence)); } - lseek(fd, 521, FSEEK_SET); + // 随机读写测试 + lseek(fd, 4 * 4096, FSEEK_SET); write(fd, test_sequence, sizeof(test_sequence)); char read_out[256]; - write(tty, "input: ", 8); - int size = read(tty, read_out, 256); + write(STDOUT, "input: ", 8); + int size = read(STDIN, read_out, 256); - write(tty, "your input: ", 13); - write(tty, read_out, size); + write(STDOUT, "your input: ", 13); + write(STDOUT, read_out, size); write(fd, read_out, size); - write(tty, "\n", 1); + write(STDOUT, "\n", 1); // 读出我们写的内容 lseek(fd, 512, FSEEK_SET); read(fd, read_out, sizeof(read_out)); // 将读出的内容直接写入tty设备 - write(tty, read_out, sizeof(read_out)); - write(tty, "\n", 1); + write(STDOUT, read_out, sizeof(read_out)); + write(STDOUT, "\n", 1); // 关闭文件,这同时会将页缓存中的数据下发到底层驱动 close(fd); - close(tty); kprint_hex(read_out, sizeof(read_out)); } \ No newline at end of file diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index 1104d9b..11896ec 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -945,7 +945,7 @@ __DEFINE_LXSYSCALL1(int, fsync, int, fildes) } int -__vfs_dup_fd(struct v_fd* old, struct v_fd** new) +vfs_dup_fd(struct v_fd* old, struct v_fd** new) { int errno = 0; struct v_fd* copied = cake_grab(fd_pile); @@ -953,10 +953,13 @@ __vfs_dup_fd(struct v_fd* old, struct v_fd** new) memcpy(copied, old, sizeof(struct v_fd)); old->file->ref_count++; + *new = copied; + return errno; } -__DEFINE_LXSYSCALL2(int, dup2, int, oldfd, int, newfd) +int +vfs_dup2(int oldfd, int newfd) { if (newfd == oldfd) { return newfd; @@ -964,7 +967,7 @@ __DEFINE_LXSYSCALL2(int, dup2, int, oldfd, int, newfd) int errno; struct v_fd *oldfd_s, *newfd_s; - if (!GET_FD(oldfd, oldfd_s) || TEST_FD(newfd)) { + if (!GET_FD(oldfd, oldfd_s) || !TEST_FD(newfd)) { errno = EBADF; goto done; } @@ -973,7 +976,7 @@ __DEFINE_LXSYSCALL2(int, dup2, int, oldfd, int, newfd) goto done; } - if (!(errno = __vfs_dup_fd(oldfd_s, &newfd_s))) { + if (!(errno = vfs_dup_fd(oldfd_s, &newfd_s))) { __current->fdtable->fds[newfd] = newfd_s; return newfd; } @@ -982,6 +985,11 @@ done: return DO_STATUS(errno); } +__DEFINE_LXSYSCALL2(int, dup2, int, oldfd, int, newfd) +{ + return vfs_dup2(oldfd, newfd); +} + __DEFINE_LXSYSCALL1(int, dup, int, oldfd) { int errno, newfd; @@ -989,7 +997,7 @@ __DEFINE_LXSYSCALL1(int, dup, int, oldfd) if (!GET_FD(oldfd, oldfd_s)) { errno = EBADF; } else if (!(errno = vfs_alloc_fdslot(&newfd)) && - !(errno = __vfs_dup_fd(oldfd_s, &newfd_s))) { + !(errno = vfs_dup_fd(oldfd_s, &newfd_s))) { __current->fdtable->fds[newfd] = newfd_s; return newfd; } diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index ec99742..5fac5f8 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,12 @@ _iotest_main(); void __USER__ __proc0_usr() { + // 打开tty设备(控制台),作为标准输入输出。 + // tty设备属于序列设备(Sequential Device),该类型设备的上层读写 + // 无须经过Lunaix的缓存层,而是直接下发到底层驱动。(不受FO_DIRECT的影响) + int stdout = open("/dev/tty", 0); + int stdin = dup2(stdout, 1); + pid_t p; if (!fork()) { _pconsole_main(); diff --git a/lunaix-os/kernel/process.c b/lunaix-os/kernel/process.c index 4d6a77e..086a5e3 100644 --- a/lunaix-os/kernel/process.c +++ b/lunaix-os/kernel/process.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -176,6 +177,17 @@ __mark_region(uintptr_t start_vpn, uintptr_t end_vpn, int attr) } } +void +__copy_fdtable(struct proc_info* pcb) +{ + for (size_t i = 0; i < VFS_MAX_FD; i++) { + struct v_fd* fd = __current->fdtable->fds[i]; + if (!fd) + continue; + vfs_dup_fd(fd, &pcb->fdtable->fds[i]); + } +} + pid_t dup_proc() { @@ -184,7 +196,7 @@ dup_proc() pcb->intr_ctx = __current->intr_ctx; pcb->parent = __current; - memcpy(pcb->fdtable, __current->fdtable, sizeof(struct v_fdtable)); + __copy_fdtable(pcb); region_copy(&__current->mm.regions, &pcb->mm.regions); setup_proc_mem(pcb, PD_REFERENCED); -- 2.27.0