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