Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Inotify.hpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2024 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#ifndef TOOLBOX_IO_INOTIFY_HPP
18#define TOOLBOX_IO_INOTIFY_HPP
19
21
22#include <sys/inotify.h>
23
24#include <filesystem>
25#include <map>
26
27namespace toolbox {
28inline namespace io {
29
30struct WatchFile {
31 int fd{-1}, wd{-1};
32};
33
35{
36 return lhs.fd == rhs.fd && lhs.wd == rhs.wd;
37}
38
40{
41 return !(lhs == rhs);
42}
43
45 using Id = WatchFile;
46 static constexpr WatchFile invalid() noexcept { return WatchFile{}; }
47 static void close(WatchFile wf) noexcept { ::inotify_rm_watch(wf.fd, wf.wd); }
48};
49
51
53inline FileHandle inotify_init(int flags, std::error_code& ec) noexcept
54{
55 const auto fd = ::inotify_init1(flags);
56 if (fd < 0) {
58 }
59 return fd;
60}
61
63inline FileHandle inotify_init(std::error_code& ec) noexcept
64{
65 return inotify_init(0, ec);
66}
67
71{
72 const auto fd = ::inotify_init1(flags);
73 if (fd < 0) {
74 throw std::system_error{make_error(errno), "inotify_init1"};
75 }
76 return fd;
77}
78
80inline WatchFileHandle inotify_add_watch(int fd, const char* path, std::uint32_t mask,
81 std::error_code& ec) noexcept
82{
83 const auto wd = ::inotify_add_watch(fd, path, mask);
84 if (wd < 0) {
86 return {};
87 }
88 return WatchFile{.fd = fd, .wd = wd};
89}
90
92inline WatchFileHandle inotify_add_watch(int fd, const char* path, std::uint32_t mask)
93{
94 const auto wd = ::inotify_add_watch(fd, path, mask);
95 if (wd < 0) {
96 throw std::system_error{make_error(errno), "inotify_add_watch"};
97 }
98 return WatchFile{.fd = fd, .wd = wd};
99}
100
103 public:
104 explicit Inotify(int flags = 0)
105 : fh_{inotify_init(flags)}
106 {
107 }
108 ~Inotify() = default;
109
110 // Copy.
111 Inotify(const Inotify&) = delete;
112 Inotify& operator=(const Inotify&) = delete;
113
114 // Move.
115 Inotify(Inotify&&) noexcept = default;
116 Inotify& operator=(Inotify&&) noexcept = default;
117
118 int fd() const noexcept { return fh_.get(); }
119
121 [[nodiscard]] WatchFileHandle add_watch(const char* path, std::uint32_t mask,
122 std::error_code& ec) noexcept
123 {
124 return inotify_add_watch(fh_.get(), path, mask, ec);
125 }
127 [[nodiscard]] WatchFileHandle add_watch(const char* path, std::uint32_t mask)
128 {
129 return inotify_add_watch(fh_.get(), path, mask);
130 }
131
132 private:
133 FileHandle fh_;
134};
135
138 public:
139 using Path = std::filesystem::path;
141
142 FileWatcher(Reactor& r, Inotify& inotify);
143 ~FileWatcher() = default;
144
145 // Copy.
146 FileWatcher(const FileWatcher&) = delete;
148
149 // Move.
150 FileWatcher(FileWatcher&&) noexcept = default;
151 FileWatcher& operator=(FileWatcher&&) noexcept = default;
152
153 void watch(const Path& path, Slot slot, std::uint32_t mask = IN_ALL_EVENTS);
154
155 private:
156 struct Watch {
157 Path path;
158 Slot slot;
160 };
161
162 void on_inotify(CyclTime /*now*/, int fd, unsigned events);
163
164 Inotify* inotify_;
165 Reactor::Handle sub_;
166 std::map<Path, Watch> path_index_;
167 std::map<int, const Watch*> wd_index_;
168};
169
170} // namespace io
171} // namespace toolbox
172
173#endif // TOOLBOX_IO_INOTIFY_HPP
#define TOOLBOX_API
Definition Config.h:39
FileWatcher watches for changes to files.
Definition Inotify.hpp:137
std::filesystem::path Path
Definition Inotify.hpp:139
FileWatcher(FileWatcher &&) noexcept=default
FileWatcher(const FileWatcher &)=delete
FileWatcher & operator=(const FileWatcher &)=delete
Inotify provides a simplified interface to an inotify instance.
Definition Inotify.hpp:102
WatchFileHandle add_watch(const char *path, std::uint32_t mask, std::error_code &ec) noexcept
Add a watch to an initialised inotify instance.
Definition Inotify.hpp:121
Inotify(int flags=0)
Definition Inotify.hpp:104
WatchFileHandle add_watch(const char *path, std::uint32_t mask)
Add a watch to an initialised inotify instance.
Definition Inotify.hpp:127
Inotify(const Inotify &)=delete
Inotify & operator=(const Inotify &)=delete
Inotify(Inotify &&) noexcept=default
STL namespace.
WatchFileHandle inotify_add_watch(int fd, const char *path, std::uint32_t mask, std::error_code &ec) noexcept
Add a watch to an initialised inotify instance.
Definition Inotify.hpp:80
constexpr bool operator==(const BasicHandle< PolicyT > &lhs, const BasicHandle< PolicyT > &rhs)
Definition Handle.hpp:91
FileHandle inotify_init(int flags, std::error_code &ec) noexcept
Initialise an inotify instance.
Definition Inotify.hpp:53
constexpr bool operator!=(const BasicHandle< PolicyT > &lhs, const BasicHandle< PolicyT > &rhs)
Definition Handle.hpp:97
std::error_code make_error(int err) noexcept
Definition Error.hpp:25
constexpr auto bind() noexcept
Definition Slot.hpp:92
static constexpr WatchFile invalid() noexcept
Definition Inotify.hpp:46
static void close(WatchFile wf) noexcept
Definition Inotify.hpp:47