]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-queue.c
Merge pull request #10538 from poettering/tmpfiles-reorder
[thirdparty/systemd.git] / src / libudev / libudev-queue.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 Copyright © 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
4 ***/
5
6 #include <errno.h>
7 #include <stddef.h>
8 #include <stdlib.h>
9 #include <sys/inotify.h>
10 #include <unistd.h>
11
12 #include "libudev.h"
13
14 #include "alloc-util.h"
15 #include "fd-util.h"
16 #include "io-util.h"
17
18 /**
19 * SECTION:libudev-queue
20 * @short_description: access to currently active events
21 *
22 * This exports the current state of the udev processing queue.
23 */
24
25 /**
26 * udev_queue:
27 *
28 * Opaque object representing the current event queue in the udev daemon.
29 */
30 struct udev_queue {
31 struct udev *udev;
32 unsigned n_ref;
33 int fd;
34 };
35
36 /**
37 * udev_queue_new:
38 * @udev: udev library context
39 *
40 * The initial refcount is 1, and needs to be decremented to
41 * release the resources of the udev queue context.
42 *
43 * Returns: the udev queue context, or #NULL on error.
44 **/
45 _public_ struct udev_queue *udev_queue_new(struct udev *udev) {
46 struct udev_queue *udev_queue;
47
48 udev_queue = new(struct udev_queue, 1);
49 if (!udev_queue) {
50 errno = ENOMEM;
51 return NULL;
52 }
53
54 *udev_queue = (struct udev_queue) {
55 .udev = udev,
56 .n_ref = 1,
57 .fd = -1,
58 };
59
60 return udev_queue;
61 }
62
63 static struct udev_queue *udev_queue_free(struct udev_queue *udev_queue) {
64 assert(udev_queue);
65
66 safe_close(udev_queue->fd);
67 return mfree(udev_queue);
68 }
69
70 /**
71 * udev_queue_ref:
72 * @udev_queue: udev queue context
73 *
74 * Take a reference of a udev queue context.
75 *
76 * Returns: the same udev queue context.
77 **/
78
79 /**
80 * udev_queue_unref:
81 * @udev_queue: udev queue context
82 *
83 * Drop a reference of a udev queue context. If the refcount reaches zero,
84 * the resources of the queue context will be released.
85 *
86 * Returns: #NULL
87 **/
88 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_queue, udev_queue, udev_queue_free);
89
90 /**
91 * udev_queue_get_udev:
92 * @udev_queue: udev queue context
93 *
94 * Retrieve the udev library context the queue context was created with.
95 *
96 * Returns: the udev library context.
97 **/
98 _public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) {
99 assert_return_errno(udev_queue, NULL, EINVAL);
100
101 return udev_queue->udev;
102 }
103
104 /**
105 * udev_queue_get_kernel_seqnum:
106 * @udev_queue: udev queue context
107 *
108 * This function is deprecated.
109 *
110 * Returns: 0.
111 **/
112 _public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) {
113 return 0;
114 }
115
116 /**
117 * udev_queue_get_udev_seqnum:
118 * @udev_queue: udev queue context
119 *
120 * This function is deprecated.
121 *
122 * Returns: 0.
123 **/
124 _public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) {
125 return 0;
126 }
127
128 /**
129 * udev_queue_get_udev_is_active:
130 * @udev_queue: udev queue context
131 *
132 * Check if udev is active on the system.
133 *
134 * Returns: a flag indicating if udev is active.
135 **/
136 _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) {
137 return access("/run/udev/control", F_OK) >= 0;
138 }
139
140 /**
141 * udev_queue_get_queue_is_empty:
142 * @udev_queue: udev queue context
143 *
144 * Check if udev is currently processing any events.
145 *
146 * Returns: a flag indicating if udev is currently handling events.
147 **/
148 _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) {
149 return access("/run/udev/queue", F_OK) < 0;
150 }
151
152 /**
153 * udev_queue_get_seqnum_sequence_is_finished:
154 * @udev_queue: udev queue context
155 * @start: first event sequence number
156 * @end: last event sequence number
157 *
158 * This function is deprecated, it just returns the result of
159 * udev_queue_get_queue_is_empty().
160 *
161 * Returns: a flag indicating if udev is currently handling events.
162 **/
163 _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
164 unsigned long long int start, unsigned long long int end) {
165 return udev_queue_get_queue_is_empty(udev_queue);
166 }
167
168 /**
169 * udev_queue_get_seqnum_is_finished:
170 * @udev_queue: udev queue context
171 * @seqnum: sequence number
172 *
173 * This function is deprecated, it just returns the result of
174 * udev_queue_get_queue_is_empty().
175 *
176 * Returns: a flag indicating if udev is currently handling events.
177 **/
178 _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) {
179 return udev_queue_get_queue_is_empty(udev_queue);
180 }
181
182 /**
183 * udev_queue_get_queued_list_entry:
184 * @udev_queue: udev queue context
185 *
186 * This function is deprecated.
187 *
188 * Returns: NULL.
189 **/
190 _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) {
191 errno = ENODATA;
192 return NULL;
193 }
194
195 /**
196 * udev_queue_get_fd:
197 * @udev_queue: udev queue context
198 *
199 * Returns: a file descriptor to watch for a queue to become empty.
200 */
201 _public_ int udev_queue_get_fd(struct udev_queue *udev_queue) {
202 _cleanup_close_ int fd = -1;
203
204 assert_return(udev_queue, -EINVAL);
205
206 if (udev_queue->fd >= 0)
207 return udev_queue->fd;
208
209 fd = inotify_init1(IN_CLOEXEC);
210 if (fd < 0)
211 return -errno;
212
213 if (inotify_add_watch(fd, "/run/udev" , IN_DELETE) < 0)
214 return -errno;
215
216 udev_queue->fd = TAKE_FD(fd);
217 return udev_queue->fd;
218 }
219
220 /**
221 * udev_queue_flush:
222 * @udev_queue: udev queue context
223 *
224 * Returns: the result of clearing the watch for queue changes.
225 */
226 _public_ int udev_queue_flush(struct udev_queue *udev_queue) {
227 int r;
228
229 assert_return(udev_queue, -EINVAL);
230
231 if (udev_queue->fd < 0)
232 return -EINVAL;
233
234 r = flush_fd(udev_queue->fd);
235 if (r < 0)
236 return r;
237
238 return 0;
239 }