Commit | Line | Data |
---|---|---|
20c734f5 JG |
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 | ||
20c734f5 JG |
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 | ||
0038180d | 48 | int lttng::file_descriptor::fd() const noexcept |
20c734f5 JG |
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) { | |
f9a41357 | 80 | LTTNG_THROW_UNSUPPORTED_ERROR(lttng::format( |
20c734f5 JG |
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 | ||
0038180d | 86 | const auto write_ret = lttng_write(fd(), buffer, size); |
20c734f5 | 87 | if (write_ret < 0 || static_cast<std::size_t>(write_ret) != size) { |
f9a41357 | 88 | LTTNG_THROW_POSIX(lttng::format("Failed to write to file descriptor: fd={}", fd()), |
20c734f5 JG |
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) { | |
f9a41357 | 104 | LTTNG_THROW_UNSUPPORTED_ERROR(lttng::format( |
20c734f5 JG |
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 | ||
0038180d | 110 | const auto read_ret = lttng_read(fd(), buffer, size); |
20c734f5 | 111 | if (read_ret < 0 || static_cast<std::size_t>(read_ret) != size) { |
f9a41357 | 112 | LTTNG_THROW_POSIX(lttng::format("Failed to read from file descriptor: fd={}", fd()), |
20c734f5 JG |
113 | errno); |
114 | } | |
115 | } |