]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-queue.c
Merge pull request #11827 from keszybz/pkgconfig-variables
[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 return_with_errno(NULL, ENOMEM);
51
52 *udev_queue = (struct udev_queue) {
53 .udev = udev,
54 .n_ref = 1,
55 .fd = -1,
56 };
57
58 return udev_queue;
59 }
60
61 static struct udev_queue *udev_queue_free(struct udev_queue *udev_queue) {
62 assert(udev_queue);
63
64 safe_close(udev_queue->fd);
65 return mfree(udev_queue);
66 }
67
68 /**
69 * udev_queue_ref:
70 * @udev_queue: udev queue context
71 *
72 * Take a reference of a udev queue context.
73 *
74 * Returns: the same udev queue context.
75 **/
76
77 /**
78 * udev_queue_unref:
79 * @udev_queue: udev queue context
80 *
81 * Drop a reference of a udev queue context. If the refcount reaches zero,
82 * the resources of the queue context will be released.
83 *
84 * Returns: #NULL
85 **/
86 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_queue, udev_queue, udev_queue_free);
87
88 /**
89 * udev_queue_get_udev:
90 * @udev_queue: udev queue context
91 *
92 * Retrieve the udev library context the queue context was created with.
93 *
94 * Returns: the udev library context.
95 **/
96 _public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) {
97 assert_return_errno(udev_queue, NULL, EINVAL);
98
99 return udev_queue->udev;
100 }
101
102 /**
103 * udev_queue_get_kernel_seqnum:
104 * @udev_queue: udev queue context
105 *
106 * This function is deprecated.
107 *
108 * Returns: 0.
109 **/
110 _public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) {
111 return 0;
112 }
113
114 /**
115 * udev_queue_get_udev_seqnum:
116 * @udev_queue: udev queue context
117 *
118 * This function is deprecated.
119 *
120 * Returns: 0.
121 **/
122 _public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) {
123 return 0;
124 }
125
126 /**
127 * udev_queue_get_udev_is_active:
128 * @udev_queue: udev queue context
129 *
130 * Check if udev is active on the system.
131 *
132 * Returns: a flag indicating if udev is active.
133 **/
134 _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) {
135 return access("/run/udev/control", F_OK) >= 0;
136 }
137
138 /**
139 * udev_queue_get_queue_is_empty:
140 * @udev_queue: udev queue context
141 *
142 * Check if udev is currently processing any events.
143 *
144 * Returns: a flag indicating if udev is currently handling events.
145 **/
146 _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) {
147 return access("/run/udev/queue", F_OK) < 0;
148 }
149
150 /**
151 * udev_queue_get_seqnum_sequence_is_finished:
152 * @udev_queue: udev queue context
153 * @start: first event sequence number
154 * @end: last event sequence number
155 *
156 * This function is deprecated, it just returns the result of
157 * udev_queue_get_queue_is_empty().
158 *
159 * Returns: a flag indicating if udev is currently handling events.
160 **/
161 _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
162 unsigned long long int start, unsigned long long int end) {
163 return udev_queue_get_queue_is_empty(udev_queue);
164 }
165
166 /**
167 * udev_queue_get_seqnum_is_finished:
168 * @udev_queue: udev queue context
169 * @seqnum: sequence number
170 *
171 * This function is deprecated, it just returns the result of
172 * udev_queue_get_queue_is_empty().
173 *
174 * Returns: a flag indicating if udev is currently handling events.
175 **/
176 _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) {
177 return udev_queue_get_queue_is_empty(udev_queue);
178 }
179
180 /**
181 * udev_queue_get_queued_list_entry:
182 * @udev_queue: udev queue context
183 *
184 * This function is deprecated.
185 *
186 * Returns: NULL.
187 **/
188 _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) {
189 return_with_errno(NULL, ENODATA);
190 }
191
192 /**
193 * udev_queue_get_fd:
194 * @udev_queue: udev queue context
195 *
196 * Returns: a file descriptor to watch for a queue to become empty.
197 */
198 _public_ int udev_queue_get_fd(struct udev_queue *udev_queue) {
199 _cleanup_close_ int fd = -1;
200
201 assert_return(udev_queue, -EINVAL);
202
203 if (udev_queue->fd >= 0)
204 return udev_queue->fd;
205
206 fd = inotify_init1(IN_CLOEXEC);
207 if (fd < 0)
208 return -errno;
209
210 if (inotify_add_watch(fd, "/run/udev" , IN_DELETE) < 0)
211 return -errno;
212
213 udev_queue->fd = TAKE_FD(fd);
214 return udev_queue->fd;
215 }
216
217 /**
218 * udev_queue_flush:
219 * @udev_queue: udev queue context
220 *
221 * Returns: the result of clearing the watch for queue changes.
222 */
223 _public_ int udev_queue_flush(struct udev_queue *udev_queue) {
224 int r;
225
226 assert_return(udev_queue, -EINVAL);
227
228 if (udev_queue->fd < 0)
229 return -EINVAL;
230
231 r = flush_fd(udev_queue->fd);
232 if (r < 0)
233 return r;
234
235 return 0;
236 }