udev: String substitutions can be done in ENV, too
[systemd_ALT.git] / src / basic / inotify-util.c
blobee9b416c8735d555c447a7dbaab083fed79df3f4
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "fd-util.h"
4 #include "inotify-util.h"
5 #include "stat-util.h"
7 bool inotify_event_next(
8 union inotify_event_buffer *buffer,
9 size_t size,
10 struct inotify_event **iterator,
11 int log_level) {
13 struct inotify_event *e;
14 size_t offset = 0;
16 assert(buffer);
17 assert(iterator);
19 if (*iterator) {
20 assert((uint8_t*) *iterator >= buffer->raw);
21 offset = (uint8_t*) *iterator - buffer->raw;
22 offset += offsetof(struct inotify_event, name) + (*iterator)->len;
25 if (size == offset)
26 return false; /* reached end of list */
28 if (size < offset ||
29 size - offset < offsetof(struct inotify_event, name)) {
30 log_full(log_level, "Received invalid inotify event, ignoring.");
31 return false;
34 e = CAST_ALIGN_PTR(struct inotify_event, buffer->raw + offset);
35 if (size - offset - offsetof(struct inotify_event, name) < e->len) {
36 log_full(log_level, "Received invalid inotify event, ignoring.");
37 return false;
40 *iterator = e;
41 return true;
44 int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
45 int wd, r;
47 /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
48 wd = inotify_add_watch(fd, FORMAT_PROC_FD_PATH(what), mask);
49 if (wd < 0) {
50 if (errno != ENOENT)
51 return -errno;
53 /* Didn't work with ENOENT? If so, then either /proc/ isn't mounted, or the fd is bad */
54 r = proc_mounted();
55 if (r == 0)
56 return -ENOSYS;
57 if (r > 0)
58 return -EBADF;
60 return -ENOENT; /* OK, no clue, let's propagate the original error */
63 return wd;
66 int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) {
67 int wd;
69 wd = inotify_add_watch(fd, pathname, mask);
70 if (wd < 0) {
71 if (errno == ENOSPC)
72 return log_error_errno(errno, "Failed to add a watch for %s: inotify watch limit reached", pathname);
74 return log_error_errno(errno, "Failed to add a watch for %s: %m", pathname);
77 return wd;