/src/systemd/src/basic/inotify-util.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | |
3 | | #include "fd-util.h" |
4 | | #include "inotify-util.h" |
5 | | #include "log.h" |
6 | | #include "memory-util.h" |
7 | | |
8 | | bool inotify_event_next( |
9 | | union inotify_event_buffer *buffer, |
10 | | size_t size, |
11 | | struct inotify_event **iterator, |
12 | 0 | int log_level) { |
13 | |
|
14 | 0 | struct inotify_event *e; |
15 | 0 | size_t offset = 0; |
16 | |
|
17 | 0 | assert(buffer); |
18 | 0 | assert(iterator); |
19 | |
|
20 | 0 | if (*iterator) { |
21 | 0 | assert((uint8_t*) *iterator >= buffer->raw); |
22 | 0 | offset = (uint8_t*) *iterator - buffer->raw; |
23 | 0 | offset += offsetof(struct inotify_event, name) + (*iterator)->len; |
24 | 0 | } |
25 | |
|
26 | 0 | if (size == offset) |
27 | 0 | return false; /* reached end of list */ |
28 | | |
29 | 0 | if (size < offset || |
30 | 0 | size - offset < offsetof(struct inotify_event, name)) { |
31 | 0 | log_full(log_level, "Received invalid inotify event, ignoring."); |
32 | 0 | return false; |
33 | 0 | } |
34 | | |
35 | 0 | e = CAST_ALIGN_PTR(struct inotify_event, buffer->raw + offset); |
36 | 0 | if (size - offset - offsetof(struct inotify_event, name) < e->len) { |
37 | 0 | log_full(log_level, "Received invalid inotify event, ignoring."); |
38 | 0 | return false; |
39 | 0 | } |
40 | | |
41 | 0 | *iterator = e; |
42 | 0 | return true; |
43 | 0 | } |
44 | | |
45 | 0 | int inotify_add_watch_fd(int fd, int what, uint32_t mask) { |
46 | 0 | int wd; |
47 | |
|
48 | 0 | assert(fd >= 0); |
49 | 0 | assert(what >= 0); |
50 | | |
51 | | /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */ |
52 | 0 | wd = inotify_add_watch(fd, FORMAT_PROC_FD_PATH(what), mask); |
53 | 0 | if (wd < 0) { |
54 | 0 | if (errno != ENOENT) |
55 | 0 | return -errno; |
56 | | |
57 | 0 | return proc_fd_enoent_errno(); |
58 | 0 | } |
59 | | |
60 | 0 | return wd; |
61 | 0 | } |
62 | | |
63 | 0 | int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) { |
64 | 0 | int wd; |
65 | |
|
66 | 0 | wd = inotify_add_watch(fd, pathname, mask); |
67 | 0 | if (wd < 0) { |
68 | 0 | if (errno == ENOSPC) |
69 | 0 | return log_error_errno(errno, "Failed to add a watch for %s: inotify watch limit reached", pathname); |
70 | | |
71 | 0 | return log_error_errno(errno, "Failed to add a watch for %s: %m", pathname); |
72 | 0 | } |
73 | | |
74 | 0 | return wd; |
75 | 0 | } |