Fix: syscall event rule: emission sites not compared in is_equal
[lttng-tools.git] / src / common / file-descriptor.cpp
CommitLineData
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
19namespace {
20bool is_valid_fd(int fd)
21{
22 return fd >= 0;
23}
24} // anonymous namespace
25
20c734f5
JG
26lttng::file_descriptor::file_descriptor(int raw_fd) noexcept : _raw_fd{ raw_fd }
27{
28 LTTNG_ASSERT(is_valid_fd(_raw_fd));
29}
30
31lttng::file_descriptor::file_descriptor(lttng::file_descriptor&& other) noexcept
32{
33 std::swap(_raw_fd, other._raw_fd);
34}
35
36lttng::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
43lttng::file_descriptor::~file_descriptor() noexcept
44{
45 _cleanup();
46}
47
0038180d 48int lttng::file_descriptor::fd() const noexcept
20c734f5
JG
49{
50 LTTNG_ASSERT(is_valid_fd(_raw_fd));
51 return _raw_fd;
52}
53
54void 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
68void 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
93void 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}
This page took 0.035768 seconds and 4 git commands to generate.