]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
88a6477e | 2 | /*** |
96b2fb93 | 3 | Copyright © 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk> |
88a6477e | 4 | ***/ |
64ccdf82 | 5 | |
64ccdf82 | 6 | #include <errno.h> |
cf0fbc49 TA |
7 | #include <stddef.h> |
8 | #include <stdlib.h> | |
14cb7336 | 9 | #include <sys/inotify.h> |
cf0fbc49 | 10 | #include <unistd.h> |
64ccdf82 | 11 | |
b5efdb8a | 12 | #include "alloc-util.h" |
3ffd4af2 | 13 | #include "fd-util.h" |
c004493c | 14 | #include "io-util.h" |
64ccdf82 KS |
15 | #include "libudev-private.h" |
16 | ||
ce1d6d7f KS |
17 | /** |
18 | * SECTION:libudev-queue | |
19 | * @short_description: access to currently active events | |
20 | * | |
9ea28c55 | 21 | * This exports the current state of the udev processing queue. |
ce1d6d7f KS |
22 | */ |
23 | ||
24 | /** | |
25 | * udev_queue: | |
26 | * | |
27 | * Opaque object representing the current event queue in the udev daemon. | |
28 | */ | |
64ccdf82 | 29 | struct udev_queue { |
912541b0 | 30 | struct udev *udev; |
3c6ac219 | 31 | unsigned n_ref; |
14cb7336 | 32 | int fd; |
64ccdf82 KS |
33 | }; |
34 | ||
8d6bc73a KS |
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 | **/ | |
ccda7f87 | 44 | _public_ struct udev_queue *udev_queue_new(struct udev *udev) { |
912541b0 KS |
45 | struct udev_queue *udev_queue; |
46 | ||
ccda7f87 | 47 | udev_queue = new(struct udev_queue, 1); |
309f631d LP |
48 | if (udev_queue == NULL) { |
49 | errno = ENOMEM; | |
912541b0 | 50 | return NULL; |
309f631d | 51 | } |
9ea28c55 | 52 | |
ccda7f87 YW |
53 | *udev_queue = (struct udev_queue) { |
54 | .udev = udev, | |
55 | .n_ref = 1, | |
56 | .fd = -1, | |
57 | }; | |
58 | ||
912541b0 | 59 | return udev_queue; |
64ccdf82 KS |
60 | } |
61 | ||
3c6ac219 YW |
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 | ||
8d6bc73a KS |
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 | **/ | |
64ccdf82 | 77 | |
8d6bc73a KS |
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. | |
c1959569 | 84 | * |
725d7e6c | 85 | * Returns: #NULL |
8d6bc73a | 86 | **/ |
3c6ac219 | 87 | DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_queue, udev_queue, udev_queue_free); |
64ccdf82 | 88 | |
8d6bc73a KS |
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 | **/ | |
d35c0e8d YW |
97 | _public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) { |
98 | assert_return_errno(udev_queue, NULL, EINVAL); | |
99 | ||
912541b0 | 100 | return udev_queue->udev; |
64ccdf82 KS |
101 | } |
102 | ||
8d6bc73a KS |
103 | /** |
104 | * udev_queue_get_kernel_seqnum: | |
105 | * @udev_queue: udev queue context | |
106 | * | |
9ea28c55 | 107 | * This function is deprecated. |
21dbe43a | 108 | * |
9ea28c55 | 109 | * Returns: 0. |
8d6bc73a | 110 | **/ |
f8cdabc0 | 111 | _public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) { |
912541b0 | 112 | return 0; |
f503f6b2 AJ |
113 | } |
114 | ||
8d6bc73a KS |
115 | /** |
116 | * udev_queue_get_udev_seqnum: | |
117 | * @udev_queue: udev queue context | |
118 | * | |
9ea28c55 | 119 | * This function is deprecated. |
21dbe43a | 120 | * |
9ea28c55 | 121 | * Returns: 0. |
8d6bc73a | 122 | **/ |
f8cdabc0 | 123 | _public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) { |
9ea28c55 | 124 | return 0; |
f503f6b2 AJ |
125 | } |
126 | ||
8d6bc73a KS |
127 | /** |
128 | * udev_queue_get_udev_is_active: | |
129 | * @udev_queue: udev queue context | |
130 | * | |
21dbe43a KS |
131 | * Check if udev is active on the system. |
132 | * | |
8d6bc73a KS |
133 | * Returns: a flag indicating if udev is active. |
134 | **/ | |
f8cdabc0 | 135 | _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) { |
9ea28c55 | 136 | return access("/run/udev/control", F_OK) >= 0; |
11d5eec2 KS |
137 | } |
138 | ||
8d6bc73a KS |
139 | /** |
140 | * udev_queue_get_queue_is_empty: | |
141 | * @udev_queue: udev queue context | |
142 | * | |
21dbe43a KS |
143 | * Check if udev is currently processing any events. |
144 | * | |
8d6bc73a KS |
145 | * Returns: a flag indicating if udev is currently handling events. |
146 | **/ | |
f8cdabc0 | 147 | _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) { |
45e60962 | 148 | return access("/run/udev/queue", F_OK) < 0; |
64ccdf82 KS |
149 | } |
150 | ||
8d6bc73a KS |
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 | * | |
9ea28c55 KS |
157 | * This function is deprecated, it just returns the result of |
158 | * udev_queue_get_queue_is_empty(). | |
21dbe43a | 159 | * |
9ea28c55 | 160 | * Returns: a flag indicating if udev is currently handling events. |
8d6bc73a | 161 | **/ |
54cf0b7f | 162 | _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue, |
f8cdabc0 | 163 | unsigned long long int start, unsigned long long int end) { |
9ea28c55 | 164 | return udev_queue_get_queue_is_empty(udev_queue); |
f503f6b2 AJ |
165 | } |
166 | ||
8d6bc73a KS |
167 | /** |
168 | * udev_queue_get_seqnum_is_finished: | |
169 | * @udev_queue: udev queue context | |
170 | * @seqnum: sequence number | |
171 | * | |
9ea28c55 KS |
172 | * This function is deprecated, it just returns the result of |
173 | * udev_queue_get_queue_is_empty(). | |
21dbe43a | 174 | * |
9ea28c55 | 175 | * Returns: a flag indicating if udev is currently handling events. |
8d6bc73a | 176 | **/ |
f8cdabc0 | 177 | _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) { |
9ea28c55 | 178 | return udev_queue_get_queue_is_empty(udev_queue); |
64ccdf82 KS |
179 | } |
180 | ||
8d6bc73a KS |
181 | /** |
182 | * udev_queue_get_queued_list_entry: | |
183 | * @udev_queue: udev queue context | |
184 | * | |
9ea28c55 | 185 | * This function is deprecated. |
21dbe43a | 186 | * |
9ea28c55 | 187 | * Returns: NULL. |
8d6bc73a | 188 | **/ |
f8cdabc0 | 189 | _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) { |
309f631d | 190 | errno = ENODATA; |
9ea28c55 | 191 | return NULL; |
64ccdf82 | 192 | } |
14cb7336 KS |
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) { | |
2dac88a9 YW |
201 | _cleanup_close_ int fd = -1; |
202 | ||
203 | assert_return(udev_queue, -EINVAL); | |
14cb7336 KS |
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 | ||
2dac88a9 YW |
212 | if (inotify_add_watch(fd, "/run/udev" , IN_DELETE) < 0) |
213 | return -errno; | |
14cb7336 | 214 | |
2dac88a9 YW |
215 | udev_queue->fd = TAKE_FD(fd); |
216 | return udev_queue->fd; | |
14cb7336 KS |
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) { | |
665dfe93 LP |
226 | int r; |
227 | ||
d35c0e8d | 228 | assert_return(udev_queue, -EINVAL); |
665dfe93 | 229 | |
14cb7336 KS |
230 | if (udev_queue->fd < 0) |
231 | return -EINVAL; | |
232 | ||
665dfe93 LP |
233 | r = flush_fd(udev_queue->fd); |
234 | if (r < 0) | |
235 | return r; | |
236 | ||
237 | return 0; | |
14cb7336 | 238 | } |