sendfd.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <Kernel/FileSystem/OpenFileDescription.h>
  7. #include <Kernel/Net/LocalSocket.h>
  8. #include <Kernel/Process.h>
  9. namespace Kernel {
  10. ErrorOr<FlatPtr> Process::sys$sendfd(int sockfd, int fd)
  11. {
  12. VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
  13. TRY(require_promise(Pledge::sendfd));
  14. auto socket_description = TRY(open_file_description(sockfd));
  15. if (!socket_description->is_socket())
  16. return ENOTSOCK;
  17. auto& socket = *socket_description->socket();
  18. if (!socket.is_local())
  19. return EAFNOSUPPORT;
  20. if (!socket.is_connected())
  21. return ENOTCONN;
  22. auto passing_description = TRY(open_file_description(fd));
  23. auto& local_socket = static_cast<LocalSocket&>(socket);
  24. TRY(local_socket.sendfd(*socket_description, move(passing_description)));
  25. return 0;
  26. }
  27. ErrorOr<FlatPtr> Process::sys$recvfd(int sockfd, int options)
  28. {
  29. VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
  30. TRY(require_promise(Pledge::recvfd));
  31. auto socket_description = TRY(open_file_description(sockfd));
  32. if (!socket_description->is_socket())
  33. return ENOTSOCK;
  34. auto& socket = *socket_description->socket();
  35. if (!socket.is_local())
  36. return EAFNOSUPPORT;
  37. auto fd_allocation = TRY(m_fds.with_exclusive([](auto& fds) { return fds.allocate(); }));
  38. auto& local_socket = static_cast<LocalSocket&>(socket);
  39. auto received_description = TRY(local_socket.recvfd(*socket_description));
  40. u32 fd_flags = 0;
  41. if (options & O_CLOEXEC)
  42. fd_flags |= FD_CLOEXEC;
  43. m_fds.with_exclusive([&](auto& fds) { fds[fd_allocation.fd].set(move(received_description), fd_flags); });
  44. return fd_allocation.fd;
  45. }
  46. }