Fix: syscall event rule: emission sites not compared in is_equal
[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(int raw_fd) noexcept : _raw_fd{ raw_fd }
27 {
28 LTTNG_ASSERT(is_valid_fd(_raw_fd));
29 }
30
31 lttng::file_descriptor::file_descriptor(lttng::file_descriptor&& other) noexcept
32 {
33 std::swap(_raw_fd, other._raw_fd);
34 }
35
36 lttng::file_descriptor& lttng::file_descriptor::operator=(lttng::file_descriptor&& other) noexcept
37 {
38 _cleanup();
39 std::swap(_raw_fd, other._raw_fd);
40 return *this;
41 }
42
43 lttng::file_descriptor::~file_descriptor() noexcept
44 {
45 _cleanup();
46 }
47
48 int lttng::file_descriptor::fd() const noexcept
49 {
50 LTTNG_ASSERT(is_valid_fd(_raw_fd));
51 return _raw_fd;
52 }
53
54 void lttng::file_descriptor::_cleanup() noexcept
55 {
56 if (!is_valid_fd(_raw_fd)) {
57 return;
58 }
59
60 const auto ret = ::close(_raw_fd);
61
62 _raw_fd = -1;
63 if (ret) {
64 PERROR("Failed to close file descriptor: fd=%i", _raw_fd);
65 }
66 }
67
68 void lttng::file_descriptor::write(const void *buffer, std::size_t size)
69 {
70 /*
71 * This is a limitation of the internal helper that is not a problem in practice for the
72 * moment.
73 */
74 using lttng_write_return_type = decltype(lttng_write(
75 std::declval<int>(), std::declval<const void *>(), std::declval<size_t>()));
76 constexpr auto max_supported_write_size =
77 std::numeric_limits<lttng_write_return_type>::max();
78
79 if (size > max_supported_write_size) {
80 LTTNG_THROW_UNSUPPORTED_ERROR(lttng::format(
81 "Write size exceeds the maximal supported value of lttng_write: write_size={}, maximal_write_size={}",
82 size,
83 max_supported_write_size));
84 }
85
86 const auto write_ret = lttng_write(fd(), buffer, size);
87 if (write_ret < 0 || static_cast<std::size_t>(write_ret) != size) {
88 LTTNG_THROW_POSIX(lttng::format("Failed to write to file descriptor: fd={}", fd()),
89 errno);
90 }
91 }
92
93 void lttng::file_descriptor::read(void *buffer, std::size_t size)
94 {
95 /*
96 * This is a limitation of the internal helper that is not a problem in practice for the
97 * moment.
98 */
99 using lttng_read_return_type = decltype(lttng_read(
100 std::declval<int>(), std::declval<void *>(), std::declval<size_t>()));
101 constexpr auto max_supported_read_size = std::numeric_limits<lttng_read_return_type>::max();
102
103 if (size > max_supported_read_size) {
104 LTTNG_THROW_UNSUPPORTED_ERROR(lttng::format(
105 "Read size exceeds the maximal supported value of lttng_read: read_size={}, maximal_read_size={}",
106 size,
107 max_supported_read_size));
108 }
109
110 const auto read_ret = lttng_read(fd(), buffer, size);
111 if (read_ret < 0 || static_cast<std::size_t>(read_ret) != size) {
112 LTTNG_THROW_POSIX(lttng::format("Failed to read from file descriptor: fd={}", fd()),
113 errno);
114 }
115 }
This page took 0.032118 seconds and 4 git commands to generate.