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);
LOG_MODULE("IOTEST")
+#define STDIN 1
+#define STDOUT 0
+
void
_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;
}
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
}
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);
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;
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;
}
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;
}
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;
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;
}
#include <arch/x86/boot/multiboot.h>
#include <lunaix/block.h>
#include <lunaix/common.h>
+#include <lunaix/fctrl.h>
#include <lunaix/fs.h>
#include <lunaix/fs/twifs.h>
#include <lunaix/lunistd.h>
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();
#include <lunaix/common.h>
#include <lunaix/mm/pmm.h>
#include <lunaix/mm/region.h>
+#include <lunaix/mm/valloc.h>
#include <lunaix/mm/vmm.h>
#include <lunaix/process.h>
#include <lunaix/spike.h>
}
}
+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()
{
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);