File.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. * Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
  3. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Noncopyable.h>
  9. #include <AK/StdLibExtras.h>
  10. #include <unistd.h>
  11. namespace IPC {
  12. class File {
  13. AK_MAKE_NONCOPYABLE(File);
  14. public:
  15. // Must have a default constructor, because LibIPC
  16. // default-constructs arguments prior to decoding them.
  17. File() { }
  18. // Intentionally not `explicit`.
  19. File(int fd)
  20. : m_fd(fd)
  21. {
  22. }
  23. // Tagged constructor for fd's that should be closed on destruction unless take_fd() is called.
  24. // Note that the tags are the same, this is intentional to allow expressive invocation.
  25. enum Tag {
  26. ConstructWithReceivedFileDescriptor = 1,
  27. CloseAfterSending = 1,
  28. };
  29. File(int fd, Tag)
  30. : m_fd(fd)
  31. , m_close_on_destruction(true)
  32. {
  33. }
  34. File(File&& other)
  35. : m_fd(exchange(other.m_fd, -1))
  36. , m_close_on_destruction(exchange(other.m_close_on_destruction, false))
  37. {
  38. }
  39. File& operator=(File&& other)
  40. {
  41. if (this != &other) {
  42. m_fd = exchange(other.m_fd, -1);
  43. m_close_on_destruction = exchange(other.m_close_on_destruction, false);
  44. }
  45. return *this;
  46. }
  47. ~File()
  48. {
  49. if (m_close_on_destruction && m_fd != -1)
  50. close(m_fd);
  51. }
  52. int fd() const { return m_fd; }
  53. // NOTE: This is 'const' since generated IPC messages expose all parameters by const reference.
  54. [[nodiscard]] int take_fd() const
  55. {
  56. return exchange(m_fd, -1);
  57. }
  58. private:
  59. mutable int m_fd { -1 };
  60. bool m_close_on_destruction { false };
  61. };
  62. }