Build fix: common: eventfd only exists on Linux
[lttng-tools.git] / src / common / file-descriptor.cpp
1 /*
2 * Copyright (C) 2023 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include "file-descriptor.hpp"
9
10 #include <common/error.hpp>
11 #include <common/exception.hpp>
12 #include <common/format.hpp>
13 #include <common/readwrite.hpp>
14
15 #include <algorithm>
16 #include <limits>
17 #include <unistd.h>
18
19 namespace {
20 bool is_valid_fd(int fd)
21 {
22 return fd >= 0;
23 }
24 } // anonymous namespace
25
26 lttng::file_descriptor::file_descriptor() noexcept
27 {
28 }
29
30 lttng::file_descriptor::file_descriptor(int raw_fd) noexcept : _raw_fd{ raw_fd }
31 {
32 LTTNG_ASSERT(is_valid_fd(_raw_fd));
33 }
34
35 lttng::file_descriptor::file_descriptor(lttng::file_descriptor&& other) noexcept
36 {
37 std::swap(_raw_fd, other._raw_fd);
38 }
39
40 lttng::file_descriptor& lttng::file_descriptor::operator=(lttng::file_descriptor&& other) noexcept
41 {
42 _cleanup();
43 std::swap(_raw_fd, other._raw_fd);
44 return *this;
45 }
46
47 lttng::file_descriptor::~file_descriptor() noexcept
48 {
49 _cleanup();
50 }
51
52 int lttng::file_descriptor::fd() const noexcept
53 {
54 LTTNG_ASSERT(is_valid_fd(_raw_fd));
55 return _raw_fd;
56 }
57
58 void lttng::file_descriptor::_cleanup() noexcept
59 {
60 if (!is_valid_fd(_raw_fd)) {
61 return;
62 }
63
64 const auto ret = ::close(_raw_fd);
65
66 _raw_fd = -1;
67 if (ret) {
68 PERROR("Failed to close file descriptor: fd=%i", _raw_fd);
69 }
70 }
71
72 void lttng::file_descriptor::write(const void *buffer, std::size_t size)
73 {
74 /*
75 * This is a limitation of the internal helper that is not a problem in practice for the
76 * moment.
77 */
78 using lttng_write_return_type = decltype(lttng_write(
79 std::declval<int>(), std::declval<const void *>(), std::declval<size_t>()));
80 constexpr auto max_supported_write_size =
81 std::numeric_limits<lttng_write_return_type>::max();
82
83 if (size > max_supported_write_size) {
84 LTTNG_THROW_UNSUPPORTED_ERROR(fmt::format(
85 "Write size exceeds the maximal supported value of lttng_write: write_size={}, maximal_write_size={}",
86 size,
87 max_supported_write_size));
88 }
89
90 const auto write_ret = lttng_write(fd(), buffer, size);
91 if (write_ret < 0 || static_cast<std::size_t>(write_ret) != size) {
92 LTTNG_THROW_POSIX(fmt::format("Failed to write to file descriptor: fd={}", fd()),
93 errno);
94 }
95 }
96
97 void lttng::file_descriptor::read(void *buffer, std::size_t size)
98 {
99 /*
100 * This is a limitation of the internal helper that is not a problem in practice for the
101 * moment.
102 */
103 using lttng_read_return_type = decltype(lttng_read(
104 std::declval<int>(), std::declval<void *>(), std::declval<size_t>()));
105 constexpr auto max_supported_read_size = std::numeric_limits<lttng_read_return_type>::max();
106
107 if (size > max_supported_read_size) {
108 LTTNG_THROW_UNSUPPORTED_ERROR(fmt::format(
109 "Read size exceeds the maximal supported value of lttng_read: read_size={}, maximal_read_size={}",
110 size,
111 max_supported_read_size));
112 }
113
114 const auto read_ret = lttng_read(fd(), buffer, size);
115 if (read_ret < 0 || static_cast<std::size_t>(read_ret) != size) {
116 LTTNG_THROW_POSIX(fmt::format("Failed to read from file descriptor: fd={}", fd()),
117 errno);
118 }
119 }
This page took 0.032791 seconds and 4 git commands to generate.