Skip to content

Commit efc95fc

Browse files
author
Will
committed
watcher/linux: simplify
1 parent c985adb commit efc95fc

File tree

5 files changed

+104
-150
lines changed

5 files changed

+104
-150
lines changed

devel/include/detail/wtr/watcher/adapter/linux/fanotify/watch.hpp

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@
88
#if (KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE) && ! __ANDROID_API__
99

1010
#include "wtr/watcher.hpp"
11-
#include <atomic>
1211
#include <cassert>
1312
#include <cerrno>
1413
#include <climits>
1514
#include <cstdio>
1615
#include <cstring>
1716
#include <fcntl.h>
18-
#include <filesystem>
1917
#include <functional>
2018
#include <optional>
2119
#include <sys/epoll.h>
@@ -58,7 +56,7 @@ struct sysres {
5856
};
5957

6058
inline auto do_mark =
61-
[](char const* const dirpath, int fa_fd, auto const& cb) noexcept -> bool
59+
[](char const* const dirpath, int fa_fd, auto const& cb) -> bool
6260
{
6361
auto do_error = [&]() -> bool
6462
{ return adapter::do_error("w/sys/not_watched@", dirpath, cb); };
@@ -81,9 +79,8 @@ inline auto do_mark =
8179
fcntl(fa_fd, F_SETFL, O_NONBLOCK);
8280
fcntl(ep_fd, F_SETFL, O_NONBLOCK);
8381
*/
84-
inline auto make_sysres(
85-
char const* const base_path,
86-
::wtr::watcher::event::callback const& cb) noexcept -> sysres
82+
inline auto make_sysres =
83+
[](char const* const base_path, auto const& cb) -> sysres
8784
{
8885
auto do_error = [&](auto&& msg, int fa_fd, int ep_fd = -1) -> sysres
8986
{
@@ -112,9 +109,9 @@ inline auto make_sysres(
112109
.ke{.fd = fa_fd},
113110
.ep{.fd = ep_fd},
114111
};
115-
}
112+
};
116113

117-
inline auto close_sysres(sysres& sr) noexcept -> bool
114+
inline auto close_sysres(sysres& sr) -> bool
118115
{
119116
sr.ok = false;
120117
auto ok = close(sr.ke.fd) == 0 && close(sr.ep.fd) == 0;
@@ -152,8 +149,7 @@ inline auto close_sysres(sysres& sr) noexcept -> bool
152149
character string to the event's directory entry
153150
after the file handle to the directory.
154151
Confusing, right? */
155-
inline auto pathof(fanotify_event_metadata const* const mtd) noexcept
156-
-> std::filesystem::path
152+
inline auto pathof(fanotify_event_metadata const* const mtd) -> std::string
157153
{
158154
constexpr size_t path_ulim = PATH_MAX - sizeof('\0');
159155
auto dir_info = (fanotify_event_info_fid*)(mtd + 1);
@@ -189,20 +185,19 @@ inline auto pathof(fanotify_event_metadata const* const mtd) noexcept
189185
if (file_name && not_selfdir) snprintf(beg, end, "/%s", file_name);
190186
}
191187
}
188+
192189
return {path_buf};
193190
}
194191

195-
inline auto
196-
peek(fanotify_event_metadata const* const mtd, size_t read_len) noexcept
192+
inline auto peek(fanotify_event_metadata const* const mtd, size_t read_len)
197193
-> fanotify_event_metadata const*
198194
{
199195
auto evlen = mtd->event_len;
200196
auto next = (fanotify_event_metadata*)((char*)mtd + evlen);
201197
return FAN_EVENT_OK(next, read_len - evlen) ? next : nullptr;
202198
}
203199

204-
inline auto
205-
parse_event(fanotify_event_metadata const* m, size_t read_len) noexcept
200+
inline auto parse_event(fanotify_event_metadata const* m, size_t read_len)
206201
-> ::wtr::watcher::event
207202
{
208203
using ev = ::wtr::watcher::event;
@@ -229,10 +224,8 @@ parse_event(fanotify_event_metadata const* m, size_t read_len) noexcept
229224
Most of the other code is
230225
a layer of translation
231226
between us and the kernel. */
232-
inline auto send(
233-
::wtr::watcher::event const& ev,
234-
sysres& sr,
235-
::wtr::watcher::event::callback const& cb) noexcept -> bool
227+
inline auto send =
228+
[](::wtr::watcher::event const& ev, sysres& sr, auto const& cb) -> bool
236229
{
237230
using e = ::wtr::watcher::event;
238231
using ev_pt = enum e::path_type;
@@ -242,7 +235,7 @@ inline auto send(
242235
? do_mark(pn.c_str(), sr.ke.fd, cb)
243236
: true;
244237
return (cb(ev), update_ok);
245-
}
238+
};
246239

247240
/* Read some events from what fanotify gives
248241
us. Sends (the valid) events to the user's
@@ -265,17 +258,15 @@ inline auto send(
265258
The `metadata->vers` field may differ between
266259
kernel versions, so we check it against the
267260
version we were compiled with. */
268-
inline auto do_event_recv(
269-
std::filesystem::path const& base_path,
270-
::wtr::watcher::event::callback const& cb,
271-
sysres& sr) noexcept -> bool
261+
inline auto do_ev_recv =
262+
[](char const* const base_path, auto const& cb, sysres& sr) -> bool
272263
{
273-
auto do_error = [&](auto&& msg) noexcept -> bool
274-
{ return adapter::do_error(msg, base_path.c_str(), cb); };
275-
auto do_warn = [&](auto&& msg) noexcept -> bool { return ! do_error(msg); };
276-
auto ev_info = [](fanotify_event_metadata* m) noexcept
264+
auto do_error = [&](auto&& msg) -> bool
265+
{ return adapter::do_error(msg, base_path, cb); };
266+
auto do_warn = [&](auto&& msg) -> bool { return ! do_error(msg); };
267+
auto ev_info = [](fanotify_event_metadata* m)
277268
{ return (fanotify_event_info_fid*)(m + 1); };
278-
auto ev_has_dirname = [&](fanotify_event_metadata* m) noexcept -> bool
269+
auto ev_has_dirname = [&](fanotify_event_metadata* m) -> bool
279270
{ return ev_info(m)->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID_NAME; };
280271

281272
unsigned ev_c = 0;
@@ -290,24 +281,22 @@ inline auto do_event_recv(
290281
FAN_EVENT_OK(mtd, read_len);
291282
mtd = FAN_EVENT_NEXT(mtd, read_len))
292283
if (ev_c++ > sr.ke.c_ulim)
293-
return do_error("e/sys/bad_count@");
284+
return do_error("e/sys/ev_lin@");
294285
else if (mtd->vers != FANOTIFY_METADATA_VERSION)
295286
return do_error("e/sys/kernel_version@");
296287
else if (mtd->fd != FAN_NOFD)
297288
return do_warn("w/sys/bad_fd@");
298289
else if (mtd->mask & FAN_Q_OVERFLOW)
299-
return do_warn("w/sys/overflow@");
290+
return do_warn("w/sys/ev_lim@");
300291
else if (! ev_has_dirname(mtd))
301292
return do_warn("w/sys/bad_info@");
302293
else
303294
send(parse_event(mtd, read_len), sr, cb);
304295
return true;
305-
}
296+
};
306297

307-
inline auto watch(
308-
char const* const path,
309-
::wtr::watcher::event::callback const& cb,
310-
std::atomic<bool>& is_living) noexcept -> bool
298+
inline auto watch =
299+
[](char const* const path, auto const& cb, auto const& is_living) -> bool
311300
{
312301
auto sr = make_sysres(path, cb);
313302
auto do_error = [&](auto&& msg) -> bool
@@ -322,12 +311,12 @@ inline auto watch(
322311
else if (ep_c > 0) [[likely]]
323312
for (int n = 0; n < ep_c; n++)
324313
if (sr.ep.interests[n].data.fd == sr.ke.fd) [[likely]]
325-
if (! do_event_recv(path, cb, sr)) [[unlikely]]
326-
return do_error("e/self/event_recv@");
314+
if (! do_ev_recv(path, cb, sr)) [[unlikely]]
315+
return do_error("e/self/ev_recv@");
327316
}
328317

329318
return close_sysres(sr);
330-
}
319+
};
331320

332321
} /* namespace detail::wtr::watcher::adapter::fanotify */
333322

devel/include/detail/wtr/watcher/adapter/linux/inotify/watch.hpp

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#if (KERNEL_VERSION(2, 7, 0) <= LINUX_VERSION_CODE) || __ANDROID_API__
99

1010
#include "wtr/watcher.hpp"
11-
#include <atomic>
1211
#include <cstring>
1312
#include <filesystem>
1413
#include <functional>
@@ -94,11 +93,8 @@ struct sysres {
9493
adapter::ep ep{};
9594
};
9695

97-
inline auto do_mark = [](
98-
char const* const dirpath,
99-
int dirfd,
100-
auto& dm,
101-
auto const& cb) noexcept -> bool
96+
inline auto do_mark =
97+
[](char const* const dirpath, int dirfd, auto& dm, auto const& cb) -> bool
10298
{
10399
auto do_error = [&]() -> bool
104100
{ return adapter::do_error("w/sys/not_watched@", dirpath, cb); };
@@ -111,7 +107,7 @@ inline auto do_mark = [](
111107
};
112108

113109
inline auto make_sysres =
114-
[](char const* const base_path, auto const& cb) noexcept -> sysres
110+
[](char const* const base_path, auto const& cb) -> sysres
115111
{
116112
auto do_error = [&](std::string&& msg = "e/self/resource@")
117113
{ return (adapter::do_error(std::move(msg), base_path, cb), sysres{}); };
@@ -201,14 +197,14 @@ inline auto make_sysres =
201197
If this happens for some other
202198
reason, we're in trouble.
203199
*/
204-
inline auto do_event_recv =
205-
[](char const* const base_path, auto const& cb, sysres& sr) noexcept -> bool
200+
inline auto do_ev_recv =
201+
[](char const* const base_path, auto const& cb, sysres& sr) -> bool
206202
{
207-
auto do_error = [&](auto&& msg) noexcept -> bool
203+
auto do_error = [&](auto&& msg) -> bool
208204
{ return adapter::do_error(msg, base_path, cb); };
209-
auto do_warn = [&](auto&& msg) noexcept -> bool { return ! do_error(msg); };
205+
auto do_warn = [&](auto&& msg) -> bool { return ! do_error(msg); };
210206
auto defer_close = std::vector<int>{};
211-
auto do_deferred = [&]() noexcept
207+
auto do_deferred = [&]()
212208
{
213209
/* No need to check rm_watch for errors
214210
because there is a very good chance
@@ -256,8 +252,8 @@ inline auto do_event_recv =
256252
: msk & IN_DELETE_SELF || msk & IN_MOVE_SELF ? self_delmov
257253
: eventful;
258254
switch (recv_state) {
259-
case e_lim : return (do_deferred(), do_error("e/sys/event_lim@"));
260-
case w_lim : do_warn("w/sys/event_lim@"); break;
255+
case e_lim : return (do_deferred(), do_error("e/sys/ev_lim@"));
256+
case w_lim : do_warn("w/sys/ev_lim@"); break;
261257
case phantom : do_warn("w/sys/phantom_event@"); break;
262258
case impossible : break;
263259
case ignore : break;
@@ -307,10 +303,8 @@ inline auto do_event_recv =
307303
return do_deferred();
308304
};
309305

310-
inline auto watch(
311-
char const* const path,
312-
::wtr::watcher::event::callback const& cb,
313-
std::atomic<bool>& is_living) noexcept -> bool
306+
inline auto watch =
307+
[](char const* const path, auto const& cb, auto const& is_living) -> bool
314308
{
315309
auto sr = make_sysres(path, cb);
316310
auto do_error = [&](auto&& msg) -> bool
@@ -325,12 +319,12 @@ inline auto watch(
325319
else if (ep_c > 0) [[likely]]
326320
for (int n = 0; n < ep_c; n++)
327321
if (sr.ep.interests[n].data.fd == sr.ke.fd) [[likely]]
328-
if (! do_event_recv(path, cb, sr)) [[unlikely]]
329-
return do_error("e/self/event_recv@");
322+
if (! do_ev_recv(path, cb, sr)) [[unlikely]]
323+
return do_error("e/self/ev_recv@");
330324
}
331325

332326
return close_sysres(sr);
333-
}
327+
};
334328

335329
} /* namespace detail::wtr::watcher::adapter::inotify */
336330

devel/include/detail/wtr/watcher/adapter/linux/sysres.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct ep {
4343
};
4444

4545
inline auto do_error =
46-
[](std::string&& msg, char const* const path, auto const& cb) noexcept -> bool
46+
[](std::string&& msg, char const* const path, auto const& cb) -> bool
4747
{
4848
using et = enum ::wtr::watcher::event::effect_type;
4949
using pt = enum ::wtr::watcher::event::path_type;
@@ -52,7 +52,7 @@ inline auto do_error =
5252
};
5353

5454
inline auto do_warn =
55-
[](std::string&& msg, auto const& path, auto const& cb) noexcept -> bool
55+
[](std::string&& msg, auto const& path, auto const& cb) -> bool
5656
{ return (do_error(std::move(msg), path, cb), true); };
5757

5858
inline auto make_ep =
@@ -78,7 +78,7 @@ inline auto is_dir(char const* const path) -> bool
7878
return stat(path, &s) == 0 && S_ISDIR(s.st_mode);
7979
}
8080

81-
inline auto strany = [](char const* const s, auto... cmp) noexcept -> bool
81+
inline auto strany = [](char const* const s, auto... cmp) -> bool
8282
{ return ((strcmp(s, cmp) == 0) || ...); };
8383

8484
/* $ echo time wtr.watcher / -ms 1
@@ -102,7 +102,7 @@ inline auto strany = [](char const* const s, auto... cmp) noexcept -> bool
102102
not having a full picture.
103103
*/
104104
template<class Fn>
105-
inline auto walkdir_do(char const* const path, Fn f) noexcept -> void
105+
inline auto walkdir_do(char const* const path, Fn const& f) -> void
106106
{
107107
auto pappend = [&](char* head, char* tail)
108108
{ return snprintf(head, PATH_MAX, "%s/%s", path, tail); };
@@ -121,7 +121,7 @@ inline auto walkdir_do(char const* const path, Fn f) noexcept -> void
121121
}
122122
}
123123

124-
inline auto close_sysres = [](auto& sr) noexcept -> bool
124+
inline auto close_sysres = [](auto& sr) -> bool
125125
{
126126
sr.ok = false;
127127
auto closed = close(sr.ke.fd) == 0 && close(sr.ep.fd) == 0;

devel/include/detail/wtr/watcher/adapter/linux/watch.hpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,18 @@
99

1010
namespace detail::wtr::watcher::adapter {
1111

12-
/* We'll run and keep running as long as
13-
we have:
14-
- A lifetime the user hasn't ended
15-
- System resources for inotify and epoll
16-
- An event buffer to `read()` into */
1712
inline auto watch =
18-
[](auto const& path, auto const& cb, auto& is_living) noexcept -> bool
13+
[](auto const& path, auto const& cb, auto const& is_living) -> bool
1914
{
15+
auto p = path.c_str();
2016
#if (KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE) && ! __ANDROID_API__
21-
bool fanotify_usable = geteuid() == 0;
17+
return geteuid() == 0 ? fanotify::watch(p, cb, is_living)
18+
: inotify::watch(p, cb, is_living);
2219
#elif (KERNEL_VERSION(2, 7, 0) <= LINUX_VERSION_CODE) || __ANDROID_API__
23-
bool fanotify_usable = false;
20+
return inotify::watch(p, cb, is_living);
2421
#else
2522
#error "Define 'WATER_WATCHER_USE_WARTHOG' on kernel versions < 2.7.0"
2623
#endif
27-
28-
return fanotify_usable ? fanotify::watch(path.c_str(), cb, is_living)
29-
: inotify::watch(path.c_str(), cb, is_living);
3024
};
3125

3226
} /* namespace detail::wtr::watcher::adapter */

0 commit comments

Comments
 (0)