From ba2ebbc7c1736e3262c3b8064e23f5fc58b989cb Mon Sep 17 00:00:00 2001 From: Matheus Date: Mon, 10 Oct 2022 10:46:44 -0300 Subject: [PATCH] syscalls: pipe2 --- src/arch/x86_64/syscall.asm | 4 +- src/sys/syscalls/pipe2.c | 80 +++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/sys/syscalls/pipe2.c diff --git a/src/arch/x86_64/syscall.asm b/src/arch/x86_64/syscall.asm index bbcfb8d3..e2304955 100644 --- a/src/arch/x86_64/syscall.asm +++ b/src/arch/x86_64/syscall.asm @@ -25,7 +25,8 @@ extern syscall_getdirent extern syscall_ioctl extern syscall_chdir extern syscall_fstatat -func_count equ 24 +extern syscall_pipe2 +func_count equ 25 func_table: @@ -53,6 +54,7 @@ func_table: dq syscall_ioctl dq syscall_chdir dq syscall_fstatat + dq syscall_pipe2 section .text global asm_syscall_entry diff --git a/src/sys/syscalls/pipe2.c b/src/sys/syscalls/pipe2.c new file mode 100644 index 00000000..e23d06f0 --- /dev/null +++ b/src/sys/syscalls/pipe2.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include + +extern fs_t kerneltmpfs; + +// the pipe2 system call will return the two fds in the same register + +syscallret syscall_pipe2(int flags){ + syscallret retv; + retv.ret = -1; + + proc_t* proc = arch_getcls()->thread->proc; + + fd_t* rfd = NULL; + fd_t* wfd = NULL; + + int rifd, wifd; + + retv.errno = fd_alloc(&proc->fdtable, &rfd, &rifd, 0); + + if(retv.errno) + return retv; + + retv.errno = fd_alloc(&proc->fdtable, &wfd, &wifd, 0); + + if(retv.errno) + goto _fail; + + wfd->flags = O_WRONLY+1; + rfd->flags = O_RDONLY+1; + + wfd->node = vfs_newnode("FIFO", &kerneltmpfs, NULL); + if(!wfd->node){ + retv.errno = ENOMEM; + goto _fail; + } + rfd->node = wfd->node; + + rfd->mode = MAKETYPE(TYPE_FIFO); + wfd->mode = rfd->mode; + rfd->node->st.st_mode = rfd->mode; + rfd->node->refcount = 2; + + pipe_t* pipe = pipe_create(PAGE_SIZE*16); + + if(!pipe){ + retv.errno = ENOMEM; + goto _fail; + } + + wfd->node->objdata = pipe; + + pipe->readers = 1; + pipe->writers = 1; + + retv.errno = 0; + retv.ret = ((long)rifd & 0xFFFFFFFF) + (((long)wifd & 0xFFFFFFFF) << 32); + + fd_release(wfd); + fd_release(rfd); + + return retv; + + _fail: + + if(wfd){ + fd_release(wfd); + fd_free(&proc->fdtable, wifd); + } + if(rfd){ + fd_release(rfd); + fd_free(&proc->fdtable, rifd); + } + + return retv; + + +}