File.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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 <LibCore/Stream.h>
  11. #include <unistd.h>
  12. namespace IPC {
  13. class File {
  14. AK_MAKE_NONCOPYABLE(File);
  15. public:
  16. // Must have a default constructor, because LibIPC
  17. // default-constructs arguments prior to decoding them.
  18. File() = default;
  19. // Intentionally not `explicit`.
  20. File(int fd)
  21. : m_fd(fd)
  22. {
  23. }
  24. // Tagged constructor for fd's that should be closed on destruction unless take_fd() is called.
  25. // Note that the tags are the same, this is intentional to allow expressive invocation.
  26. enum Tag {
  27. ConstructWithReceivedFileDescriptor = 1,
  28. CloseAfterSending = 1,
  29. };
  30. File(int fd, Tag)
  31. : m_fd(fd)
  32. , m_close_on_destruction(true)
  33. {
  34. }
  35. template<typename... Args>
  36. File(Core::Stream::File& file, Args... args)
  37. : File(file.leak_fd(Badge<File> {}), args...)
  38. {
  39. }
  40. File(File&& other)
  41. : m_fd(exchange(other.m_fd, -1))
  42. , m_close_on_destruction(exchange(other.m_close_on_destruction, false))
  43. {
  44. }
  45. File& operator=(File&& other)
  46. {
  47. if (this != &other) {
  48. m_fd = exchange(other.m_fd, -1);
  49. m_close_on_destruction = exchange(other.m_close_on_destruction, false);
  50. }
  51. return *this;
  52. }
  53. ~File()
  54. {
  55. if (m_close_on_destruction && m_fd != -1)
  56. close(m_fd);
  57. }
  58. int fd() const { return m_fd; }
  59. // NOTE: This is 'const' since generated IPC messages expose all parameters by const reference.
  60. [[nodiscard]] int take_fd() const
  61. {
  62. return exchange(m_fd, -1);
  63. }
  64. private:
  65. mutable int m_fd { -1 };
  66. bool m_close_on_destruction { false };
  67. };
  68. }