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/OpenFileDescription.h> 8#include <Kernel/Net/LocalSocket.h> 9#include <Kernel/Process.h> 10 11namespace Kernel { 12 13ErrorOr<FlatPtr> Process::sys$sendfd(int sockfd, int fd) 14{ 15 VERIFY_NO_PROCESS_BIG_LOCK(this); 16 TRY(require_promise(Pledge::sendfd)); 17 auto socket_description = TRY(open_file_description(sockfd)); 18 if (!socket_description->is_socket()) 19 return ENOTSOCK; 20 auto& socket = *socket_description->socket(); 21 if (!socket.is_local()) 22 return EAFNOSUPPORT; 23 if (!socket.is_connected()) 24 return ENOTCONN; 25 26 auto passing_description = TRY(open_file_description(fd)); 27 auto& local_socket = static_cast<LocalSocket&>(socket); 28 TRY(local_socket.sendfd(*socket_description, move(passing_description))); 29 return 0; 30} 31 32ErrorOr<FlatPtr> Process::sys$recvfd(int sockfd, int options) 33{ 34 VERIFY_NO_PROCESS_BIG_LOCK(this); 35 TRY(require_promise(Pledge::recvfd)); 36 auto socket_description = TRY(open_file_description(sockfd)); 37 if (!socket_description->is_socket()) 38 return ENOTSOCK; 39 auto& socket = *socket_description->socket(); 40 if (!socket.is_local()) 41 return EAFNOSUPPORT; 42 43 auto fd_allocation = TRY(m_fds.with_exclusive([](auto& fds) { return fds.allocate(); })); 44 45 auto& local_socket = static_cast<LocalSocket&>(socket); 46 auto received_description = TRY(local_socket.recvfd(*socket_description)); 47 48 u32 fd_flags = 0; 49 if (options & O_CLOEXEC) 50 fd_flags |= FD_CLOEXEC; 51 52 m_fds.with_exclusive([&](auto& fds) { fds[fd_allocation.fd].set(move(received_description), fd_flags); }); 53 return fd_allocation.fd; 54} 55 56}