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