Serenity Operating System
at master 56 lines 1.8 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/FileSystem/FIFO.h> 8#include <Kernel/Process.h> 9 10namespace Kernel { 11 12ErrorOr<FlatPtr> Process::sys$pipe(Userspace<int*> pipefd, int flags) 13{ 14 VERIFY_NO_PROCESS_BIG_LOCK(this); 15 TRY(require_promise(Pledge::stdio)); 16 17 // Reject flags other than O_CLOEXEC, O_NONBLOCK 18 if ((flags & (O_CLOEXEC | O_NONBLOCK)) != flags) 19 return EINVAL; 20 21 u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0; 22 auto credentials = this->credentials(); 23 auto fifo = TRY(FIFO::try_create(credentials->uid())); 24 25 auto reader_description = TRY(fifo->open_direction(FIFO::Direction::Reader)); 26 auto writer_description = TRY(fifo->open_direction(FIFO::Direction::Writer)); 27 28 reader_description->set_readable(true); 29 writer_description->set_writable(true); 30 if (flags & O_NONBLOCK) { 31 reader_description->set_blocking(false); 32 writer_description->set_blocking(false); 33 } 34 35 TRY(m_fds.with_exclusive([&](auto& fds) -> ErrorOr<void> { 36 auto reader_fd_allocation = TRY(fds.allocate()); 37 auto writer_fd_allocation = TRY(fds.allocate()); 38 39 fds[reader_fd_allocation.fd].set(move(reader_description), fd_flags); 40 fds[writer_fd_allocation.fd].set(move(writer_description), fd_flags); 41 42 int fds_for_userspace[2] = { 43 reader_fd_allocation.fd, 44 writer_fd_allocation.fd, 45 }; 46 if (copy_to_user(pipefd, fds_for_userspace, sizeof(fds_for_userspace)).is_error()) { 47 fds[reader_fd_allocation.fd] = {}; 48 fds[writer_fd_allocation.fd] = {}; 49 return EFAULT; 50 } 51 return {}; 52 })); 53 return 0; 54} 55 56}